MySQLがファントムリードを解決する方法の詳細な説明

MySQLがファントムリードを解決する方法の詳細な説明

1. ファントムリーディングとは何ですか?

トランザクションにおいて、複数のクエリの後に結果セットの数が不一致になる状況をファントム リードと呼びます。

余分な行または欠落した行はファントム行と呼ばれます。

2. なぜファントムリーディングを解決する必要があるのでしょうか?

同時実行性の高いデータベース システムでは、トランザクション間の分離とトランザクション自体の一貫性を確保する必要があります。

3. MySQL はファントム リーディングをどのように解決しますか?

この記事をご覧になった方は、ダーティ リード、非反復リード、反復可能リードについて理解されているものとみなします。

1. マルチバージョン同時実行制御 (MVCC) (スナップショット読み取り)

ほとんどのデータベースはマルチバージョン同時実行制御を実装しており、これを実現するためにデータのスナップショットを保存しています。

InnoDB を例にとると、各行に 2 つの冗長バイトが追加されます。 1 つは行の作成バージョンであり、もう 1 つは行の削除 (期限切れ) バージョンです。バージョン番号はトランザクションごとに増加します。トランザクションがデータを取得するたびに、作成バージョンが現在のトランザクション バージョンより小さいデータと、期限切れバージョンが現在のバージョンより大きいデータが取得されます。

通常の選択はスナップショット読み取りです。

番号が 1 である T から * を選択します。

原則: 履歴データのスナップショットが保存されるため、他のトランザクションによって追加または削除されたデータは現在のトランザクションには表示されません。

2. 次のキーロック(現在の読み取り)

ネクストキーロックは 2 つの部分で構成されています。

  1. レコードロック(行ロック)
  2. ギャップロック

レコード ロックはインデックスに追加されるロックであり、ギャップ ロックはインデックス間に追加されるロックです。 (考えてみてください: 列にインデックスがない場合、どうなるでしょうか?)

更新のために、番号が 1 である T から * を選択します。
select * from T where number = 1 共有モードでロックします。
入れる
アップデート
消去

原則: 現在のデータ行と前のデータ行および次のデータ行の間のギャップをロックして、この範囲内で読み取られたデータの一貫性を確保します。

その他: MySQL InnoDB エンジンの RR 分離レベルはファントム リードを解決しますか? github のコメント アドレスを参照してください:

MySQL によるファントム リードの公式説明は、トランザクションの 2 番目の選択に余分な行がある限り、ファントム リードと見なされるというものです。
トランザクション a が最初に選択し、トランザクション b が挿入します。これにより、ギャップ ロックが追加されます。ただし、トランザクション b がコミットすると、ギャップ ロックが解除されます (その後、トランザクション a は DML 操作を自由に実行できます)。トランザクション a の選択の結果は、MVCC での最初の選択と同じです。次に、トランザクション a は無条件に更新し、この更新はすべての行 (トランザクション b によって新しく追加された行を含む) に適用されます。トランザクション a が再度選択すると、トランザクション b の新しい行が表示され、この新しい行は更新によって変更されています。これは、RR レベルでは確かに当てはまります。

この場合、MySQL の RR レベルではファントム リードを防ぐことはできません。

友人がそのアドレスに返信しました:

スナップショット読み取りの場合、MySQL はファントム読み取りを回避するために mvcc を使用します。
現在の読み取り/読み取り状況では、MySQL はファントム読み取りを回避するために next-key を使用します。
select * from t where a=1; スナップショット読み取りに属する
select * from t where a=1 共有モードでのロック; 現在の読み取りに属します

スナップショット読み取りと現在の読み取りの結果が異なる状況は、ファントム読み取りとは見なされません。これらは 2 つの異なる用途です。したがって、MySQL の rr レベルはファントム リーディングの問題を解決すると思います。

まず結論を述べます。MySQL ストレージ エンジン InnoDB 分離レベル RR はファントム リード問題を解決します。

前回の質問にもありましたが、select後にT1が更新されるとT2に挿入されたデータも一緒に更新されるため、余分な行があると考えられるためファントムリードは防げません。このステートメントは申し分ないように思えますが、実際は間違っています。InnoDB には、スナップショット読み取りと現在の読み取りの 2 つのモードがあります。スナップショット読み取りのみの場合、当然ファントム読み取りの問題はありません。ただし、ステートメントが現在の読み取りに昇格された場合、T1 は選択時に次の構文を使用する必要があります: select * from t for update (lock in share mode) を使用して現在の読み取りに入ると、当然 T2 がデータを挿入できるということはあり得ません。

知らせ
Next-key は確かにファントム リード問題を非常にうまく解決しますが、分離レベルが高くなるほど同時実行性が低くなるという一般的な規則に従います。

上記は、MySQL がファントム リードを解決する方法についての詳細な説明です。お役に立てれば幸いです。ご質問がある場合は、メッセージを残していただければ、すぐに返信いたします。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。

以下もご興味があるかもしれません:
  • MySQL トランザクション機能を使用して同時かつ安全な自動増分 ID を実装する例
  • PHP+MySQL の高同時ロックトランザクション処理問題の解決方法
  • MySQL の繰り返し読み取りレベルでファントム読み取りを解決できますか?
  • MySQL トランザクション同時実行問題の解決
  • MySQL ファントムリードとその排除方法の詳細な説明
  • MySQL シリーズ 10 同時実行制御を実装するための MySQL トランザクション分離
  • MySQL のファントムリード問題を解決する方法
  • mysql+mybatisはストアドプロシージャ+トランザクション+複数同時シリアル番号取得を実装します
  • Mysql トランザクションにおける同時ダーティ リード + 非反復リード + ファントム リードの詳細な説明

<<:  Ubuntu 18.0.4 は mysql をインストールし、エラー 1698 (28000): ユーザー ''root''@''localhost'' のアクセスが拒否されましたを解決します

>>:  JavaScript を使用して div の位置をドラッグして入れ替える例

推薦する

JavaScript はクラス宝くじアプレットを実装します

この記事では、クラス抽選アプレットを実装するためのJavaScriptの具体的なコードを参考までに紹...

Linux でユーザー アカウントをロックおよびロック解除する 3 つの方法

組織内で何らかのパスワード ポリシーがすでに実装されている場合は、この記事を読む必要はありません。た...

自動的にフォーカスを取得する要素入力ボックスの実装

最近のプロジェクトでフォームを作成するときに、コメント ボックスまで自動的にスクロールし、コメント ...

Linux コマンドを使用してオーディオ形式を変換および結合する方法

FFmpeg flacをインストールする eric@ray:~$ sudo apt install ...

MySQLのユーザー権限の確認と管理方法の詳細な説明

この記事では、例を使用して、MySQL ユーザー権限を確認および管理する方法を説明します。ご参考まで...

bodyタグの主な属性の概要

bgcolor="テキストの色" background="背景画像&q...

ネイティブ JS でスネーク ゲームを書く

この記事では、参考までに、JSでスネークゲームを書くための具体的なコードを紹介します。具体的な内容は...

Dockerを使用してElasticsearchクラスターを素早くデプロイする方法

この記事では、 Dockerコンテナ ( docker-composeを使用してオーケストレーション...

XHTML チュートリアル、XHTML の基礎を簡単に紹介します

<br />この記事では、XHTMLとXHTMLの基礎知識について簡単に紹介します。 X...

Centos7 での DNS サーバーの構築の概要

目次1. プロジェクト環境: 2: DNSサーバーの設定i: 前方解析を構成する: ii: 逆解像度...

MySQLフィールドのデフォルト値を設定する方法

目次序文: 1. デフォルト値に関する操作2. 使用上の提案要約:序文: MySQL では、テーブル...

IE8 開発者ツール メニューの説明

<br />この記事では、開発者ツールのさまざまなメニューについて簡単に説明しました。こ...

Navicat は CSV データを MySQL にインポートします

この記事では、Navicatを使用してcsvデータをmysqlにインポートする方法を参考までに紹介し...

Vue+SpringBoot+Shiroのクロスドメイン問題を解決する

目次1. Vueフロントエンドを構成する1. クロスドメイン構成を開発する2. 本番環境のクロスドメ...

テーブルを開く際のMySQLスレッドの問題の解決方法

問題の説明最近、MySQL5.6.21サーバーがありました。アプリケーションがリリースされた後、同時...