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 ページにミュージック ビデオを追加する例

推薦する

MySQL 接続制御プラグインの紹介

目次1. 接続制御プラグイン(connection_control)の紹介1.1 connectio...

Zabbix 監視 Docker アプリケーション構成

コンテナの応用はますます一般的になっていますが、大量のコンテナをどのように管理すればよいのでしょうか...

フロントエンド JavaScript でローカルあいまい検索機能を実装する方法の例

目次1. プロジェクトの見通し2. 知識ポイントObject.assign() の使用法filter...

LinuxでRPMを使用してmysql5.7.17をインストールする

LinuxでのMySQL5.7 rpmのインストール方法を参考までに記録します。具体的な内容は以下の...

Linux で完全な Samba サーバーを構築する方法 (CentOS バージョン)

序文smb は、クライアントとサーバー間の Web 接続および情報通信に使用できるプロトコルの名前で...

MySQLの保存場所を新しいディスクに移行する方法

1. 新しいディスクを準備し、現在のルートパーティションと同じファイルシステムでフォーマットし、ディ...

html オプション 無効 選択 選択 無効 オプションの例

コードをコピーコードは次のとおりです。 <選択> <オプション値="&q...

Centos7.4 サーバーへの Apache のインストールとインストール プロセス中に発生した問題の解決策

この記事では、CentOS 7.4 サーバーに Apache をインストールする方法と、インストール...

JavaScript の onblur および onfocus イベントの詳細な説明

HTML ページでは、ボタンやテキスト ボックスなどの視覚要素にフォーカスを設定したり、フォーカスを...

iPhone デバイスの WAP ページでフォントサイズが大きい問題の解決策

JavaScriptコントロールを使用したくない場合は、次の方法を試してください。 Safariブラ...

Vueコンポーネント間の通信の非常に詳細な要約

目次序文1. Props、$emit一方向データフロー2. $親、$子3. $attrs、$list...

Jsonフォーマットの詳細な説明

目次JSON は次の 2 つの構造に基づいて構築されます。 2. JSON形式1. オブジェクト2....

TypeScript ジェネリックを簡単に説明する方法

目次概要ジェネリック医薬品とはビルドシステムジェネリック医薬品の一般的な理解ジェネリッククラスジェネ...

Nginxサービス500:内部サーバーエラーの原因の1つ

500 (内部サーバー エラー) サーバーでエラーが発生したため、要求を完了できませんでした。 50...

ウェブページサイズに関する調査

<br />統計によると、Web ページの平均サイズは 2003 年以降 3 倍に増加し...