ホームページ  >  記事  >  データベース  >  MVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。

MVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。

coldplay.xixi
coldplay.xixi転載
2020-09-16 16:37:0643691ブラウズ


MVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。

関連する学習の推奨事項: mysql チュートリアル

MVCC とは

正式名称は Multi-Version Concurrency Control で、マルチバージョン同時実行制御であり、主にデータベースの 同時実行パフォーマンスを向上させるためのものです。 myIsam はトランザクションをサポートしていないため、以下の記事はすべて InnoDB エンジンに関するものです。

同じデータ行に対して読み取りまたは書き込みリクエストが発生すると、そのリクエストは ロックされブロックされます。ただし、mvcc は、読み取り/書き込み要求の処理に優れた方法を使用しているため、読み取り/書き込み要求の競合が発生したときにロックが必要ありません。 この読み取りは、

現在の読み取り

ではなく、スナップショット読み取りを参照します。現在の読み取りはロック操作であり、ペシミスティック ロックです。 では、ロック

を行わずに読み取り/書き込み

をどのように実現するのでしょうか? スナップショット読み取り現在の読み取り とは一体何ですか? に従ってください。思いやりのある兄弟、読み続けてください。

MVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。
現在の読み取りとスナップショットの読み取りとは何ですか?

MySQL InnoDB での現在の読み取りとスナップショットの読み取りとは何ですか?

現在の読み取り値

読み取るデータベース レコードはすべて

現在の最新の

バージョン であり、現在読み取られるデータは Lock# になります## 他のトランザクションがデータを変更するのを防ぎます。 悲観ロックの操作です。 次の操作はすべて現在の読み取りです:

共有モードでロックを選択 (共有ロック)
  • 更新用に選択(排他ロック)
  • update (排他ロック)
  • insert (排他ロック)
  • delete (排他ロック)
  • シリアル化トランザクション分離レベル
  • スナップショット読み取り
スナップショット読み取りの実装は # に基づいています。 # #マルチバージョン

同時実行制御、つまりMVCCはマルチバージョンであるため、スナップショットによって読み取られるデータは必ずしも最新のデータであるとは限らず、以前の

履歴バージョン#のデータである可能性があります。 ##。

次の操作はスナップショット読み取りです: ロックなしの選択操作 (注: トランザクション レベルはシリアル化されません)

スナップショット読み取りと mvcc の関係
  • MVCCC
は、「読み取り操作と書き込み操作が競合しないようにデータの複数のバージョンを維持する」という

抽象概念

です。

この概念には特定の機能を実装する必要があり、この特定の実装は スナップショット読み取りです。 (具体的な実装については後述します)

思いやりのあるお兄さん

の説明を聞いた後、突然トイレが開きました?

#データベース同時実行シナリオ

MVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。
##Read-Read
: 問題ありません。同時実行制御は必要ありません

  • read-write

    : スレッド セーフティの問題があり、トランザクション分離の問題が発生する可能性があり、ダーティ リードやファントム リードが発生する可能性があります。繰り返し不可能な読み取り

  • Write-Write

    : スレッドの安全性の問題があり、最初のタイプの更新損失など、更新損失の問題が発生する可能性があります。 2 番目のタイプの更新損失

  • MVCC はどのような並行性の問題を解決しますか?
  • mvcc が読み取り/書き込み競合を解決するために使用するロックフリー同時実行制御は、 一方向の増加

    タイムスタンプ
  • をトランザクションに割り当てます。データ変更ごとに
バージョン

が保存され、バージョン

はトランザクション タイムスタンプ

に関連付けられます。 読み取り操作 は、このトランザクションの開始 前の データベース スナップショット のみを読み取ります。

この問題は次のように解決されます:

同時読み取り/書き込み時間: 読み取り操作は、同時に、書き込み操作は読み取り操作をブロックしません。

ダーティ読み取り
  • ファントム読み取り

    非反復読み取りおよびその他のトランザクション分離問題を解決しますが、解決できません上記の

    書き込み-書き込み更新が失われる
  • 問題。
  • #したがって、同時実行パフォーマンスを向上させるための次の 組み合わせパンチがあります:

  • # # MVCC 悲観的ロック
: MVCC は読み取り/書き込み競合を解決し、悲観的ロックは書き込み/書き込み競合を解決します

MVCC 楽観的ロック

: MVCC は読み取り/書き込み競合を解決します、オプティミスティックロックは書き込みと書き込みの競合を解決します
  • MVCCの実装原理

    その実装原理は主に
  • バージョンチェーン
  • ,

    アンドゥログです,Read View

バージョン チェーンを実装するには

データベース内のデータの各行は、肉眼で見えるデータに加えて、

隠しフィールドがいくつかあります。それを見るには、天の目を開いてください。それぞれ db_trx_iddb_roll_pointer

db_row_id

です。

db_trx_id

6byte、最新の変更 (変更/挿入)トランザクション ID: レコード作成このレコード/最終変更このレコードのトランザクション ID ## #。

  • db_roll_pointer (バージョン チェーン キー)

    7 バイト、

    ロールバック ポインター、このレコードの を指します 以前のバージョン (ロールバックセグメントに保存)

  • db_row_id
  • 6byte、暗黙的

    自動インクリメント ID

    (隠し主キー)、データテーブルの場合 には主キー がありません。InnoDB は db_row_id に基づいて クラスター化インデックス を自動的に生成します。

  • 実際には、
  • 削除フラグ

    隠しフィールドがあります。レコードが updated または deleted であるという事実は、そうではありません。 、しかし削除フラグ変更

  • MVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。
    ##上記のように、
    db_row_id
    これは、このレコード行に対してデフォルトでデータベースによって生成される

    一意の暗黙的な主キー です。 db_trx_id は、現在の操作の トランザクション ID です。このレコードと db_roll_pointer これは ロールバック ポインタ であり、元に戻すログ と連携するために使用され、以前の 古いバージョン を指します。 。 データベース レコードが変更されるたびに、アンドゥ ログ

    が記録されます。各アンドゥ ログには、

    roll_pointer 属性もあります (INSERT 操作に対応するアンドゥ ログ)レコードに以前のバージョンがないため、この属性はありません)、これらの undo ログは をリンク リスト に接続できるため、現在の状況は次の図のようになります。

    MVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。
    レコードが更新されるたびに、古い値が元に戻すログに配置されます。古いバージョンのレコードであっても、更新の数が増えると、すべてのバージョンが
    roll_pointer
    属性によって

    リンク リスト に接続されます。このリンク リストを バージョン チェーン と呼びます。バージョンチェーンの先頭ノードは、現在のレコードの最新の値です。さらに、各バージョンには、そのバージョンが生成されたときの対応するトランザクション ID も含まれており、この情報は非常に重要であり、ReadView に基づいてバージョンの可視性を判断するときに使用されます。 undo ログ

    Undo ログは主に、データが

    変更される前のログを

    記録するために使用されます

    。テーブル情報が変更される前に、データは 元に戻すログにコピーされます。 トランザクション

    ロールバックされる

    場合、アンドゥ ログのログを通じて データを復元できます Undo ログの目的

    ロールバック
      を実行するときに、
    • トランザクション

      アトミックであることを確認します。パフォーマンスと一貫性 、トランザクションが ロールバックされた場合、元に戻すログ データを使用して 回復できます。 MVCC マルチバージョン管理で、undo log

      データの
    • 履歴バージョンを読み取ることにより、MVCC
    • スナップショット読み取り

      データに使用されます。 異なるトランザクション バージョン番号 には、独自の 独立したスナップショット データ バージョン があることがわかります。 undo ログは主に 2 つのタイプに分類されます。

    insert undo log は、トランザクション内の新しいレコードの挿入時に生成される UNDO ログは、トランザクションがロールバックされる場合にのみ必要であり、トランザクションがコミットされた直後に破棄できます。

    • Update Undo log (main)

      トランザクションが更新または削除されるときに生成される元に戻すログ。トランザクションがロールバックされるときだけでなく、スナップショットが読み取られるときにも必要です。

    • したがって、気軽に削除することはできません。高速読み取りまたはトランザクション ロールバックがこのログに関係しない場合にのみ使用されます。この場合、対応するログはパージ スレッドによって一律にクリアされます。
    • Read View (読み取りビュー)

      トランザクションが

      snapshot read
    • 操作を実行するときに生成されます。
    Read View

    (読み取りビュー)、トランザクション実行スナップショットが読み取られる瞬間、

    snapshot

    現在のデータベース システムのファイルが生成されます。 アクティブなトランザクションのシステムの現在の ID を記録して維持します(コミットしない場合、各トランザクションが開始されると ID が割り当てられます。この ID は増加するため、トランザクションが新しいほど、 ID 値が大きいほど、システム内の このトランザクション が現在認識すべきではない他のトランザクション ID

    のリストになります。

    Read View は主に visibility を判断するために使用されます。つまり、特定のトランザクションsnapshot read

    を実行するときに、レコードを作成して、 Read View 読み取りビュー。それを条件と比較して、現在のトランザクション

    が参照できる データのバージョンを 決定します。これは、現在の 最新 データである場合もあります。この行に記録されている元に戻すログ内の特定のバージョン読み取り いくつかのプロパティを表示しますtrx_ids

    : 現在のシステムはアクティブです (

    Uncommitted)トランザクションのバージョン番号のコレクション。

    • low_limit_id: 現在の読み取りビューを作成するときの「現在のシステム 最大トランザクション バージョン番号 1」。

    • up_limit_id: 現在の読み取りビューの作成時、「システムはアクティブなトランザクション 最小バージョン番号中です」

    • creator_trx_id: 現在の読み取りビューのトランザクション バージョン番号を作成します;

    読み取りビューの可視性判定条件

    • db_trx_id < up_limit_id || db_trx_id == creator_trx_id(表示)

      データ トランザクション ID が読み取りビューの 最小アクティブ トランザクション ID より小さい場合、データ の前に存在することを確認できます。現在のトランザクションが開始されているため、 を表示できます。 または、データの トランザクション ID

      creator_trx_id と等しい場合、このデータは現在のトランザクション によって生成されたことを意味します。もちろん、自分で生成したデータを参照することもできるので、この場合、このデータを 表示することもできます。

    • db_trx_id
    • >=

      low_limit_id (表示されません) データ トランザクション ID が現在のシステムより大きい場合読み取りビューの 最大トランザクション ID

      は、現在の読み取りビューが作成された

      後にデータが生成されたことを意味するため、データ を表示しません。未満の場合は、次の判定を入力します。 #db_trx_id

      is in
    • activetransaction
    • (trx_ids)

      ## が存在しません: 読み取りビューの生成時にトランザクション

      がコミットされたことを意味します。この場合、データは
        表示できます
      • Exists: これは、読み取りビューが生成されたとき、トランザクションはまだアクティブで、まだコミットされていないことを意味します。変更したデータは、次の方法でも表示されます。現在の取引がありません。

      MVCC とトランザクション分離レベル
    上記の内容
    Read ViewMVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。 は、
    RC
    (コミットされた読み取り、送信の読み取り) および
    RR

    (反復可能な読み取り、反復可能な読み取り) をサポートするために使用されます。 ##。

    RR および RC 生成のタイミング#RC分離レベルでは、すべての スナップショット読み取り になります。生成され、最新の

    Read View

    ;

    • を取得し、RR 分離レベルで、同じ にあります。トランザクション 最初のスナップショット読み取りRead View を作成し、

      その後のスナップショット読み取りは
    • 同じ読み取りビュー
    • を取得し、後続のクエリが実行されます。

      を繰り返し生成しないため、トランザクションのクエリ結果は 毎回同じ になります。 ファントム読み取り問題の解決策スナップショット読み取り: MVCC を通じて制御され、ロックは必要ありません。ファントムリードを避けるため、MVCCで規定された「文法」に従って追加、削除、変更、検索などの操作を行ってください。

    • 現在の読書内容
    : この問題は、ネクストキー ロック (行ロック ギャップ ロック) によって解決されます。

    • RC レベルと RR レベルでの InnoDB スナップショット読み取りの違い

      RR レベルでのトランザクションによる特定のレコードの最初の読み取り2 番目のスナップショット読み取りでは、現在のシステム内の他のアクティブなトランザクションを記録するためのスナップショットと読み取りビューが作成されます。その後、スナップショット読み取りを呼び出すと、現在のトランザクションが他のトランザクションの前に使用される限り、同じ読み取りビューが引き続き使用されます。更新を送信してスナップショットを読み取り、その後の後続のスナップショット読み取りでは同じ読み取りビューが使用されるため、後続の変更は表示されません;
    • つまり、RR レベルで、スナップショット読み取りによって読み取りビューが生成されるとき, 読み取りビューは、この時点で他のすべてのアクティブなトランザクションのスナップショットを記録します。これらのトランザクションの変更は現在のトランザクションには表示されません。読み取りビューより前に作成されたトランザクションによって行われた変更は表示されます

    #そして、RC レベルでは、トランザクション内の各スナップショット読み取りによって新しいスナップショットと読み取りビューが生成されます。トランザクション内の他のトランザクションによって送信された更新を RC レベルで確認できます

    • 概要

      上記の説明からわかるように、いわゆる MVCC は、
    • READ COMMITTD
    • および

      REPEATABLE READ

      トランザクションを使用して、通常の
    • SEELCT
    • 操作を実行するときにレコードにアクセスします。 #バージョン チェーンのプロセス

      このように、 ##異なるトランザクションの #read-write

    • write-read
    操作

    を同時に実行できるため、

    システム パフォーマンスが向上します

    プログラミング学習について詳しく知りたい方は、php training のコラムに注目してください!

    以上がMVCC はネットワーク全体で最も完全なデータベースです。説明の不完全性については私が責任を負います。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。