2010年10月23日土曜日

MySQLのクエリーログ


今日は開発からMySQLに投げているクエリーの調子が悪いという話がきました。


開発は基本的にPHPなのですが、PHPからDBに接続しクエリを投げる際にPHP5.1から実装されたPDOを利用しています。


PDOとは


DBにはMySQLやPostgreSQL、Oracleなどがあります。


DBにデータを入れたり、DBからデータを抜き出したり、検索したりする場合はDBに対してクエリを実行します。しかし、クエリはDBによって異なるので新しくクエリを覚えるのは非常にトレーニングコストがかかったりします。


PDOは、データベースの違いによるクエリの差を吸収してくれるための関数です。


完全に差を吸収してくれるわけではありませんが、MySQLからPostgreSQLに以降する時などに非常に効率が上がり、セキュリティを向上させる仕組みもあるのでセキュリティ向上も期待できます。




PDOからクエリを取得できない


今日問題が起こったのはPDOからDBに実際に渡るクエリを知る術が基本的にないため、クエリが正しく実行されているのかを分析できない点にありました。


PDOからクエリを収集する方法



  1. MySQL QueryLogを取る

  2. TCPダンプを取る


などがありました。TCPダンプを取るよりも明らかにクエリログを取る方が簡単なのでこちらを採用しました。



クエリログを取る方法


/etc/my.cnfにlogを追加します。



log=/var/log/mysql/query.log




logディレクトリがない場合は予め作成しておいてください。


また、MySQL実行ユーザの権限をディレクトリに付けてください。



普通はこんな感じでしょうか



chown root:mysql /var/log/mysql/




パーミッションは775です。


MySQLを再起動させます。


ログの監視を開始します。



tail -f /var/log/mysql/query.log




しかし、問題のあるクエリを投げてもいっこうにログが流れてきません‥。



どうやらQueryCacheが効いているようです。


QueryCacheは、参照系のクエリが実行されキャッシュにある場合クエリを実行せずにキャッシュから結果を返すためログにクエリが残りません。


MySQLのキャッシュをクリアします。


MySQLにログイン後



FLUSH QUERY CACHE;




これでログにクエリが流れてきました。



結局、サーバ側やPHPの問題ではなく投げているクエリが間違っていただけでした。。。。



この設定では、ずっとログを書き込んで行くのでローテートログなどを設定する必要があります。


0 件のコメント:

コメントを投稿