2021-09-03 MySQL OPTIMIZE TABLE / ロック状態の確認
MySQL OPTIMIZE TABLE
Amazon RDS for MySQL が予想以上のストレージを使用するときのディスクストレージを最適化
テーブル用の領域の一部は実際に使用されない場合でも割り当てられます。innodb_file_per_table が有効化されている場合 (デフォルトでは有効化)、OPTIMIZE TABLE を使ってその容量を解放できます。OPTIMIZE TABLE は InnoDB、MyISAM、ARCHIVE テーブルに対して機能し、Amazon RDS は OPTIMIZE TABLE コマンドを受け入れますが、Amazon RDS は ALTER TABLE…FORCE を実行します。これが発生すると、「テーブルが最適化をサポートしていません。代わりに、再作成 + 分析を実行します」のような警告メッセージが表示されます。 詳細については、OPTIMIZE TABLE に関する MySQL ドキュメントを参照してください。
👆でリンクされている公式ドキュメントは下記。
MySQL :: MySQL 5.7 Reference Manual :: 13.7.2.4 OPTIMIZE TABLE Statement
OPTIMIZE TABLE は短期間しかテーブルをロックしない
英語より日本語の説明のほうが丁寧なのでこちらから引用する。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.7.2.4 OPTIMIZE TABLE 構文
Mysql 5.6.17 より前は、OPTIMIZE TABLE はオンライン DDL (ALGORITHM=INPLACE) を使用しません。その結果、OPTIMIZE TABLE が実行中のテーブルに対しては (つまり、そのテーブルのロック中は) 並列 DML (INSERT、UPDATE、DELETE) が許可されません。また、主キーに現れる順序でキーが挿入されるため、セカンダリインデックスはそれほど効率的に作成されません。
5.6.17 の時点では、OPTIMIZE TABLE は、InnoDB の通常のテーブルとパーティション化されたテーブルの両方に対してオンライン DDL (ALGORITHM=INPLACE) を使用します。OPTIMIZE TABLE によってトリガーされ、ALTER TABLE … FORCE の下で実行されるテーブル再構築は現在、オンライン DDL (ALGORITHM=INPLACE) を使用して実行され、短期間しかテーブルをロックしないため、並列 DML 操作のためのダウンタイムが短縮されます。
ポイントは新しいMySQLバージョンであればオンライン DDLが効くので「短期間しかテーブルをロックしない」ので「ダウンタイムが短縮」されていることだ。
こう思ったっす
RDSレベルならもう自動optimize tableとかやってくれてんのかなって思ったら optimize table いまだに手動で打たなきゃならんかー
— toshimaru (@toshimaru_e) September 3, 2021
ロック状態の確認
MySQL 5.7と8.0でロック状態を確認する(sys.innodb_lock_waitsビュー) - Qiita
ロックの状態を確認したいときのクエリ。
mysql> SELECT * FROM sys.innodb_lock_waits\G
*************************** 1. row ***************************
wait_started: 2018-01-07 13:09:32
wait_age: 00:00:02
wait_age_secs: 2
locked_table: `lock_test`.`lock_test`
locked_index: PRIMARY
locked_type: RECORD
waiting_trx_id: 92210
waiting_trx_started: 2018-01-07 13:07:49
waiting_trx_age: 00:01:45
waiting_trx_rows_locked: 2
waiting_trx_rows_modified: 0
waiting_pid: 6
waiting_query: UPDATE lock_test.lock_test SET val1=6 WHERE id=6
waiting_lock_id: 92210:112:3:7
waiting_lock_mode: X
blocking_trx_id: 92209
blocking_pid: 4
blocking_query: NULL
blocking_lock_id: 92209:112:3:7
blocking_lock_mode: X
blocking_trx_started: 2018-01-07 13:04:45
blocking_trx_age: 00:04:49
blocking_trx_rows_locked: 1
blocking_trx_rows_modified: 1
sql_kill_blocking_query: KILL QUERY 4
sql_kill_blocking_connection: KILL 4
1 row in set, 3 warnings (0.00 sec)