PHP
MySQL
PHPUnit
laravel

LaravelのPHPUnitでToo many connections

テストを実行中にmysqlで以下のエラーが出るようになった。(5.5.29ではframework側で対応済みのようです)

PDOException: SQLSTATE[08004] [1040] Too many connections

対応方法

同時接続数を増やす

[mysqld]
max_connections=数値

数値を増やす(デフォルト値151)

テストケース毎にコネクションを切る

tearDownDB::disconnect();を入れる

PDO::ATTR_PERSISTENTを設定する

接続、および接続の管理
持続的な接続は、スクリプトが 終了しても閉じられずにキャッシュされ、他のスクリプトが同じ内容の 接続を要求してきた際にそれが再利用されます。

config/database.php
'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'database'),
    'username' => env('DB_USERNAME', 'user'),
    'password' => env('DB_PASSWORD', 'password'),
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
+   'options' => [
+       PDO::ATTR_PERSISTENT => env('DB_PERSISTENT', true),
+   ],
],

動作確認

挙動がよくわからなかったので以下をいろんなパターンで埋め込んでみた。

var_dump(exec("mysql -u XXXXXXXXXXXX -pXXXXXXXXXXXX -Nse \"show status like 'Threads_connected';\""));

テスト内

  • 次のケースに移るとコネクション数が増えた。 (次のテストケースに行くと別コネクションになる?)

LaravelのテストはsetUp\Illuminate\Foundation\Applicationを毎回作成しているみたいなのでコネクションも新しいものを作っているのかも?

直接呼び出す

  • 別プロセスで同じスクリプトを実行してみたらPDO::ATTR_PERSISTENTの設定があろうがなかろうがコネクションは増えた。
  • テストからの実行ではない場合はコネクションは1つから増えなかった。

とりあえず以上のことから
テストケースの時だけ注意すれば良さそう。

私はPDO::ATTR_PERSISTENTで対応しました。

PDO Too many connections when running test suite


5.5.29では修正されているみたいでした。
Disconnect from the database when refresh is done