目次
本題に入る前に、まず行フォーマットとは何かを一般的に理解すると、次の MVCC を理解するのに役立ちます。行フォーマットは、テーブル内の行レコードがディスクに保存される方法です。Innodb ストレージ エンジンには、合計 4 つの異なるタイプの行フォーマットがあります:
ホームページ データベース mysql チュートリアル MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事

MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事

Feb 06, 2023 pm 08:14 PM
mysql java

MySQL はファントム リードの問題をどのように解決しますか?この問題については次の記事で解説していますので、疑問を持ちながら記事を読んでみましょう!

MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事

## ジン・ブサンとイン・ブシの頻繁なインタビュー質問の中で、MySQL のトランザクション特性、分離レベル、その他の問題も、非常に古典的な 8 部構成のエッセイの 1 つです。この種の質問に直面すると、ほとんどの友人はこれに精通していると推定されます:

トランザクション特性 (ACID): Atomicity (Atomicity##) #)、分離(分離)、一貫性(一貫性)および永続性

分離レベル

: READ UNCOMMITTED(READ UNCOMMITTED), READ COMMITTED(READ COMMITTED), Repeatable Read (REPEATABLE READ)、 Serializable (SERIALIZABLE) そして、それぞれの種類の分離 レベルによって引き起こされる問題は次のとおりです。 :

    READ UNCOMMITTED
  • 分離レベルでは、ダーティ読み取り非反復読み取りおよび##が発生する可能性があります。 #phantom readproblemREAD COMMITTED
  • 分離レベルでは、
  • non-repeatable read および phantom read の問題が発生する可能性がありますが、これらは問題です。不可能です ダーティ リード問題REPEATABLE READ
  • 分離レベルでは、
  • ファントム リード問題が発生する可能性がありますが、ダーティ リード#は発生しません## および Non-repeatable read問題SERIALIZABLE分離レベルでは、さまざまな問題は発生しません
  • MySQL InnoDB の場合ストレージ エンジンでサポートされるデフォルトの分離レベルは REPEATABLE-READ (反復可能)
  • です。上記の SQL 標準の 4 つの分離レベルの定義から、
REPEATABLE-READ (反復可能)

となります。 ファントム リード を防ぐことは不可能ですが、MySQL InnoDB ストレージ エンジンがファントム リードの問題を解決することは誰もが知っています。では、どのようにしてそれを解決するのでしょうか? 1. 行フォーマット

本題に入る前に、まず行フォーマットとは何かを一般的に理解すると、次の MVCC を理解するのに役立ちます。行フォーマットは、テーブル内の行レコードがディスクに保存される方法です。Innodb ストレージ エンジンには、合計 4 つの異なるタイプの行フォーマットがあります:

compact

redundant , dynamic , compress; 行フォーマットには多くの種類がありますが、原理的には基本的に同じで、次のように、 compact 行フォーマット: As図からわかるように、完全なレコードは実際には 2 つの部分に分けることができます: 記録された追加情報 記録された実際のデータ MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事. 記録された追加情報 はそれぞれ changes. 長いフィールド長リスト NULL 値リスト および レコード ヘッダー情報 、および 記録された実際のデータ 独自に定義した列に加えて、 MySQL は、各レコードにいくつかのデフォルトの列を追加します。これらのデフォルトの列は、隠し列とも呼ばれます。特定の列は次のとおりです:

列名Lengthrow_id6 バイト 6 バイトを識別します7 バイト
Description
一意の行 ID 1 つの Record transaction_id
トランザクション ID roll_pointer
ロールバック ポインタ

非表示列の値について心配する必要はありません。 InnoDB ストレージ エンジンがそれを生成します。さらに詳細に描画しましょう。 compact行形式は次のとおりです:

MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事

  • transaction_id: トランザクション ID トランザクションが行レコードを変更すると、このトランザクションのトランザクション ID がこの列に割り当てられます。
  • ##roll_pointer: 行が変更されるたびにレコードが変更されると、古いバージョンのデータが undolog ログに書き込まれます。
  • 続いて、roll_pointerundolog を指します。 なので、この列はポインターに相当し、これを介して「前の情報の変更」

#2. MVCC の詳細な説明

# を見つけることができます。 #2.1 バージョン チェーン

次のようなレコードがあるとします。

レコードに挿入された

トランザクション IDMySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事80 であり、roll_pointer ポインタは NULL です (理解を容易にするため、読者はポインタが NULL であることを理解できます。実際は roll_pointer 最初のビットは、それが指す Undo ログのタイプをマークします。このビットの値が 1 の場合、それは意味します。これが指す undo ログ タイプが insert undo であることを示します)次の 2 つを仮定します

トランザクション ID

100200 のトランザクションがそれぞれ実行されますこのレコードに対する UPDATE 操作: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'> -- 事务id=100 update person set grade =20 where id =1; update person set grade =40 where id =1; -- 事务id=200 update person set grade =70 where id =1;</pre><div class="contentsignin">ログイン後にコピー</div></div> レコードが変更されるたびに、

元に戻すログ

が記録されます。各 元に戻すログ roll_pointer 属性 (操作に対応する INSERT) もあり、レコードには以前のバージョンがないため、##undo log にはこの属性がありません)、次のようにすることができます。これらの undo log をリンク リストに接続すると、現在の状況は下の図のようになります。 同じ: レコードが更新されるたびに、古い値が配置されます

undo ログ

、古いバージョンのレコードであっても、更新の数が増えると、すべてのバージョンが MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事roll_pointer 属性によってリンク リストに接続されます。このリンク リストを バージョン チェーン と呼びます。バージョン チェーンのヘッド ノードは、現在のレコードの最新の値です。さらに、各バージョンには、対応する transaction id#2.2 ReadView

# データベースの 4 つの分離レベル: 1) read uncommitted

; 2)

read committed; 3) REPEATABLE READ; 4)SERIALIZABLE; たとえば、READ UNCOMMITTED 、毎回バージョン チェーンの最新データを読み取るだけです; SERIALIZABLE、主にロックによって制御されます; read commitREPEATABLE READ これらはすべて、これら 2 つの分離レベルでは、バージョン チェーン内のどのものが現在のものに表示されるかが中心的な問題になります。この問題を解決するために、MySQL は読み取りビューの概念を提案しました。これには 4 つの中核的な概念が含まれています。 m_ids

:
    read view
  • を生成するとき、アクティブなモノ ID コレクション min_trx_id:# # の最小値#m_ids
  • 、つまり、読み取りビューを生成するときのアクティブなものの最小値
  • max_trx_id: 読み取りビュー
  • を生成するときに、システムが次のモノの ID 値
  • creator_trx_id を割り当てる必要があります。これは、read view
  • を作成するモノの ID (現在のモノの ID) です。
  • このReadViewを使用すると、レコードにアクセスするときに、次の手順に従うだけで、レコードの特定のバージョンが表示されているかどうかを確認できます。
記録されたモノの ID が

creator_trx_id と等しい場合、現在のモノが変更したレコードにアクセスしていることを意味するため、このバージョンは表示されますMySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事アクセスされたバージョンの場合Thing ID が

min_trx_id
    より小さい場合、
  • read view が作成されたときに Thing が送信され、このバージョンが現在の Thing に読み取り可能であることを意味します
  • Ifアクセスされたモノのバージョン ID が
  • max_trx_id 以上の場合、read view が作成されるときに、バージョン レコードを生成するモノ ID が開かれていないことを意味しますRead view
  • が生成されるまで、このバージョンは現在の Thing
  • で読み取ることができません。アクセスされたバージョンの Thing transaction_idm_ids# にある場合、 ## コレクションの場合、Read view が生成された時刻、トランザクションがまだアクティブで送信されていない場合、バージョンにアクセスできないことを意味します。そうでない場合は、バージョンを生成したトランザクションを意味します。
  • ReadView
  • は作成され、送信され、アクセスできます 注: 読み取り用の ID は 0 です

    MySQL では、READ COMMITTEDREPEATABLE READ 分離レベルの大きな違いは、異なるタイミングで ReadView を生成することです。

    • READ COMMITTED —— ReadView
    • REPEATABLE READ を生成します —— 毎回データを読み取る前に、データを 1 回読み取るときに、 ReadView
    が生成されます。詳細な例を使用して 2 つの違いを説明しましょう:

    Timenumbertrx 100trx 200①BEGIN; #②③④SELECT * FROM person WHERE id = 1;##個人セットのグレード =70 (ID =1) を更新します。SELECT * FROM person WHERE id = 1;コミット;コミット;trx 100時間⑥では、トランザクション trx 200




    BEGIN;
    BEGIN;

    個人セットのグレード =20 (ID = 1) を更新します;

    ##個人セットのグレード =40 (ID =1) を更新します;



    ##コミット;




    9


    ?

    ##時刻④では、トランザクション
    によりトランザクションが送信され、id=1 行に記録されているバージョン チェーンは次のようになります。
    により、トランザクションのコミットが実行され、バージョン チェーンが id=1 行に記録されます。 次のように:

    時間 ⑤ では、トランザクション MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事trx 100 は、select

    ステートメントの実行時に最初に

    ReadView## を生成します。 MySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事ReadView

    m_ids リストの [100, 200]min_trx_id100 max_trx_id201creator_trx_id0 です。この時点では、バージョン チェーンから表示されているレコードを選択し、バージョン チェーンを上から下までたどります。下: Grade=40 であるため、trx_id の値は m_ids にある 100 であるため、レコードは表示されません。 =20も見えません。引き続き下に移動し、グレード = 20、trx_id 値は 80 であり、ReadViewmin_trx_id100# よりも小さいです。 ## したがって、このバージョンは要件を満たしており、レベル 10 のレコードがユーザーに返されます。 時間 ⑧ で、トランザクションの分離レベルが READ COMMITTED の場合、別の ReadView (ReadView# の ##) が生成されます。 m_ids リストの内容は [200]

    min_trx_id200max_trx_id 201 , creator_trx_id0 です。このとき、バージョン チェーンから表示されているレコードを選択すると、バージョン チェーンが上から下にたどられます: Grade=70 であるため、 trx_id の値は m_ids200 であるため、レコードは表示されません。トラバースを続けます。grade=40、trx_id値は 100 です。これは ReadViewmin_trx_id200 より小さいため、このバージョンは要件を満たしており、レコードは次のようになります。レベル 40 がユーザーに返されます。 時間 ⑧ で、トランザクションの分離レベルが REPEATABLE READ である場合、時間 8 で、ReadView は個別に生成されず、時間ごとに生成されます。 ReadView では 5 が使用されるため、ユーザーに返されるレベルは 10 です。 2 つの選択の結果は同じです。これが 繰り返し読み取り の意味です。

    3. 概要 MVCC の詳細な説明を分析すると、MVCC に基づいて、RR 分離レベルの下で、非常に簡単に解決できると結論付けることができます。 ファントム読み取り問題ですが、select for update が現在の読み取りを生成し、スナップショット読み取りではなくなっていることがわかっています。この場合、MySQL は ファントム読み取り

    をどのように解決しますか?問題?時間の問題 (整理して図を描くにはかなりの時間がかかります) に基づいて、最初に結論を述べてから、現在の読み取り状況で MySQL が

    ファントム読み取り 問題をどのように解決するかを分析します。

    現在の読み取り値: Next-Key Lock (ギャップ ロック) を使用して、ファントム読み取りが発生しないようにロックします。ギャップ ロックの使用方法現在の読書状況 ファントム リーディングの問題を解決したい場合は、興味のある友人がフォローといいねを追加してください [関連する推奨事項: mysql ビデオ チュートリアル

    ]

    以上がMySQL がファントム読み取り問題をどのように解決するかを簡単に分析した記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

    中国語版、とても使いやすい

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)

    MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 Dec 09, 2024 am 11:42 AM

    MySQL 8.4 (2024 年時点の最新の LTS リリース) で導入された主な変更の 1 つは、「MySQL Native Password」プラグインがデフォルトで有効ではなくなったことです。さらに、MySQL 9.0 ではこのプラグインが完全に削除されています。 この変更は PHP および他のアプリに影響します

    Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

    Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

    Java をシンプルに: プログラミング能力を高める初心者向けガイド Java をシンプルに: プログラミング能力を高める初心者向けガイド Oct 11, 2024 pm 06:30 PM

    Java をシンプルに: プログラミング能力の初心者向けガイド はじめに Java は、モバイル アプリケーションからエンタープライズ レベルのシステムに至るまで、あらゆるもので使用される強力なプログラミング言語です。初心者にとって、Java の構文はシンプルで理解しやすいため、プログラミングの学習に最適です。基本構文 Java は、クラスベースのオブジェクト指向プログラミング パラダイムを使用します。クラスは、関連するデータと動作をまとめて編成するテンプレートです。簡単な Java クラスの例を次に示します。 publicclassperson{privateStringname;privateintage;

    未来を創る: まったくの初心者のための Java プログラミング 未来を創る: まったくの初心者のための Java プログラミング Oct 13, 2024 pm 01:32 PM

    Java は、初心者と経験豊富な開発者の両方が学習できる人気のあるプログラミング言語です。このチュートリアルは基本的な概念から始まり、高度なトピックに進みます。 Java Development Kit をインストールしたら、簡単な「Hello, World!」プログラムを作成してプログラミングを練習できます。コードを理解したら、コマンド プロンプトを使用してプログラムをコンパイルして実行すると、コンソールに「Hello, World!」と出力されます。 Java の学習はプログラミングの旅の始まりであり、習熟が深まるにつれて、より複雑なアプリケーションを作成できるようになります。

    カプセルの量を見つけるためのJavaプログラム カプセルの量を見つけるためのJavaプログラム Feb 07, 2025 am 11:37 AM

    カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4

    Spring Tool Suiteで最初のSpring Bootアプリケーションを実行するにはどうすればよいですか? Spring Tool Suiteで最初のSpring Bootアプリケーションを実行するにはどうすればよいですか? Feb 07, 2025 pm 12:11 PM

    Spring Bootは、Java開発に革命をもたらす堅牢でスケーラブルな、生産対応のJavaアプリケーションの作成を簡素化します。 スプリングエコシステムに固有の「構成に関する慣習」アプローチは、手動のセットアップを最小化します。

    スタックの下部に要素を挿入するJavaプログラム スタックの下部に要素を挿入するJavaプログラム Feb 07, 2025 am 11:59 AM

    スタックは、LIFO(最後の、最初のアウト)の原則に従うデータ構造です。言い換えれば、スタックに最後に追加する要素は、削除される最初の要素です。要素をスタックに追加(またはプッシュ)すると、それらは上に配置されます。つまり、とりわけ

    Intellijで最初のスプリングブートアプリケーションを実行する方法は? Intellijで最初のスプリングブートアプリケーションを実行する方法は? Feb 07, 2025 am 11:40 AM

    Intellijのアイデアは、Spring Boot開発を簡素化し、Java開発者の間でお気に入りになります。 その慣習と構成アプローチは、ボイラープレートコードを最小限に抑え、開発者がビジネスロジックに集中できるようにします。このチュートリアルでは、2つのメトーを示しています

    See all articles