MySQL wait_timeoutの挙動
アイドル状態(最後の実行から何もしていない)がN秒続くとMySQLが勝手に接続を切るらしい。
このN秒を設定するのがwait_timeoutである。
まず、デフォルト設定を確認してみる。
mysql -uroot -e'show variables' | egrep '(wait)'; -------- wait_timeout 28800
ということで、28800秒=8時間がデフォルトの模様。
http://dev.mysql.com/doc/refman/4.1/ja/gone-away.htmlにも書いてある。
次にwait_timeoutを10秒に変更してみる。
/etc/my.cnfに以下を追加。
[mysqld] wait_timeout=10
これで準備はOKなので、テストしてみる。
my $dbh = &get_handle my $sth = $dbh->prepare(<<'SQL'); select * from data limit 1; SQL $sth->execute; my $cnt = 0; while(1) { sleep(1); $cnt++; print "$cnt\n"; last if ($cnt > 9); } $sth->execute;
実行すると期待通りエラーになる。
1 2 3 4 5 6 7 8 9 10 DBD::mysql::st execute failed: MySQL server has gone away at connection.pl line 20.
ちなみにハンドルを取得してからの時間が問題になるので、
以下のケースでもエラーになる。
my $dbh = &get_handle my $sth = $dbh->prepare(<<'SQL'); select * from data limit 1; SQL #ハンドル取得後に時間経つ my $cnt = 0; while(1) { sleep(1); $cnt++; print "$cnt\n"; last if ($cnt > 9); } $sth->execute;
まとめ
アイドル状態のコネクションをMySQLが切断するまでの時間はwait_timeoutで設定できる。
プログラムでもwait_timeout値を意識し、処理フローの組み立てに気を使う必要がある。
ハンドル取得から処理まで長い時間を置かない、置くならハンドル再取得等。
追記(2014.08.27)
検索で上位に表示されてることにビビったので。。。
「wait_timeoutを延ばしておけば安心だよ」と言いたいのではなく、むしろ「timeout しないよう、気をつけてコーディング必要だよね。特に長めの処理をする batchなどは、集計等してる間にうっかり timeout しないよう利用するサーバの設定確認しておくべし」という趣旨です。
当時書いた文章からは全く伝わらないけども、そういう背景でありました。。。