序文繰り返し読み取り分離レベルでは、MySQL は他のトランザクションによって送信されたコンテンツを参照できないことがわかっています。コミット可能な分離レベルでは、他のトランザクションがコミットされていることを確認できます。ビジネス シナリオで、トランザクション内の同じ 2 つのクエリで確認する必要があるデータが一貫しており、他のトランザクションの影響を受けないという場合は、繰り返し読み取り分離レベルを使用します。この場合、RR レベルでの通常のクエリ (スナップショット読み取り) は、MVCC に依存して「ファントム読み取り」問題を解決します。「現在の読み取り」状況の場合、「ファントム読み取り」問題を解決するために何に依存する必要がありますか?それがこのブログ投稿の目的です。 これについて説明する前に、前回のブログ記事 (MySQL はトランザクション分離をどのように実装するのか?) を読んでください。この投稿では、主に分離レベルの具体的な技術的詳細が紹介されています。この投稿を読んだ後にこの記事を読むと、より役立つかもしれません。 注: このブログ記事で説明されている「ファントム リード」は、「繰り返し読み取り」分離レベルで実行されるものを指します。 1. ファントムリーディングとは何ですか?次のような構造のテーブルtがあるとします。初期データ行は(0,0,0),(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5)です。 テーブル `t` を作成します ( `id` INT(11) NULLではない、 `key` INT(11) デフォルト NULL, `value` INT(11) デフォルト NULL, 主キー (`id`)、 キー `値` (`値`) )エンジン = InnoDB; tに挿入 値 (0, 0, 0)、 (1、1、1)、 (2、2、2)、 (3、3、3)、 (4、4、4)、 (5、5、5) 更新のために select * from where value=1 を実行し、この行のみをロックし (これは単なる仮定であることに注意してください)、他の行はロックしないと仮定すると、次のシナリオが発生します。 セッション A の 3 つのクエリ Q1 ~ Q3 はすべて、更新のために select * from where value=1 を実行し、value=1 であるすべての行をクエリします。
Q3 が値 = 1 を読み取る現象はファントム リードと呼ばれます。ファントム リードとは、トランザクションが同じ範囲を 2 回クエリすると、後者のクエリでは前のクエリでは表示されなかった行が表示されることを意味します。 まず、「ファントムリーディング」について、次のように説明しましょう。
2. ファントムリーディングの問題点は何ですか?(1)別途解決する必要があるご存知のとおり、select ...for update ステートメントは対応するデータ行をロックします。たとえば、時刻 T1 のセッション A の Q1 クエリ ステートメント: select * from where value=1 for update は、value=1 のデータ行をロックします。ただし、上記のシナリオが発生すると、for update のセマンティクスは破棄されます (value=1 のデータ行はロックされません)。 すべてのレコードがロックされていても、新しいレコードの挿入を防ぐことはできないため、「ファントム リード」の問題は別途解決する必要があります。これは、MVCC または行ロック メカニズムでは解決できません。ここで、もう 1 つのロック機構である「ギャップ ロック」について説明します。 (2)ギャップロックによる並行性ギャップ ロックを導入すると、同じステートメントでより広い範囲がロックされる可能性があり、同時実行性に影響する可能性があります。詳細は下記紹介をご覧ください 3. ファントムリーディングを解決するには?ファントム リードが発生する理由は、行ロックでは行しかロックできませんが、新しいレコードを挿入するアクションによってレコード間の「ギャップ」が更新されるためです。したがって、ファントム リード問題を解決するために、InnoDB はギャップ ロックという新しいロックを導入する必要がありました。 ギャップ: たとえば、テーブルに 0、5、10、15、20、25 の 6 つのレコードを追加します。その結果、7 つのギャップが生じます。 行ごとのスキャン処理中に、行に行ロックが追加されるだけでなく、行の両側のスペースにギャップ ロックも追加されます。これにより、新しいレコードが挿入されなくなります。 ギャップ ロックと行ロックは、まとめてネクスト キー ロックと呼ばれます。各ネクスト キー ロックは、オープン ファースト クローズ インターバル (ギャップ ロック オープン インターバル、ネクスト キー ロック オープン ファースト クローズ インターバル) です。 ギャップ ロック間に競合はありません。競合はギャップにレコードを挿入することです。 テーブル t にはデータ値 = 7 がないため、Q1 はギャップ ロック (1,5) を追加し、Q2 もこのギャップ ロックを追加します。この 2 つは互いに競合せず、どちらもギャップが挿入されるのを防ぎます。 テーブル t が初期化された後、テーブル内のデータが次のようになっていると仮定します。 更新を実行するためにselect * fromを使用すると、テーブル全体のすべてのレコードがロックされ、7つの次のキーロック、すなわち(-∞,0]、(0,2]、(2,4]、(4,6]、(6,8]、(8, 10]、(10、+supremum]が形成されます。 ギャップ ロックを導入すると、同じステートメントでより広い範囲がロックされる可能性があり、同時実行性に影響します。 次のシナリオを想定します。 その後、明らかにデッドロックが発生しました。分析は次のようになります。
前述のように、ギャップ ロックの導入により、同じステートメントでより広い範囲がロックされる可能性があり、これは実際には同時実行性に影響します。 ファントム リード問題を解決するには、読み取りコミット可能分離レベルを使用できます。ギャップ ロックは、繰り返し読み取り分離レベルでのみ有効になります。したがって、分離レベルがコミットされた読み取りに設定されている場合、ギャップ ロックは発生しません。ただし、同時に、データとログ間の不整合の可能性を解決したい場合は、binlog 形式を row に設定する必要があります。つまり、「RC 分離レベル + ログ形式 binlog_format=row」の組み合わせを使用します。 結論
MySQL のファントム リード問題を解決する方法については、これで終わりです。MySQL ファントム リードの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: ネストされた HTML ページの使用例 (フレームセットの使用)
>>: Presto をインストールし、Docker で Hive を接続する詳細なプロセス
requireJS には、baseURL というプロパティがあります。baseURL を設定すること...
この記事では、アコーディオン効果を実現するためのJavaScriptの具体的なコードを参考までに紹介...
昨年末、Thinkpad T450 のデュアルシステムの opensuse を Manjaro に置...
通常、プロジェクト開発では、マージン、位置、座標などを扱う必要があります。悲劇なのは、これらの概念が...
必要:バックグラウンド管理では、次のようなレイアウトでデータを表示する必要があることがよくあります。...
デバッグブランチプロジェクトの通常の開発中に、以前にリリースされたバージョンにバグがある場合がありま...
123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...
序文簡単に言えば、tcpdump は、ネットワーク上のトラフィックをダンプし、ユーザーの定義に従って...
目次1: https証明書を準備する2: nginx sslモジュールを準備する3: SSL証明書を...
MYSQL を使用する場合、トリガーがよく使用されますが、不適切な使用によって問題が発生する場合が...
目次1. ビューフック1. ngAfterViewInit および ngAfterViewCheck...
HTML に触れる初心者は、いくつかの HTML タグを学びます。関連記事:初心者が学ぶ HTML...
目次インデックスモデルB+ツリーインデックスの選択インデックスの最適化インデックスの選択性カバーイン...
MySQL 5.0 は、いくつかの「高度な機能」があるため定番となっています。これは、Windows...
Web には一般的な読み込みアイコンが 2 つあります。1 つは iOS の「菊」、もう 1 つは ...