MySQLセッションタイムアウト設定のinteractive_timeoutとwait_timeout

問題現象

MySQLクライアント接続時に操作がない状態が続くと、次のエラーが発生することがあります:

ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...

または

ERROR 2013 (HY000): Lost connection to MySQL server during query

これらのエラーは接続が切断されたことを示し、再接続が必要です。このタイムアウト時間はMySQLの特定のパラメータによって制御されます。

パラメータ定義

MySQL 5.7ドキュメントに基づく定義:

  • wait_timeout (デフォルト: 28800秒)

    非対話型接続において、サーバーがアクティビティを待機する時間

  • interactive_timeout (デフォルト: 28800秒)

    対話型接続において、サーバーがアクティビティを待機する時間

検証実験

interactive_timeout変更時の挙動

SET GLOBAL interactive_timeout = 10;
SELECT @@global.wait_timeout, @@session.wait_timeout, 
       @@global.interactive_timeout, @@session.interactive_timeout;

対話型接続(mysqlクライアント)での挙動:

SELECT ... -- 10秒後に接続切断が発生
ERROR 2006 (HY000): MySQL server has gone away

非対話型接続(Pythonアプリケーション)の挙動:

def execute_query():
    while True:
        max_id = session.query(func.max(Table.id)).first()
        logger.info(f'Current max ID: {max_id}')
        session.commit()
        time.sleep(15)

interactive_timeoutの変更は非対話型接続に影響しません。

wait_timeout変更時の挙動

SET GLOBAL wait_timeout = 10;
SET GLOBAL interactive_timeout = 30;

対話型接続での挙動:

SELECT ... -- 30秒後に接続切断
ERROR 2006 (HY000): MySQL server has gone away

非対話型接続での挙動:

def connection_test():
    while True:
        try:
            result = conn.execute("SELECT @@wait_timeout, NOW()")
            print(result.fetchall())
        except Exception as e:
            print(f'Error occurred: {e}')
        time.sleep(15)
[(10, datetime.datetime(2024, 7, 25, 16, 14, 13))]
Error occurred: (pymysql.err.OperationalError) (2013, 'Lost connection...')

結論

  • 対話型接続:interactive_timeoutパラメータで制御
  • 非対話型接続:wait_timeoutパラメータで制御

補足:TCP Keepaliveの影響

OSレベルのTCP keepalive設定(例:tcp_keepalive_time=15)はMySQLの接続タイムアウトに影響しません:

# クライアント側設定
echo 15 > /proc/sys/net/ipv4/tcp_keepalive_time

# MySQL設定
SET GLOBAL wait_timeout = 20;

パケットキャプチャ結果より、TCP keepaliveパケットが送信されても、MySQLサーバーは20秒で接続を切断します。

タグ: MySQL セッション管理 タイムアウト設定 データベース接続 interactive_timeout

8月3日 18:40 投稿