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

推薦する

マークアップ言語 - タイトル

123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...

Centos7.9 で独立したメール サーバーを構築するための詳細な手順

目次序文1. イントラネットDNS AレコードとMXレコードを構成する2. メールサーバの初期化設定...

CSSマスクのフルスクリーン中央揃えを実装する方法

具体的なコードは次のとおりです。 <スタイル> #トーストローダーフルスクリーン{ 高さ...

MySQL でデータ テーブルを作成し、主キーと外部キーの関係を確立する方法の詳細な説明

序文MySQL テーブルの主キーと外部キーを作成するときは、次の点に注意する必要があります。主キーと...

LinuxベースのApacheウェブサイトサービス構成の詳細な説明

オープンソース ソフトウェアである Apache は、最も広く使用されている Web アプリケーショ...

Ajax リクエストにおけるクロスドメイン問題の原因と解決策

目次1. クロスドメインはどのように形成されるのでしょうか? 2. クロスドメインの根本的な原因3....

HiveメタデータをMySQLに設定するプロセス全体

Hiveのインストールディレクトリで、confディレクトリに入り、hive-site.xmlファイル...

Vueはマーキースタイルのテキストの水平スクロールを実装します

この記事では、マーキースタイルのテキストの水平スクロールを実現するためのVueの具体的なコードを参考...

vscode で Prettier Code プラグインを使用する詳細なチュートリアル

なぜprettierを使うのですか?大企業では、フロントエンド開発コードに独自のコード標準がある場合...

git bash を使用して Linux にログインするための ssh の設定方法

1. まず、Linux サーバー上で公開鍵ファイルと秘密鍵ファイルを生成します。デフォルトの保存ディ...

Vue における ref と $refs の紹介と使用例

序文JavaScript では、document.querySelector("#demo...

CentOS7 は rpm を使用して MySQL 5.7 をインストールするチュートリアル図

1. 4つのrpmパッケージをダウンロードする mysql-コミュニティクライアント-5.7.26-...

lastInfdexOf 関数の MySQL 実装例

MySQL では lastIndexOf に似た関数を使用する必要がある場合もありますが、すぐに使用...

3つの主要データベース(Mysql、SqlServer、Oracle)の違いについて簡単に説明します。

マイグレーションアドバンテージ:小型、高速、総所有コストが低い、オープンソース。複数のオペレーティン...

MySQL ストアド プロシージャの概念、原則、一般的な使用法の詳細な説明

この記事では、例を使用して、MySQL ストアド プロシージャの概念、原則、および一般的な使用法につ...