MySQLの接続タイムアウト設定

サーバ用途でJava+MySQLを利用する場合、コネクションプーリングなど
によってコネクションを保持していることが多いと思います。

ご存じの方も多いと思われますが、MySQL(4.x系。5.x系は未確認)では
コネクションの状態を常時監視していて、一定時間利用していないと接続を
切断するようになっています。その「一定時間」のデフォルトは8時間。

つまり、昼夜問わずアクセスのあるシステムならともかく、夜間にアクセスが
少ないシステムの場合、その8時間が経過してしまいプーリングしているにも
関わらずその接続が切れていて起動翌日になると使えなくなる、というような
現象が起こることがあります。

その際には以下のような例外が出ます。

java.sql.SQLException: No operations allowed after connection closed.

MySQLのJDBCドライバには、JDBC URLに付加することのできる
autoReconnectというパラメータがあり、接続が切れた後にそのコネクション
を使おうとすると再接続してくれたのですが、これは最近のドライバでは
無効になっているようでうまく働きません(もともと将来のバージョンで削除
される予定だったそうです)。ちょっとググってみるとautoReconnectせよ、
というのがたくさん出てくるので、初めてこの現象に出くわした方はちょっと
回り道をさせられてしまったかもしれません。

本来的な解決は、タイムアウトで切断された後にアプリケーション側で
再接続することらしいのですが、以前から稼働しているシステムの場合、
アプリに手を入れるのがちょっと・・・ということもあると思います。

そこで、スマートではないですがとりあえず問題を先送りできる方法として、
その「一定時間」を伸ばしてしまうという方法があります。
一番楽なのは、「一定時間後の切断」そのものを無効にすることなのですが、
どうもそのような設定ができないようですので、my.cnfに「一定時間」を思い切り
長く設定してしまいます。

[mysqld]
set-variable = wait_timeout=31536000
set-variable = interactive_timeout=31536000

単位は秒でして、3153600 = 3600 x 24 x 365 ということで1年間です。
wait_timeoutはインタラクティブでない接続、interactive_timeoutはインタラクティブ
な接続のタイムアウトなのだそうですが、両者の違いが今ひとつわからないので、
私は一応両方設定しています。

もし1年間通して1度もアクセスのないアプリなら、わざわざ常時起動しておく
必要がないということで、現実的にはこれでもいいかなと思います。

アプリで再接続する方法は、また機会がありましたら。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です