LoginSignup
3
1

More than 5 years have passed since last update.

PDOでLOBを入れようとしてMySQL server has gone away.

Posted at

PDOExceptionが出た

  1. SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
  2. PHP側のエラーはError while sending QUERY packet.
  3. 場所は比較的大きなサイズのLOBを突っ込むクエリのexecute()の場所
  4. でもPHPのmemory_limit(=128MB)に収まる程度だし、max_execution_time(=30秒)に収まる程度
  5. MySQLのログには何も出てない

調べたこと

  • wait_timeoutの値が小さい?

    • 設定もいじってないし、mysql -uhoge -p -e "show variables like '%timeout%'"してもデフォルトの28800秒になっている。
    • execute()の直前に$pdo->query("SELECT 1")とか実行してみたら普通に実行できた。
  • max_allowed_packetの値が小さい?

    • 設定を変更して大きくしてある。mysql -uhoge -p -e "show variables like '%allowed%'"しても設定通りになっている。
  • クエリの前に接続を閉じてる?

    • 上でも書いたとおり直前に実行したクエリは通る。
  • LOBが大きいから?

    • 小さなLOBにするとエラーが出ない

:thinking: :thinking: :thinking: :thinking:

原因

setAttribute(PDO::ATTR_EMULATE_PREPARES, true);としていたことっぽい???
エミュレーションをオフにしたら治った。

クエリをダンプしてみた

$pdo = new PDO();
$pdo->beginTransaction();

$pdo->query("SELECT 1");
$stmt = $pdo->prepare("INSERT INTO foo(file) values (?)");
$stmt->bindValue(1,LOB,PDO::PARAM_LOB);
$stmt->execute();

$pdo->commit();
  • エミュレーションON、大きなLOB(25MB)
Connect   hoge@localhost as anonymous on po
Query     START TRANSACTION
Query     SELECT 1
Prepare   INSERT INTO foo (file) VALUES (?)
Execute   INSERT INTO foo (file) VALUES (LOB)

エミュレーションONなのに静的プレースホルダのような動きをしている。
QuitもCOMMITもしていない。Connectが消えているので、本当にserver has gone awayなことがわかる。

  • エミュレーションON、小さなLOB(1文字)
Connect   hoge@localhost as anonymous on po
Query     START TRANSACTION
Query     SELECT 1
Query     INSERT INTO foo (file) VALUES (LOB)
Query     COMMIT
Quit

正常な動作

  • エミュレーションOFF、大きなLOB(25MB)
Connect   hoge@localhost as anonymous on po
Query     START TRANSACTION
Prepare   INSERT INTO foo (file) VALUES (?)
Prepare   SELECT 1
Execute   SELECT 1
Execute   INSERT INTO foo (file) VALUES (LOB)
Query     COMMIT
Quit

正常な動作

まとめると

PDO::ATTR_EMULATE_PREPARESTRUEのときにLOBをinsertしようとするとconnectionが消える

:thinking: :thinking: :thinking: :thinking:

そんなこと聞いたこともないし、調べても出てこないし、原因はこれ以外のところ……?でもfalseにしたら治ったし……謎

環境

  • CentOS Linux release 7.4.1708 (Core)
  • PHP 7.1.15
  • mysql Ver 15.1 Distrib 10.2.13-MariaDB, for Linux (x86_64) using readline 5.1

結論

:angel:よくわからない:angel:

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1