PHPとMySQLでハマった件
PHPとMySQLを使うプログラムでエラーに悩まされたので記録しておきます。
a.php
1.MySQLにアクセスしてSELECT。
2.約2時間かかる別の処理。
3.MySQLにアクセスしてINSERT INTO。
↓
3の挿入が出来ていない・・・。
a.phpで何度もテストするのは時間がもったいないので規模を小さくしたb.phpを作成してテストしてみる。
b.php
1.MySQLにアクセスして1件をSELECT。
2.数秒で終わる別の処理。
3.MySQLにアクセスして10件ほどINSERT INTO。
↓
あっけなく成功。
Error while sending QUERY packet.
php.iniのmax_allowed_packetの値を大きくしろと言ってる外人がいたので実行するも変化なし。
日本語の情報が引っかからなくて試行錯誤した末、
mysql_connectを読み込むrequire_onceが1回しか読み込めないからだと考え、
2回めのクエリの前に読み込むmysql_connectをrequireに変更してa.phpを実行。
↓
Error while sending INIT_DB packet.
変化があった。
このエラーも日本語の情報が皆無。。。
a.phpとb.phpの違いといえば2回めの接続までの時間。
・my.cnf
wait_timeout = 60
これって短いんじゃないか?
上記項目について検索してみると
「デフォルトの8時間じゃ短いから1年に変更した」
という記事などが引っかかる。
どうやら一度接続が切れると再接続出来ない事もあるとか。
というわけでwait_timeoutを28800(8時間)に変更。
念の為にinteractive_timeoutも28800に変更。
a.phpを実行したらうまくいきました。
60秒しか待ってくれないのに2時間も違う処理をしていればそりゃあタイムアウトしますよね。
タイムアウトで接続が切られて再接続出来なかっただけ
でした。検索の途中でデッドロックという文字を見かけたのはこれの事だったのかな。。。
何で60秒に変更していたのかは謎です。
さらに調べるとmysql_connectじゃなくてmysql_pconnectを使えば接続が切れないとの事。
mysql_pconnectに変更してweit_timeoutを60秒に戻してみてもしっかり動いてくれました。
(じゃあこっちがいいや。)
mysql_pconnectはPHP 5.5では非推奨なので次のバージョンで無くなりそうな気がしますが、connectの方も非推奨らしいので同じ事です。
いまさらPDOを覚えるのは面倒なので早くPythonをマスターしてSQLAlchemyでデータベースをいじれるようになりたいです。
p.s.
「PHP逆引きレシピ 第2版」より「PHP逆引きハンドブック」の方が役に立つと思いました。