InnoDB
では、SQL ステートメントを使用して行を削除しても、データベースからすぐには行が物理的に削除されません。 行とそのインデックスレコードは、削除のために書き込まれた undo ログレコードが InnoDB
によって破棄された場合にのみ物理的に削除されます。 この削除操作は、行がマルチバージョン同時実行性制御 (MVCC) またはロールバックに不要になった後にのみ実行され、パージと呼ばれます。
パージは定期的に実行されます。 履歴リストから undo ログページを解析して処理します。これは、InnoDB
トランザクションシステムによってメンテナンスされるコミット済トランザクションの undo ログページのリストです。 パージすると、undo ログページは処理後に履歴リストから解放されます。
パージスレッドの構成
パージ操作は、1 つ以上のパージスレッドによってバックグラウンドで実行されます。 パージスレッドの数は、innodb_purge_threads
変数によって制御されます。 デフォルト値は 4 です。 DML アクションが単一のテーブルまたはいくつかのテーブルに集中している場合は、スレッドがテーブルにアクセスするために互いに競合しないように、設定を低くしておきます。 DML 操作が多数のテーブルに分散している場合は、この設定を増やします。 パージスレッドの最大数は 32 です。
innodb_purge_threads
設定は、許可されるパージスレッドの最大数です。 パージシステムは、必要に応じてパージスレッドの数を自動的に調整します。
パージバッチサイズの構成
innodb_purge_batch_size
変数は、履歴リストから一度に解析および処理をパージする undo ログページの数を定義します。 デフォルト値は 300 です。 マルチスレッドパージ構成では、コーディネータパージスレッドは innodb_purge_batch_size
を innodb_purge_threads
で除算し、その数のページを各パージスレッドに割り当てます。
パージシステムでは、不要になった undo ログページも解放されます。 undo ログを使用して 128 回ずつ反復します。 innodb_purge_batch_size
変数では、バッチで解析および処理される undo ログページの数の定義に加えて、undo ログを介して 128 回反復するたびにパージによって解放される undo ログページの数を定義します。
innodb_purge_batch_size
変数は、高度なパフォーマンスチューニングおよび実験を目的としています。 ほとんどのユーザーは、innodb_purge_batch_size
をデフォルト値から変更する必要はありません。
最大パージラグの構成
innodb_max_purge_lag
変数は、必要な最大パージラグを定義します。 パージラグが innodb_max_purge_lag
のしきい値を超えると、INSERT
、UPDATE
および DELETE
操作に遅延が課され、パージ操作がキャッチアップされる時間が許可されます。 デフォルト値は 0 です。これは、最大パージラグおよび遅延がないことを意味します。
InnoDB
トランザクションシステムでは、UPDATE
または DELETE
操作で削除のマークが付けられたインデックスレコードを含むトランザクションのリストが保持されます。 リストの長さはパージラグです。 MySQL 8.0.14 より前では、パージラグ遅延は次の式によって計算されるため、最小遅延は 5000 マイクロ秒になりました:
(purge lag/innodb_max_purge_lag - 0.5) * 10000
MySQL 8.0.14 では、パージラグ遅延は次の改訂された式によって計算され、最小遅延が 5 マイクロ秒に削減されます。 5 マイクロ秒の遅延は、最新のシステムに適しています。
(purge_lag/innodb_max_purge_lag - 0.9995) * 10000
遅延は、パージバッチの開始時に計算されます。
問題のあるワークロードの一般的な innodb_max_purge_lag
設定は 1000000 (100 万) で、トランザクションが小さく、サイズが 100 バイトのみで、100MB のパージされていないテーブルの行を持つことができると想定されます。
パージラグは、SHOW ENGINE INNODB STATUS
出力の TRANSACTIONS
セクションに History list length
値として表示されます。
mysql> SHOW ENGINE INNODB STATUS;
...
------------
TRANSACTIONS
------------
Trx id counter 0 290328385
Purge done for trx's n:o < 0 290315608 undo n:o < 0 17
History list length 20
通常、History list length
は低い値で、通常は数千未満ですが、書込み負荷の高いワークロードまたは長時間実行中のトランザクションは、読取り専用のトランザクションの場合でも増加する可能性があります。 長時間実行トランザクションが原因で History list length
が増加する理由は、REPEATABLE READ
などの読取り一貫性トランザクション分離レベルでは、トランザクションの読取りビューが作成されたときと同じ結果を返す必要があるためです。 したがって、InnoDB
マルチバージョン同時実行性制御 (MVCC) システムは、そのデータに依存するすべてのトランザクションが完了するまで、undo ログにデータのコピーを保持する必要があります。 次に、History list length
が増加する可能性のある長時間実行トランザクションの例を示します:
大量の同時 DML があるときに
--single-transaction
オプションを使用する mysqldump 操作。autocommit
を無効にし、明示的なCOMMIT
またはROLLBACK
の発行を忘れた後のSELECT
クエリーの実行。
パージラグが膨大になる極端な状況での過剰な遅延を防ぐために、innodb_max_purge_lag_delay
変数を設定して遅延を制限できます。 innodb_max_purge_lag_delay
変数は、innodb_max_purge_lag
しきい値を超えた場合に課される遅延の最大遅延をマイクロ秒単位で指定します。 指定された innodb_max_purge_lag_delay
値は、innodb_max_purge_lag
式で計算された遅延期間の上限です。
パージおよび undo テーブルスペースの切捨て
パージシステムは、undo テーブルスペースの切捨ても行います。 パージシステムが切り捨てる undo テーブルスペースを検索する頻度を制御するように innodb_purge_rseg_truncate_frequency
変数を構成できます。 詳細は、undo テーブルスペースの切捨てを参照してください。