MVCCの実装原理
mvcc的实现,基于undolog、版本链、readview。(具体就如下图)
MySQL に保存されているデータには、MySQL はデフォルトで、trx_id
や roll_pointer
などの追加の隠しフィールド (隠しフィールド) を追加します。これらのフィールドのほとんどは、トランザクションやデータ回復などの機能をサポートするために使用されます。
trx_id
: これは、システムによって自動的に生成される増分整数で、現在の操作が実行されるトランザクションを識別するために使用されます。新しいトランザクションが開始されるたびに、トランザクション ID は 1 ずつ増加します。トランザクション ID はシステムによって自動的に生成されるため、通常は手動で変更する必要はありません。roll_pointer
: 以前のバージョンのデータを見つけるために使用されるポインターです。レコードを変更すると、MySQL は内部でレコードのコピーを作成し、REDO ログに保存します。同時に、このコピーの位置を REDO ログに記録します。これはroll_pointer
表現されるコンテンツ。ロールバック操作が発生した場合、MySQL はroll_pointer
を使用して、対応するレコードの前のバージョンを見つけて復元します。
非常に多くのバージョンがある場合、選択クエリがある場合、具体的にどのバージョンがクエリされるのでしょうか?
readview は、この問題の解決に役立つビューを読み取ります。
select を使用してデータを読み取る場合、現時点では多くのバージョンのデータが存在します (たとえば、上の図には 4 つのバージョンがあります) が、どのバージョンを読み取るかはわかりません。私たちは readview に依存しています。読み取れるバージョンが制限されているため、どのバージョンを読み取れるかは readview を通じてのみわかります。
トランザクション選択がデータをクエリすると、データ バージョン チェーンのいくつかの統計値を記録する読み取りビューが構築されます。これにより、後続のクエリ処理中にすべてのバージョン チェーンをトラバースする必要がなくなります。
readview スナップショットには、具体的には次のフィールドが含まれます。
readview のパラメータについていくつか説明します。
m_ids:アクティブなトランザクションは、まだコミットされていないトランザクションを指します (アクティブな [未コミット] トランザクションはコレクションのように表示されます)。
max_trx_id:たとえば、m_ids のトランザクション ID が (1, 2, 3) の場合、次に割り当てる必要があるトランザクション ID は 4 で、max_trx_id は 4 になります。
creator_trx_id: 現在選択読み取りオペレーションを実行しているトランザクションの ID。
readview は、バージョン チェーン内のどのバージョンが利用可能かを具体的に決定します (強調!)。
4 段階の検索ルール——
ステップ 1: バージョンが現在のトランザクションによって作成されたかどうかを確認する
場合creator_trx_id=[現在のバージョン trx_id] は、変更したデータを読み取ることを意味します。もちろん、直接アクセスできます。現在のバージョンの trx_id と等しくない場合は、2 番目のステップに進みます
ステップ 2: [現在のバージョン trx_id] が min_trx_id 未満かどうか
[現在のバージョン trx_id]。このバージョンは readview を生成する前に送信されており、直接アクセスできることを示します。そうでない場合は、ステップ 3 に進みます
ステップ 3: [現在のバージョンの trx_id] は max_trx_id より大きいか
[現在のバージョン trx_id]>max_trx_id。この バージョンは、readview が生成された後にのみ開かれることを示します。 、確かに現在のトランザクションはアクセスできませんので、この時点でトラバースして次のトランザクションを決定するために 4 番目のステップを実行する必要はありません。バージョン。現在のバージョンのトランザクション ID が最大トランザクション ID 未満の場合は、ステップ 4 に進むことができます
ステップ 4: min_trx_id<[現在のバージョンの trx_id]
現在のバージョンがアクティブなトランザクション リストにない場合は、リードビューの作成時にバージョンが送信され、直接アクセスできます。
アクティブなトランザクション リストにある場合、要件を満たす最初のバージョンが見つかるまで、バージョン チェーンのトラバースに従って次のバージョンが判断されます。
上から順に(1)(2)(3)(4)となっておりますので、もう一度説明していただき、印象を深めてください。
trx_id は、読み取られるトランザクション ID を示します。
(1) 読み込むトランザクション ID が読み取り操作のトランザクション ID と等しい場合、自分で作成したレコードを読み取っていることになりますが、なぜそうではないのでしょうか。
(2) 読み出し対象のトランザクション ID がアクティブな最小トランザクション ID 未満の場合、読み出し対象のトランザクションは送信済みであり、読み出し可能であることを意味します。
(3) max_trx_id は readview 生成時に次のトランザクションに割り当てられる ID を示し、読み込むトランザクション ID が max_trx_id より大きい場合、その ID は readview のバージョンチェーンに存在しないことを意味するため、アクセスできません。
(4) m_ids にはアクティブなトランザクションの ID が格納されており、読み込むトランザクション ID がアクティブリストにない場合は読み出すことができますが、その逆はできません。
mvcc が RC および RR の分離レベルを実装する方法
(1)RC 分離レベル、各 スナップショット読み取り< a i=4 >最新の readview を生成して取得します。
(2)RR 分離レベル、同じトランザクション内のみ の最初のスナップショット読み取りは、その後すべて、 読み取りビュー を作成します。スナップショット読み取りは同じ読み取りビューを使用するため、 のすべてのクエリ結果は同じになります。 。