GCの概要
TiDBはMVCCを使用してトランザクションの同時実行を制御します。データを更新しても、元のデータはすぐには削除されず、新しいデータと一緒に保持され、バージョンを区別するためのタイムスタンプが付与されます。ガベージコレクション(GC)の目的は、古くなったデータをクリアすることです。
GCプロセス
各 TiDB クラスターには、GC プロセスを制御する GC リーダーとして選択される TiDB インスタンスが含まれています。
TiDBでは、GCが定期的に実行されます。GCごとに、TiDBはまず「セーフポイント」と呼ばれるタイムスタンプを計算します。次に、セーフポイント以降のすべてのスナップショットがデータの整合性を保持しているという前提で、TiDBは古いデータをクリアします。具体的には、各GCプロセスには以下の3つのステップが含まれます。
- ロックを解決します。このステップでは、TiDB はすべてのリージョンのセーフ ポイントの前のロックをスキャンし、これらのロックをクリアします。
- 範囲を削除します。このステップでは、
DROP TABLE
/DROP INDEX
操作で生成された範囲全体の古いデータがすぐにクリアされます。 - GC を実行します。このステップでは、各 TiKV ノードがそのデータ全体をスキャンし、各キーの不要な古いバージョンを削除します。
デフォルト設定では、GCは10分ごとに実行されます。各GCは直近10分間のデータを保持するため、GCの有効期間はデフォルトで10分となります(安全点 = 現在時刻 - GC有効期間)。あるGCの実行時間が長すぎる場合、そのGCが完了する前に次のGCは開始されません。たとえ次のGCの実行時間になっても、安全点が実行中のトランザクションの開始時刻(start_ts)を超えないようにする必要があります。また、GC有効期間を超過した後も長時間トランザクションが正常に実行されるように、安全点は現在実行中のトランザクションの開始時刻(start_ts)を超えないようにする必要があります。
実装の詳細
ロックを解決する
TiDBトランザクションモデルはGoogleのパーコレーターに基づいて実装されています。これは主に2フェーズコミットプロトコルであり、実用的な最適化がいくつか施されています。第1フェーズが終了すると、関連するすべてのキーがロックされます。これらのロックのうち、1つはプライマリロックで、残りはプライマリロックへのポインタを含むセカンダリロックです。第2フェーズでは、プライマリロックを持つキーに書き込みレコードが取得され、そのロックが解除されます。書き込みレコードは、このキーの履歴またはトランザクションロールバックレコードにおける書き込みまたは削除操作を示します。プライマリロックを置き換える書き込みレコードの種類は、対応するトランザクションが正常にコミットされたかどうかを示します。その後、すべてのセカンダリロックが順次置き換えられます。障害などの何らかの理由でこれらのセカンダリロックが保持され、置き換えられない場合でも、セカンダリロックの情報に基づいてプライマリキーを見つけ、プライマリキーがコミットされたかどうかに基づいてトランザクション全体がコミットされたかどうかを判断できます。ただし、GCによってプライマリキー情報がクリアされ、このトランザクションにコミットされていないセカンダリロックがある場合、これらのロックがコミット可能かどうかを知ることはできません。その結果、データの整合性は保証されません。
「ロックの解決」ステップは、セーフポイントの前のロックをクリアします。つまり、ロックの主キーがコミットされている場合は、このロックもコミットする必要があります。そうでない場合は、ロールバックする必要があります。主キーがまだロックされている場合(コミットもロールバックもされていない場合)、このトランザクションはタイムアウトと見なされ、ロールバックされます。
ロックの解決ステップは、システム変数tidb_gc_scan_lock_mode
を使用して構成できる次の 2 つの方法のいずれかで実装されます。
LEGACY
(デフォルト): GC リーダーは、すべてのリージョンに古いロックをスキャンするリクエストを送信し、スキャンされたロックの主キーのステータスを確認し、対応するトランザクションをコミットまたはロールバックするリクエストを送信します。PHYSICAL
: TiDB はRaftレイヤーをバイパスし、各 TiKV ノード上のデータを直接スキャンします。
範囲を削除
DROP TABLE/INDEX
ような操作では、連続するキーを持つ大量のデータが削除されます。各キーを削除して後でGCを実行すると、storage回収の実行効率が低下する可能性があります。このようなシナリオでは、TiDBは実際には各キーを削除しません。代わりに、削除する範囲と削除のタイムスタンプのみを記録します。その後、「範囲削除」ステップで、タイムスタンプが安全点より前の範囲に対して、高速な物理削除を実行します。
GCを実行する
Do GCステップは、すべてのキーの古いバージョンをクリアします。セーフポイント以降のすべてのタイムスタンプのスナップショットが一貫性を保つように、このステップではセーフポイントより前にコミットされたデータは削除されますが、削除でない限り、セーフポイントより前の各キーの最後の書き込みは保持されます。
このステップでは、TiDBはセーフポイントをPDに送信するだけで、GCラウンド全体が完了します。TiKVはセーフポイントの変更を自動的に検出し、現在のノード上のすべてのリージョンリーダーに対してGCを実行します。同時に、GCリーダーは次のGCラウンドをトリガーし続けることができます。
注記:
TiDB 5.0以降、Do GCステップでは常に
DISTRIBUTED
モードが使用されます。これは、TiDBサーバーが各リージョンにGCリクエストを送信することで実装されていた以前のCENTRAL
モードに代わるものです。