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 の位置をドラッグして入れ替える例

推薦する

Linux に JDK1.8 をインストールするための詳細なチュートリアル

1. 設置前の清掃 rpm -qa | grep jdk rpm -qa | grep gcj yu...

DockerにJava環境をインストールするための実装手順

この記事は Linux centos8 をベースにして、docker をインストールし、イメージをプ...

IIS7 IIS8 http は自動的に HTTPS にジャンプします (ポート 80 はポート 443 にジャンプします)

IIS7 では、「URL REWRITE2」疑似静的モジュールがインストールされているかどうかを確...

MySQL シリーズ データベース設計 3 つのパラダイム チュートリアルの例

目次1. データベース設計の3つのパラダイムに関する知識の説明1. デザインパラダイムとは何ですか?...

MySQL 8 の新機能: 非表示のインデックス

背景インデックスは諸刃の剣です。クエリ速度は向上しますが、DML 操作も遅くなります。結局のところ、...

MySQLデータの挿入、更新、削除の詳細

目次1. 挿入2. 更新3. 削除1. 挿入 顧客に挿入( 顧客.顧客住所、 顧客.cust_cit...

Dockerパッケージイメージの実装と構成の変更

最近、Docker の学習や実際の運用で多くの問題に遭遇したので、それを記録するためにブログを書きま...

JavaScript 上級プログラミング: 変数とスコープ

目次1. 元の値と参照値2. インスタンス3. 範囲1. 元の値と参照値6 つの単純なデータ型の値は...

Vueは双方向データバインディングを実装します

この記事の例では、双方向データバインディングを実装するためのVueの具体的なコードを参考までに共有し...

Linux の Docker コンテナで bash を終了する 2 つの方法

bash を終了する場合は、次の 2 つのオプションがあります。最初のもの: Ctrl + d を押...

アイデアはDockerプラグインを使用してワンクリックの自動デプロイを実現します

目次環境: 1. Dockerはリモート接続アクセスを可能にするidea dockerプラグインをイ...

Nginx操作応答ヘッダー情報の実装

前提条件: ヘッダー情報操作をサポートするには、ngx_http_headers_module モジ...

React forwardRefの使い方と注意点

これまで react.forwardRef は react の高階コンポーネントには適用できませんで...

React-vscode で jsx 構文を使用する際の問題と解決策

問題の説明プラグインをインストールした後、ES7 React/Redux/GraphQL/React...