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 );