通常の運用時には正常なMySQLでも、レポート作成や調査のために実施されるクエリが異常に長く実行されつづけて放置されている、という場面に出くわしたことがある方もいるかも知れません。
MySQLではmax_
max_execution_time
max_
mysql> SHOW VARIABLES LIKE 'max_execution_time'; +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | max_execution_time | 0 | +--------------------+-------+ 1 row in set (0.00 sec)
max_
mysql> SET SESSION max_execution_time = 5; Query OK, 0 rows affected (0.00 sec) mysql> select * FROM dummy; ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded
この変数は読み取り専用のSELECT構文にのみ適用されます。更新を行うようなFunctionやストアドプログラムには効かないようです。
max_execution_timeの設定
max_
SET SESSIONで設定した場合には自身のSESSION、GLOBALで設定した場合には、それ以降に新規に作成されたSESSIONに対してmax_
オプティマイザヒント句に埋め込む
max_
オプティマイザヒント句に埋め込む場合は、以下のようにSELECTの中に /*+ max_
を埋め込むことで、実行時間をNミリ秒以内に制限することができます。これによりセッション単位ではなくクエリ単位で制御することも可能です。
mysql> SELECT @@global.max_execution_time, @@session.max_execution_time; +-----------------------------+------------------------------+ | @@global.max_execution_time | @@session.max_execution_time | +-----------------------------+------------------------------+ | 0 | 0 | +-----------------------------+------------------------------+ 1 row in set (0.00 sec) mysql> SELECT /*+ MAX_EXECUTION_TIME(10) */ * FROM dummy; ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded
メタデータロックで待たされているとき
SELECT構文が詰まるものとして、他のトランザクション実行中に対象のテーブルにALTER文を実行して、後続のクエリが対象のテーブルにSELECT構文を実行すると、メタデータロック状態で詰まるといった現象があります。
この場合、通常はlock_
lock_
trx1> begin; SELECT count(1) FROM dummy ←トランザクションを開始 trx2> ALTER TABLE dummy ENGINE=InnoDB; ←ALTER文がメタデータロック待ち状態になる trx3> > SELECT COUNT(1) FROM dummy; -- max_execution_timeによってタイムアウトした場合 ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded -- lock_wait_timeoutによってタイムアウトした場合 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction)
関連するステータス
max_
- Max_
execution_ time_ exeeded - max_
execution_ timeを超えたSELECT構文の数
- max_
- Max_
execution_ time_ set - 0以外のmax_
execution_ timeが設定されているときにその値を設定したSELECT構文の数
- 0以外のmax_
- Max_
execution_ time_ failed - max_
execution_ timeを設定しようとして失敗したSELECT構文の数
- max_
mysql> SHOW STATUS LIKE '%Max_exe%'; +-------------------------------+-------+ | Variable_name | Value | +-------------------------------+-------+ | Max_execution_time_exceeded | 6 | | Max_execution_time_set | 6 | | Max_execution_time_set_failed | 0 | +-------------------------------+-------+ 3 rows in set (0.01 sec)
まとめ
今回は、max_