MySQL マルチバージョン同時実行制御 MVCC の実装

MySQL マルチバージョン同時実行制御 MVCC の実装

MVCCとは

MVCC は、マルチバージョン同時実行制御の略です。

MySQL のトランザクション ストレージ エンジンは、マルチバージョン同時実行制御 (MVCC) を通じて同時実行パフォーマンスを向上させます。

MVCC は行レベル ロックのバリエーションと考えることができますが、ほとんどの場合ロック操作を回避し、非ブロッキング読み取り操作を実装するため、オーバーヘッドは低くなります。

MVCC は、特定の時点のデータのスナップショットを保存することによって実装されます。基本的な考え方は、データの履歴バージョンを保存し、データ行の複数のバージョンを管理することでデータベースの同時実行制御を実装することです。

このようにバージョン番号を比較することでデータを表示するかどうかを決定でき、データ読み取り時にロックをかけずにトランザクションの分離効果を確保できます。

MVCC 実装

実際、InnoDB はレコードの各行の後に 3 つの隠しフィールドを追加します。

  • ROW_ID: 行 ID。新しい行が挿入されるたびに単調に増加します。主キーがある場合、この列は含まれません。
  • TRX_ID: 行を挿入または更新したトランザクションのトランザクション ID を記録します。
  • ROLL_PTR: ロールバック ポインター。UNDO ログ レコードを指します。レコードが変更されるたびに、列にポインターが格納され、それを通じてレコードが変更される前の情報を見つけることができます。レコードが複数回変更されると、行レコードの複数のバージョンが存在し、それらは ROLL_PTR によってリンクされ、バージョン チェーンに似た概念を形成します。

RR レベルを例に挙げます。

トランザクションが開かれるたびに、システムはトランザクションにトランザクション ID を割り当てます。トランザクションで最初の SELECT ステートメントが実行されると、現在の時点でのトランザクション スナップショット ReadView が生成されます。これには主に次のプロパティが含まれます。

  • m_ids: ReadView が生成された時点での現在のシステム内のコミットされていない読み取りおよび書き込みトランザクションのトランザクション ID リストを示します。
  • min_trx_id: ReadView が生成された時点での現在のシステム内のコミットされていない読み取り/書き込みトランザクションの中で最小のトランザクション ID、つまり m_ids の最小値を示します。
  • max_trx_id: ReadView を生成するときにシステム内の次のトランザクションに割り当てる ID 値を示します。
  • Creator_trx_id: ReadView が生成された際のトランザクションのトランザクション ID を示します。

この ReadView を使用すると、レコードにアクセスするときに、レコードのバージョンが表示されているかどうかを判断するには、次の手順に従うだけで済みます。

  • trx_id == Creator_trx_id: このバージョンにアクセスできます。
  • trx_id < min_trx_id : このバージョンにアクセスできます。
  • trx_id > max_trx_id: このバージョンにはアクセスできません。
  • min_trx_id <= trx_id <= max_trx_id: trx_id が m_ids 内にある場合、このバージョンにはアクセスできませんが、それ以外の場合は利用可能です。

判定を行う際は、まずレコードの最新バージョンを比較します。現在のトランザクションで参照できないバージョンの場合は、レコードの ROLL_PTR を通じて以前のバージョンを探し、現在のトランザクションで参照できるバージョンが見つかるまで再度比較します。
削除は実際には特別な更新です。InnoDB は、データが削除されたかどうかを示すために、追加のフラグ ビット delete_bit を使用します。判断を行うときは、delete_bit がマークされているかどうかを確認します。マークされている場合は、このバージョンをスキップし、ROLL_PTR を介して次のバージョンを取得して判断します。

上記の内容は RR レベルの場合です。RC レベルの場合、全体のプロセスはほぼ同じです。唯一の違いは、ReadView が生成されるタイミングです。RR レベルでは、トランザクションの開始時に 1 回だけ生成され、その後は常に ReadView が使用されます。 RC レベルでは、選択が行われるたびに ReadView が生成されます。

MVCC はファントム リードを解決しますか?

ファントム リード: トランザクション内で同じ SQL を使用して 2 回読み取りが行われ、2 回目の読み取りには他のトランザクションによって新しく挿入された行が含まれます。
例えば:

1) トランザクション 1: 最初のクエリ: select * from user where id < 10と、id = 1 のデータが見つかります。

2) トランザクション2はID = 2のデータを挿入します

3) トランザクション 1 が同じステートメントを使用して 2 回目のクエリを実行すると、id = 1 と id = 2 のデータが見つかり、ファントム リードが発生します。

ファントム リードについて説明するときは、まず「現在の読み取り」と「スナップショット読み取り」の概念を紹介する必要があります。

  • スナップショット読み取り: トランザクション スナップショット (ReadView) を生成し、このスナップショットからデータを取得します。通常の選択ステートメントはスナップショット読み取りです。
  • 現在の読み取り: 最新バージョンのデータを読み取ります。一般的な更新/挿入/削除、更新のための選択...、共有モードでの選択...ロックはすべて現在の読み取りです。

スナップショット読み取りの場合、MVCC は ReadView から読み取るため、新しく挿入された行を認識しません。そのため、ファントム読み取りの問題は自然に解決されます。

ただし、MVCC では現在の読み取りのファントム リードは解決できません。この問題を解決するには、ギャップ ロックまたは次のキー ロック (ギャップ ロック + レコード ロック) を使用する必要があります。

実際、原理は非常に単純です。上記の例を少し変更して、現在の読み取りをトリガーします。

更新のためにIDが10未満のユーザーから*を選択

ギャップ ロックを使用すると、ギャップ ロックによって ID < 10 の範囲全体がロックされるため、他のトランザクションは ID < 10 のデータを挿入できず、ファントム リードが防止されます。

これで、MySQL マルチバージョン同時実行制御 MVCC の実装に関するこの記事は終了です。MySQL マルチバージョン同時実行制御 MVCC に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQLクエリキャッシュメカニズムの基礎学習チュートリアル
  • MySQL セレクトキャッシュメカニズムの使用に関する詳細な説明
  • MySQL マルチバージョン同時実行制御 MVCC の詳細な研究
  • MySQL マルチバージョン同時実行制御 MVCC の基本原理の分析
  • MYSQL トランザクション分離レベルと MVCC
  • MySQL の MVCC と BufferPool キャッシュ メカニズムの詳細な理解

<<:  この記事では、Vueのフロントエンドページングとバックエンドページングを実装する方法を説明します。

>>:  HTML ページにミュージック ビデオを追加する例

推薦する

winx64 での mysql5.7.19 の基本的なインストール プロセス (詳細)

1. ダウンロード参考: https://www.jb51.net/softs/451120.ht...

vue の v-bind を理解する

目次1. v-bindの主要ソースコードの分析1. v-bind属性はどこに均一に保存されるか: a...

Dockerコンテナの自動終了を停止する方法の詳細な説明

この記事では、Docker コンテナとフロントエンド プロセスの関係と、コンテナを永続的に実行できる...

html-webpack-plugin' を使用してメモリ内に HTML ページ プラグインを生成します。

webpackjs ファイルをパッケージ化するときに、次に示すように、index.html インタ...

ES6スプレッド演算子の使用例

目次スプレッド演算子とレスト演算子とは何ですか?配列スプレッド演算子残り演算子(コレクション関数)ス...

反応ルーティングでパラメータを渡すいくつかの方法についての簡単な説明

最初のパラメータ渡し方法は、動的ルーティングパラメータ渡しです。リンクのパス属性を設定することで、ル...

Jenkins を使用した Vue プロジェクトのワンクリック パッケージングと公開の実装

目次Jenkinsのインストールインストールポート番号を変更します(デフォルトのポートは8080です...

vsftpd ユーザーが ssh 経由でログインすることを禁止する方法

序文vsftp は使いやすく安全な FTP サーバー ソフトウェアです。システムユーザーまたは仮想ユ...

ミニプログラムは左スライドのドロワーメニューをネイティブに実装します

目次WXS レスポンス イベントプランAページ構造とスタイルWXS イベントコールバック関数WXS ...

FileZilla を使用して FTP サーバーに接続するプロセスの図

最初にサーバー上に FTP サーバーをセットアップし始めたとき、接続できないことがわかったので、Fi...

Vueバックグラウンド管理に多言語機能を追加する例

目次1.まず、main.jsページを設定します2. 対応するパスの下で言語パックを構成します。ここに...

MySQL 8.0.18 インストール構成の最適化チュートリアル

MySQLのインストール、設定、最適化は参考用です。具体的な内容は次のとおりです。 MySQL ダウ...

Echarts バー水平棒グラフのサンプルコード

目次横棒グラフデータとスタイルを動的に更新するeChartsの幅と高さの適応の問題を解決する縦棒グラ...

Mysql GTID Mha 設定方法

Gtid + Mha + Binlog サーバー構成: 1: テスト環境OS: CentOS 6.5...

高品質なJavaScriptコードの書き方

目次1. 読みやすいコード1. 統一コード形式2. マジックナンバーを削除する3. 単一機能原則2....