序文繰り返し読み取り分離レベルでは、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 を接続する詳細なプロセス
目次1. --skip-grant-tables 経由で取得する1.1 my.conf を変更し、新...
目次使用されるPygame関数スクリーンの作成ヘビの作成ヘビを動かすゲームオーバーの処理食事を増やす...
Nginx によるソケット ポート転送の一般的なシナリオ: オンライン学習アプリケーションでは、通常...
目次1. パノラマII. 背景1. 反応: プロフェッショナル2. ビュー: 凡例3. 技術的な思考...
目次レンダリングAPIの変更レンダリング関数のパラメータレンダリング関数のシグネチャの変更VNode...
成果を達成するまずHTMLを使って基本的なフレームワークを構築します <本文> <...
tar バックアップ システム sudo tar cvpzf backup.tgz --exclud...
コンテナと呼ばれるものは、実際には親イメージに基づいて読み取りおよび書き込み可能なファイル階層を作成...
故障したストレージ ドライブからデータを救出する場合でも、アーカイブをリモート ストレージにバックア...
実際、上記の 3 つの表はいずれも 3 行 3 列です。区切り線を非表示にするコツはルールにあります...
タブバー: 異なるタブをクリックすると異なるコンテンツが表示され、クリックしたタブのスタイルが変更さ...
1. 宇宙のルールHTML コード内の空白は通常、ブラウザによって無視されます。 <p>...
0. リモート開発が必要な理由組み込み Linux を開発する場合、便宜上、通常は Windows ...
IDEA は Java で最も一般的に使用されている開発ツールであり、Docker は最も人気のある...
1. コマンドの紹介ファイル コマンドは、ファイルの種類を識別するために使用されます。ファイル チェ...