おっす! Mysql の MVCC メカニズムについて 1 つの記事で学びましょう!

MVCC の概要 

MVCC (マルチバージョン同時実行制御、マルチバージョン同時実行制御) は、人気のあるデータベースです。同時実行制御テクノロジー。これにより複数のトランザクションが相互にブロックされることなく同時に進行できるため、システムのスループットが向上します。

1. 設計原則

  • 複数のバージョン: データが更新されるたびに、MVCC は元のデータを直接変更しませんが、 データの新しいバージョンを作成します。 。更新前に開始されたトランザクションを処理するために、古いバージョンのデータが保持されます。
  • 読み取りはロックせず、書き込みはブロックしない: MVCC を使用すると、明示的なロックを行わずに読み取り操作と書き込み操作を同時に実行できます。

2.動作原理

  • トランザクション ID:実行中の各トランザクションには一意のトランザクション ID があります。この ID はトランザクションが開始された順に割り当てられます。 。

  • 行のバージョニング: トランザクションがデータ項目を更新する場合、古いデータは直接上書きされません。代わりに、新しいバージョンを作成し、それをトランザクションの ID に関連付けます。古いバージョンは保持され、それを作成したトランザクション ID に関連付けられます。

  • 可視性ルール:トランザクションがデータを読み取る場合、最新バージョンが表示されます。

  • ガベージ コレクション: 時間が経つと、一部のデータの古いバージョンがトランザクションで必要なくなる可能性があります。これらの古いバージョンは、ガベージ コレクションと呼ばれるバックグラウンド プロセスを通じて安全に削除できます。

3. 利点

  • 高い同時実行性: 複数のトランザクションが互いにブロックすることなく、同時にデータを読み取ることができます。
  • ロックフリー読み取り: 読み取り操作はロックを取得する必要がないため、書き込み操作によってブロックされません。

4. チャレンジ

  • 書き込み増幅: 更新ごとに新しいバージョンを保存する必要があるため、書き込み操作が増加し、ストレージ要件が増大する可能性があります。
  • ガベージ コレクション: 不要になった古いバージョンを定期的にクリーンアップするには、追加のプロセスが必要です。

DBA が知っておくべきこと

MVCC (Multi-Version Concurrency Control) は、多くのデータベース システム、特にトランザクション リレーショナル データベース InnoDB ストレージ エンジンをサポートするデータベース システムでデフォルトで有効になっています。 PostgreSQLやMySQLなど。 MVCC をサポートするストレージ エンジンまたはデータベースの使用を選択すると、MVCC のメカニズムが自動的に動作し、データベース管理者 (DBA) による特別な構成や手動処理は必要ありません。

DBA が知っておくべきことは次のとおりです。

  1. MVCC の原理と動作メカニズムを理解する: これは、潜在的なパフォーマンスの問題、ロックの競合、トランザクション分離の問題の解決に役立ちます。
  2. モニタリングとパフォーマンスのチューニング: MVCC は同時実行性を大幅に向上させますが、ストレージ要件の増加 (データのバージョンが複数あるため) や I/O 操作の増加など、追加のオーバーヘッドも発生する可能性があります。 (古いバージョンのデータをクリーンアップする必要があるため)。したがって、DBA はデータベースのパフォーマンスを監視して、リソースが適切に利用されていることを確認し、必要に応じて最適化を行う必要がある場合があります。
  3. ガベージ コレクションとバージョンのクリーンアップ: 最新のデータベース システムの多くは古いバージョンのデータを自動的にクリーンアップしますが、場合によっては、DBA がこのプロセスを理解したり、介入したりする必要がある場合があります。たとえば、清掃頻度を調整したり、清掃操作を手動でトリガーしたりできます。

MVCC のガベージ コレクション メカニズム

マルチバージョン同時実行制御 (MVCC) のコンテキストにおけるガベージ コレクション メカニズムは、主に、不要になったデータ バージョンをクリアすることを指します。 MySQL の InnoDB ストレージ エンジンでは、これには通常、期限切れとしてマークされた行バージョンのクリーンアップが含まれます。では、有効期限を判断する基準は何でしょうか?

  1. ガベージ コレクションの判定条件:

    • トランザクションのライフサイクル: トランザクションがコミットされると、トランザクションによって生成された以前の行バージョンは必要なくなる場合があります。ただし、一貫した読み取りビューを提供するためにこれらの以前のバージョンを必要とする他の長時間実行トランザクションが存在する可能性があるため、それらをすぐに削除することはできません。
    • 読み取りビュー: InnoDB は、現在実行中のすべてのトランザクションの「読み取りビュー」を維持します。古いバージョンは、トランザクションで不要になった場合にのみリサイクル対象としてマークされます。したがって、標準は次のとおりです。このバージョンを必要とするトランザクションがなくなった場合、そのバージョンは期限切れであると判断されます。 読み取りビューとは何ですか?それを踏まえてどう判断するのか?これについては以下で説明する。
  2. 回收方式

    • パージ スレッド: InnoDB にはパージ スレッドと呼ばれる内部スレッドがあり、そのジョブは期限切れの行バージョンを削除することです。パージ操作はバックグラウンドで実行され、通常は実行中のクエリに直接影響を与えません。
    • マージ オペレーション: 更新オペレーション中にデータ ページが生成する履歴バージョンが多すぎる場合、InnoDB はマージ オペレーションをトリガーして、データ ページをその履歴バージョンとマージし、行をクリアすることがあります。不要になったバージョン。
  3. 手动调节

    • innodb_purge_threads: パージスレッドの数を設定します。スレッドを増やすとクリーンアップ プロセスが高速化される可能性がありますが、CPU 使用率も増加します。通常はデフォルト値で十分です。
    • innodb_purge_batch_size: 各パージ操作で削除された行バージョンの数。この値を増やすとクリーンアップ プロセスが高速化される可能性がありますが、I/O 負荷も増加する可能性があります。
    • innodb_max_purge_lag: パージ操作の遅延を制御して、他の操作への影響を軽減するために使用されます。遅延がこの値を超えると、InnoDB は DML 操作を遅くし、パージ操作が追いつくまでの時間を増やします。

これらのパラメータを調整する場合は、クリーンアップ オペレーションと他のデータベース アクティビティの間でリソース使用量のバランスを取ることが重要です。スクラブが多すぎるとデータベースのパフォーマンスに影響を与える可能性があり、スクラブが不十分だとスペースが無駄になり、パフォーマンスが低下する可能性があります。パラメータを調整する前に、後で調整の効果を比較できるように、現在のデータベース パフォーマンスのベースラインを作成することをお勧めします。


ビューを読む!

「ビューの読み取り」は InnoDB の重要な概念であり、同時トランザクションがデータを変更している場合でも、トランザクションがデータの一貫したビューを参照できるようにします。 MVCC では、各トランザクションには読み取りビューが関連付けられており、これによってトランザクションがどの行バージョンを「表示」できるかが決まります。

「古いバージョンは、トランザクションが必要なくなった場合にのみリサイクル可能としてマークされます」というときのロジックは、次の考慮事項に基づいています。

1. アクティブなトランザクション: InnoDB は現在アクティブなトランザクションをすべて追跡します。
2. トランザクション ID: 各トランザクションには一意の ID があります。データの行が変更されると、InnoDB は変更を行ったトランザクションを記憶し、その行に新しいバージョンを割り当てます。この新しいバージョンの行には、それを変更したトランザクション ID に関連付けられたタグが含まれます。

3. 最も古いアクティブなトランザクション: この識別子は、現在実行中のすべてのトランザクションの中で最も早く開始されたトランザクションを指します。どのデータ バージョンが「古い」と見なされ、ガベージ コレクションの対象となる可能性があるかが決定されるため、その存在は非常に重要です。 InnoDB は、現在アクティブなすべてのトランザクションの中で最も早く開始されたトランザクション、つまり「最も古いアクティブなトランザクション」の ID を常に知っています。最も古いトランザクションが (コミットまたはロールバックによって) 終了すると、InnoDB はまだアクティブな次に古いトランザクションを探し、その識別子を更新します。このようにして、データベースは、現在アクティブなすべてのトランザクションのうち、最も早く開始されたトランザクションを常に追跡します。

4. 可視性の決定: 行バージョンとトランザクションが与えられると、InnoDB はトランザクションが行バージョンを参照する必要があるかどうかを決定できます。ルールは単純です。行バージョンのトランザクション ID が現在のトランザクションより前にあり、「最も古いアクティブなトランザクション」より後である場合、この行バージョンは現在のトランザクションに表示されます。

作成者は次のように要約しています。トランザクション ID が存在する限り、すべてのトランザクションの現在読み取り可能なデータのビューを作成することです。データが配置されている行は、このデータは現在のトランザクションと最初のトランザクションの間で読み取り可能です。 すべてのアクティブなトランザクションの読み取りビューに特定のバージョンのデータがない場合、このデータはリサイクルできます。

したがって、InnoDB は、行バージョンがまだ必要かどうかを判断しようとするときに、すべてのアクティブなトランザクションを調べます。古い行バージョンがすべてのアクティブなトランザクションに表示されない場合 (つまり、すべてのトランザクションが行バージョンよりも新しいトランザクション ID を持つ場合)、行バージョンをリサイクルできます。

このメカニズムにより、トランザクションでまだ必要な行バージョンが途中で削除されないようにすることができます。これは、MVCC が保証する一貫した読み取りビューの中核です。


このプロセスをもう少し詳しく見てみましょう。

  1. トランザクションの開始時に読み取りビューを取得する:トランザクションが開始されると、MVCC メカニズムによってそのトランザクションの読み取りビューが特別に修正されます。このビューは、現在アクティブなすべてのトランザクションによって決定されます。これは、トランザクションの存続期間全体を通じて、トランザクションの開始前にコミットされたトランザクションによって行われたすべての変更を確認できることを意味し、表示されるデータ バージョンは一貫しています。ただし、開始後に他の同時トランザクションによって行われた変更を確認することはできず、他の同時トランザクションの影響を受けません。 同様に、トランザクションがオペレーションを実行するとすぐに、その写真が撮影されます。写真には、写真が撮影されたときにアクティブなトランザクションとバインドされたデータがすべて含まれています。撮影 a>した場合、この写真の内容はトランザクションが完了するまで変更されず、内部のデータ バージョンは一貫しています。

  2. 新しいトランザクションと古いデータ: データのバージョンがリサイクルされると、新しいトランザクションでこのバージョンを必要とすることはできなくなります。新しいトランザクションには、より高いトランザクション ID に基づいて決定される新しい読み取りビューがあるため、リサイクルされた古いデータ バージョンには戻りません。 言い換えると、新しいトランザクションの実行が開始され、私たちはそのトランザクションの写真を撮り続けますが、残念なことに状況は変化し、人々も変わり、一部のトランザクションにバインドされたデータはリサイクルされています。したがって、 a>、発見されることも不可能です。新しいオフィスで使用されています。 写真が撮影されたときにアクティブなトランザクションに表示されることは不可能

  3. 新しいトランザクションの読み取りビューは、現在アクティブなすべてのトランザクションよりも高いトランザクション ID に基づいて作成されます。したがって、新しいトランザクションでは、古いものとしてマークされ、ガベージ コレクションされたバージョンのデータが必要になることはありません。簡単に言うと、新しいトランザクションは、「後方」ではなく、常に「前方」を参照します


著者の質問

このことを知った後、著者は次のような疑問を抱きます。

データは、すべてのアクティブなトランザクション読み取りビューで表示されなくなった場合にのみリサイクルされます。トランザクションが多すぎると、トランザクションがアクティブ キューに入る時間がなくなってしまいますか?リサイクル後に新しいトランザクションがアクティブになり始めることがありますが、リサイクルされたばかりのデータは必要ですか?

回答: この状況は、MySQL の InnoDB ストレージ エンジンなどの従来の RDBMS では発生する可能性は低いです。これは、トランザクション管理とスケジューリングがデータベースの中核機能であり、トランザクションのライフサイクルや状態が厳密に管理されているためです。トランザクションが開始されると、すぐに一意のトランザクション ID が割り当てられ、アクティブなトランザクション リストに追加されます。いくつかの重要なポイントを次に示します。

  1. トランザクション ID: InnoDB では、各トランザクションには最初に一意の増分トランザクション ID が割り当てられます。これにより、すべてのトランザクションを正確に識別して追跡できるようになります。

  2. 読み取りビューの作成タイミング: トランザクションは最初の読み取り操作 (場合によっては書き込み操作) を実行するときに、読み取りビューを作成します。この読み取りビューには、その時点で実行されている他のすべてのアクティブなトランザクションのトランザクション ID が含まれます。

  3. 同時実行制御: データベース システムは通常、数千、場合によっては数万の同時トランザクションを処理できます。トランザクションのスケジューリング、ロック管理、同時実行制御戦略はすべて、システムのスムーズな動作を保証するように設計されています。

  4. リソース制限: メモリ不足など、システム リソースが制限されている場合、トランザクション処理に影響を与える可能性があります。ただし、この場合でも、トランザクションは「忘れられた」わけではありません。 リソース不足によりトランザクションが遅延したり失敗したりする可能性があります。

  5. デッドロックと待機: 同時実行性の高い環境では、同じリソースに対する競合により、トランザクションがデッドロックまたは待機状態になることがあります。通常、データベース エンジンには、トランザクションの 1 つを中止してデッドロックを解決するなど、これらの状況に対処するためのデッドロック検出メカニズムが備わっています。

簡単に言えば、InnoDB などのデータベース システムは、同時実行性の高い環境で確実に動作するように設計されており、各トランザクションが正しく追跡および管理され、トランザクションが「失われた」または「忘れられた」ことはありません。


著者は引き続き調査を続ける

上記の内容:リソース不足によりトランザクションが遅延または失敗する可能性が考えられます。 これにより、新しいトランザクションがアクティブに開始されますが、リサイクルされたばかりのデータが必要になりますか?

リソースの制約(メモリ不足など)によりトランザクションが遅延した場合でも、そのデータ ビュー(読み取りビュー)は開始時の状態に基づいて維持されます。データの一貫性のセックス。 MVCC では、トランザクションの実際の操作が遅延した場合でも、システムはトランザクション開始時の状態を記憶し、必要な情報をすべて保持します。データ版。 この観点から見ると、遅延したトランザクションは、バージョン クリーニングによって必要なデータを失うことはありません。

さらに詳しい説明:

  • データ バージョンの保持: トランザクションが開始されている場合、InnoDB ストレージ エンジンは、トランザクションが開始時に存在していたすべてのデータ バージョンを確認できるようにします。これらのデータ バージョンのライフ サイクルが通常のガベージ コレクション サイクルを超えた場合でも、これらのバージョンはパージされません。 つまり、トランザクションは遅延または失敗する可能性があり、再開される可能性があります。 ただし、 前に開始されているはずです。読み取りビューの風景が必ず表示されます。たとえ失敗しても、ハングしても、再起動してもデータのメンタル バージョンはリサイクルされません。

  • ガベージ コレクションの条件: データ バージョンは、アクティブなトランザクションがそれを必要としないと判断された場合にのみクリーンアップされます。これは、トランザクションが延期された場合でも、依然として「アクティブなトランザクション」としてカウントされ、データベース システムは必要なデータのバージョンをリサイクルしないことを意味します。

実際には、InnoDB の MVCC メカニズムにより、トランザクションが遅延したり失敗したりした場合でも、データの一貫性が影響を受けないことが保証されます。これは、古いバージョンを必要とするトランザクションがなくなるまでバージョンのクリーンアップを遅らせることによって行われます。トランザクションが遅延または失敗した後に再開される場合、クリーンアップされた古いバージョンではなく、現在有効なバージョンのデータに依存する必要があります。


MVCC – きっぱりと?

MVCC (Multiple Version Concurrency Control) は、ファントム リード、非反復読み取り、ダーティ リード< などのデータベース システムの同時実行の問題を解決するように設計されています。 a i=2> など。これらの問題は通常、複数のトランザクションが同じデータ セットに対して同時に動作し、変更をコミットしようとしたときに発生します。 MVCC は、読み取りトランザクションごとにデータのスナップショットを作成することでこれらの問題を回避します。これにより、他のトランザクションが同時にデータを変更している場合でも、トランザクションで認識されるデータの一貫性がその実行中に維持されます。

MVCC は同時実行制御のメカニズムを提供しますが、トランザクションの分離レベルを設定して、さまざまな同時実行の問題をシミュレートおよび観察することもできます。

  1. ダーティ リード: トランザクションが、コミットされていない別のトランザクションのデータを読み取ります。その結果、コミットされていないトランザクションは予期せず取り消されますが、データはまだ記憶されています。 MVCC モデルでは、トランザクションはコミットされた変更のみを参照できるため、デフォルトではダーティ リードは発生しません。ただし、一部のデータベースでは、トランザクション分離レベルを「Read Uncommitted」に設定して、ダーティ リードをシミュレートできます。

  2. 反復不可能な読み取り: 同じトランザクション内で、オペレーションがデータを 2 回読み取り、その 2 回の読み取りの間に別のトランザクションがコミットされるため、最初の読み取りは読み取りデータと矛盾します。二回目。 MVCC では、Read Committed などの低い分離レベルを設定することで、反復不可能な読み取りを監視できます。

  3. ファントム読み取り: 別のトランザクションによって追加されたデータ行が 1 つのトランザクションで読み取られることを意味します。 MVCC であっても、トランザクション分離レベルがシリアル化可能でない場合、ファントム読み取りの問題が発生する可能性があります。リピータブルリード分離レベルでは、ファントムリードの問題を制御できます。

  4. シリアル化可能 (シリアル化可能): これは最高の分離レベルです。ロックまたはその他のメカニズムを使用して、トランザクションの実行結果がシリアル実行の結果と一貫していることを保証します。通常、このレベルでは上記の同時実行性の問題がすべて回避されますが、パフォーマンスの低下やロック競合が発生する可能性があります。

MVCC が使用されている場合でも、分離レベルが十分に高く設定されていない場合は、引き続きこれらの問題が発生する可能性があります。 データベースやストレージ エンジンが異なれば、これらの分離レベルの具体的な実装方法も異なる場合があります。したがって、適切なトランザクション分離レベルを理解して設定することは、DBA やデータベース開発者にとって考慮すべき重要な部分であり続けます。

おすすめ

転載: blog.csdn.net/qq_65052774/article/details/134109227