さて何から書こう。
ある日、突然、PHPアプリケーションのエラーログに次のエラーが吐かれるようになった。
PHP Warning: PDO::query(): SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared in …
原因が分からないまま数日の間、観察していると、どうも毎日一定時刻になるとこのエラーを吐くことが判明した。その時間は、ちょうど0:00:00~0:00:45と日付の変わった数十秒に限られる。
なぜ、この時間だけエラーが出るのか不明で散々アプリケーションのコードを確認したが日付の切り替え時にエラーが出るような処理は行っていなかった(たぶん)。
もちろん、ネットでも検索して原因を調べていたのだが、検索結果はすべて英語ページばかりで読むのを躊躇していた。だって英語読むの面倒。。。
とは言え、エラーが出続けるのも良くないので検索上位の数ページを読んでみた。どうやら原因は、MySQLのバックアップ、とりわけmysqldumpにあるようだ。どういうことかと言うと、サーバー上のあるmysqlプロセスがmysqldumpを使ってデータ量の多いバックアップを取ると、その間、PDOにバグが生じるというものらしい。それで、上記のようなエラーが吐かれてしまう。また、cronを使っている場合には、エラーが出現する時刻も一定となる。
(参考)
https://bugs.mysql.com/bug.php?id=42041
解決策として挙げられているのが、table_definition_cache の値を大きくすること。しかし、これも完全な解決策にはなっていない模様。根本的な解決策は、どうやら見つかっていないようだ。
もっとも、共有サーバーで、他のユーザーによるmysqldumpが原因であるならば、他のサーバーへ移れば解決するかもしれない。おそらくこれが現在有力な解決策だと思う。
ただ、サーバーを移動するのも一苦労なので躊躇してしまう。
この『General error: 1615 Prepared statement …』に悩まされている人は多そうなのだが日本では話題になっていないようだ。
【後記】
エラーが出る時間帯にsshログインしてtopコマンドで確認したところ、同時刻にmysqldumpを実行しているユーザーを確認。やはりmysqldumpしてgzipしてバックアップを取っているようだ。