はにまログ

「はにまる」のようにゆるーく生きたい。

DB移行前のユーザ情報が、どこかに残っている!?

旧サーバから、MySQLとアプリケーションを移行して順調に動いているシステム。

問題発覚

ところが、特定のテーブルだけInsertできない。Select文は実行できる。

Insert時のエラーには、(今ははっきりと覚えてないが、)
オリジナルサーバの[ユーザ名]@[アドレス]でなければ更新できない
などと書いてあったようだ。

そもそも、データベース移行後、rootユーザしか作ってない&使ってない(ほんとはアカンけど)。
どこからそんなユーザが紛れ込んだんじゃ~。

それに、rootユーザに全権限与えた。
何が不満なんじゃ~。

調査

原因を探ってみると、Information Schemaデータベースの、triggerテーブルのDEFINERというカラムにそのユーザが明記されているではないか!
MySQLのダンプとって、そのまま展開しただけだと、前のサーバのユーザ情報がそうやって残るらしい…。
そして、そのユーザでなかったらトリガーを実行できない縛りになっているらしい。。

解決

triggerテーブルのDEFINER列を直接編集できない!rootでもその権限はないらしい。
幸いにもそのトリガーを作った時のSQLを残してあるので、それを実行したらDEFINERの値が
root@XXX.XXX.XXX.XXX
に変わりました。
その後は、順調に更新できるようになりました。ありがとう!

VMWareに64ビット版のゲストOSをインストールできない

はまったのでメモ。

とあるサーバを仮想化環境にて構築する事になった。

ホストマシン: Dell PowerEdge 1800
CPU:      Intel Xeon 3.0GHz(64bit)
仮想化ソフト: VMWareServer2.0.0
ゲストOS:   CentOS6.6 X86_64版

CPU、ゲストOS、共に64ビット。問題なし!と判断した。
しかし、人生そんなに甘くない…!

1. VMWareServer の WebUIを立ち上げて、仮想サーバ作成。
 OSのタイプ: Linux
 バージョン: 2.6.x系 64bit
2. 仮想サーバに、CentOS6.6(x86_64版)をインストールしようとすると、

This kernel requires an x86-64 CPU, but only detected an i686 CPU. Unable to boot - please use a kernel appropriate for your CPU.

というメッセージが出て、インストールできない!

確か…「VMのホストのOSとして」であれば、CentOS6.6 x86_64版を同じマシンにインストール出来ていたのに、「VMのゲストのOSとして」はインストールできないのね!

調べてみると、VMWareのゲストOSとして64ビットOSをインストールさせるには、Intel VTxをBIOS設定で有効にしなければならないようだ。
https://hereirestinremorse.wordpress.com/virtualbox/this-kernel-requires-an-x86-64-cpu-but-only-detected-an-i686-cpu-unable-to-boot-please-use-a-kernel-appropriate-for-your-cpu/

しかし、BIOSの変更ってどうやるんだろう…。

さらに調べてみると、PowerEdge1800はVTx技術が現れる前のバージョンで、BIOS設定できない事が判った。
Poweredge 1800 Virtualization option in Bios - PowerEdge General HW Forum - Servers - Dell Community

これでゲストOSには32ビット版をインストールするしかないことがはっきりしました。
そして、32ビット版のインストールはすんなりできました…。ホッ。

mod_rewrite の %{QUERY_STRING} の使い方

はまったのでメモ。

【要件】
・末尾が、index.htmlの場合、一つ手前にURLを切り戻してそのパス名で、.htmlとする。
 例)/foo/index.html の場合、
   /foo.html
・さらに末尾にクエリやアンカーが着く事があるので、それをそのまま引き継ぎたい。
 例)/foo/index.html?query1=abc&query2=def#bottom の場合、
   /foo.html?query1=abc&query2=def#bottom
【指示】
mod_rewriteでクエリを表現するには、%{QUERY_STRING}を使うと良い。

① 一旦、%{QUERY_STRING}を使わずに試作してみる。
  RewriteRule ^/(.*/)?index.html(\?.*)?$ /$1.html$2 [R=301,L]
  まずは、これでうまく行った。

② 次に、$2の代わりに、%{QUERY_STRING} を設置してみた。
  RewriteRule ^/(.*)/?index.html(\?.*)?$ /$1.html%{QUERY_STRING} [R=301,L]
  すると、2重でクエリが出力されちゃう。

例)/foo/index.html?query1=abc の場合
  /foo.htmlquery1=abc?query1=abc

この記事を見ると
http://d.hatena.ne.jp/mrgoofy33/20101021/1287672461

「RewriteRule」で書き換えられる側のURIには「クエリ文字列(URLパラメタ)が含まれない」

つまり、
①の$2でクエリが取れたのではなく、どこかわからないが、別の設定により勝手にクエリが付与される。この影響で、②ではまず %{QUERY_STRING} のクエリ文字列が付与され、その後どこかで勝手にクエリが付与された。
そして、QUERY_STRINGは、クエリの先頭の ? を含まない。そのため、②では ? 無しのクエリがいきなり出力されている。

この記事は書きかけです。

mod_rewriteの書き方

他人によって大幅にリライト設定の加筆された「httpd.conf」に追加設定したのですが、素直に設定しても思ったように動きませんでした。
時間があればきっちりと調べ上げればよいのですが、「割り切り」が必要。。
その解決法を備忘録としてメモします。

解決策

とにかく先に書く(解決策と言うより、バッドノウハウ

mod_rewriteが有効になるのは、RewriteEngine on の直後です。
そこにリライト設定を書けば、他のリライト設定の影響を受ける前に、自分の設定が解釈されます。

代償として

Lフラグを使用しない場合、それ以降のRewriteCondやRewriteRuleに供されるURLはその影響を受けた後のURLになるので、他のRewriteが影響を受けない事を、リグレッション・テストする必要があります。

この記事は編集中です。

2つの日付の差分を取得する

  • java.util.Calendarクラスを利用することで、予定日を簡単に設定できる。
  • 予定日と現在のCalendarインスタンスをミリ秒に変換し、差分をとる。(Calendar.compareというメソッドでも日付の比較はできるが、日付の大小をあらわだけで、日付の差分までは取得できない)
  • 差分をDateクラスとCalendarクラスを経由して、日数や時間に変換するが、Calendar.DAY_OF_YEARを利用することで手軽に月をまたいだ日数を取得できる。
// 現在の日付を取得する
Calendar cal_now = Calendar.getInstance();
// 予定の日付を取得する
Calendar cal_target = Calendar.set("2014","5","5","11","15","10");
// 残りの日数を割り出す
long diff = cal_target.getTimeInMillis() - cal_target.getTimeInMillis();
Date diff_date = new Date(diff);
Calendar cal_diff = Calendar.setTime(diff_date);
System.out.println(
    cal_diff.get(Calendar.DAY_OF_YEAR)
    + "日" 
    + cal_diff.get(Calendar.HOUR) 
    + "時間" 
    + cal_diff.get(Calendar.MINUTE)  
    + "分" 
    + cal_diff.get(Calendar.SECOND) 
    + "秒"
);

ただし、Calendar.DAY_OF_YEARは、指定した日が1年の何日めかを取得するので、差分が1年を超える場合には使えない。一年以上先の予定まで登録されることを考慮するなら、残日数をミリ秒から直接算出する。

long diff_day = ( diff ) / (1000 * 60 * 60 * 24 );