45 MySQLの戦闘ストレス研究ノート:最後のトランザクションは、単離または単離されていないが?(講義8)

まず、今日の内容の要約

私はTが変更からも、他のトランザクション場合実行トランザクションの後、期間を最初の3件の記事で述べたように、そしてそれが反復可能読み取り分離レベルである場合、ビューの読み取りビューを作成するときに、トランザクションTが開始する、前時にトランザクション分離レベルをあなたに伝えます多くの
データ、トランザクションTは、起動時に見たい見続けています。つまり、分離レベルで行われ、反復読み取りトランザクションでは、外部からの影響から自由な、超然と思われます。

あなたが行ロックを共有している場合しかし、私の前回の記事では、また、トランザクションは、あなたが行は、この行をロックしている別のトランザクションを持って起こる場合、それはそう孤高ことができない、行を更新すると、ロックされることを述べましたライブ、待機状態に入ります。尋ねた
質問では、それはそれが何であるかの値を読み取ったときに、自分のデータを更新するために、行ロックを取得するために、このトランザクションまで待機状態に入っているので、ですか?

私はあなたにそれの例を挙げてみましょう。次は、テーブルの2行のみを初期化するための文です。

MySQLの>表'T'(CREATE 
  `id`はint(11)NOT NULL、
  'K'はint(11)は、デフォルトのNULL、
  PRIMARY KEY(` id`)
)ENGINE = InnoDBテーブルと、
T(ID、K)の値(1,1)、(2,2)に挿入します。

1つのトランザクションA、B、Cの実行フロー

ここでは、トランザクションを開始するタイミングに注意する必要があります。

開始/ transactionコマンドを起動し、トランザクションが実際に開始し、その文の後の最初の動作のInnoDBテーブルの実装では、トランザクションの開始ではありません。あなたはすぐにトランザクションを開始したい場合は、[スタート]を使用することができ
、この順序と一致し、トランザクションのスナップショットを。

;文を読んで、スナップショットの最初の実装時に最初に起動モードは、一貫性のあるビューが作成された
第2のスタートアップモードは、一貫性のあるビューがconsistentsnapshot作成したときに開始トランザクションを実行しています。

また、列全体の内部、特に指定のない限り、私たちの例では、デフォルトの自動コミット= 1であることに注意してください。

この場合、Cは、明示的に自分自身で表し、開始/コミットを使用していないトランザクションは、この更新ステートメントは、ステートメントの完了時間の取引が自動的に提出される予定です。クエリの行を更新した後、トランザクションB、読取り専用トランザクションAで

トランザクションのクエリ、そしてそれは、クエリのトランザクションB.後に時系列であります
私はあなたを伝える場合は、この時点では、トランザクションがk個のBで3、及びkトランザクションAの値の値に記載されていていることが1で発見され、あなたはそれ少しめまいを感じていないですか?

そこで、この記事では、今日、私は実際にちょうど問題を理解したいとあなたが言う、このプロセスでは、トランザクションにロックを助けるとのInnoDBのより良い理解を持つことができます混乱を解明することを期待しています。

MySQLでは、の「ビュー」の2つの概念があります。

一つは、図です。これは、呼び出しの時点でクエリを実行し、結果を生成し、仮想テーブルの定義とクエリです。ビューの構文を作成すると、ビューを作成...であり、そのクエリメソッドとテーブル。
MVCC読取り一貫性ビューその読取り一貫性ビューを実装する場合、別のInnoDBは、RC(コミット読み、提出を読み)とRR(反復可能読み取り、反復可能読み取り)分離レベルの実装をサポートするために、使用されています。

それは役割を定義するために使用され、物理的な構造ではないトランザクション中に「私は何のデータを見ることができます」。

第三の記事では、「トランザクションの分離は:なぜ私は、あなたが変更を見ることができませんか?「私はあなたと再びMVCC実装ロジックを説明しました。今日のクエリと更新の間の違いを説明するために、私は読み取りビュースプリット説明する方法に変更
オープン。あなたはMVCCのより深い理解を示すために、これら二つの記事を組み合わせることができます。

第二に、それがどのように動作するかにMVCCに「スナップショット」?

ブート時に反復可能読み取り分離レベルのトランザクションでは、「スナップショットを取る。」します これはライブラリ全体のスナップショットに基づいていることに注意してください。

この時点で、あなたはそれが現実的なああを見ていないと言うでしょう。ライブラリは100Gを持っている場合、私はトランザクションを開始し、MySQLは、プロセスがはるかにマナである、100Gの外にデータをコピーします。しかし、私は通常、ああすぐに取引を実行します。

実際には、我々はこの100Gのデータをコピーする必要はありません。このスナップショットを達成する方法であるATのは、見てみましょう。各トランザクションは、一意のトランザクションIDを持っているInnoDBは、トランザクションIDと呼ばれます。これは、トランザクションの開始時で
のInnoDBトランザクションシステムアプリケーションに待っていると、アプリケーションは、厳密に順序を増やす基づいています。

図1に示すように、テーブル内のデータの行は、実際には、複数のバージョン(行)の行があってもよいtrx_id

そして、データの各列は、複数のバージョンです。これらはデータの新しいバージョンを生成する各トランザクション更新データ、およびデータトランザクションIDのこのバージョンに割り当てられたトランザクションIDは、行trx_idと呼びます。一方、古い
データのバージョンが保持されると、データの新しいバージョンでは、情報が直接それを得ることができるかもしれません。

換言すれば、テーブル内のデータの行は、実際には、各バージョンは独自rowtrx_idを有し、複数のバージョン(行)があってもよいです。

図2に示すように、トランザクション・レコードの複数後に連続的に更新された状態です。

図2図2行ステータス変更

図中の破線のボックスは、データの同じ行の4つのバージョン、最新バージョンはV4であるkの値は22であり、それはトランザクションの更新のための25のトランザクションIDであるので、行が25 trx_idもです。

1、それはどこにログ元に戻しますか?

あなたはやる(ログをロールバック)前の記事、更新文は、アンドゥログを生成することを言っていない、求めることができますか?だから、それはアンドゥログを使用しますか?

実際、図2三の破線矢印、アンドゥログであり、V1は、V2、V3は、物理的な現実には存在しないが、各時間は、現在およびアンドゥログの必要なバージョンに基づいて算出。V2とする必要がある場合、例えば、
指名は、V4を介して実装U3続いて、U2は、アウトカウント。

マルチバージョンの概念を理解し、trx_id行、私たちはInnoDBは「100G」の定義がどのようにスナップショットがある、について考えてみましょう。

トランザクションが開始されたときに反復可能読み取りの定義によると、あなたが提出されているすべてのトランザクションの結果を見ることができます。しかし、その後、このトランザクションの実行中に、それが表示されていないその他の事項を更新します。

このように、文をブートするときにのみ必要とされるトランザクションが言いました、

私が開始する前に、データのバージョンが発生した場合1、私は勝つために開始した瞬間、あなたは知っています。

私が始まった後にのみ発生した場合は2、私はそれのバージョンを見つける必要があり、知りません。」

「以前のバージョン」は表示されていない場合はもちろん、それは楽しみにしておく必要があります。また、トランザクションは、独自のデータを更新する、または独自のを認識することである場合。

2、活性が指しますか?

実現には、InnoDBはトランザクション、現在「アクティブ」全ての事項のIDを開始する瞬間を保持するために、アレイの各トランザクションのために構築しました。「アクティブ」とは、まだ提出を開始していません。

低レベルの配列、トランザクションIDプラス高い水レベルという最大値を使用して作成された現在のシステムと呼ばれる最小のトランザクションID。

このビューアレイと高い水は、それらが時事(読み取りビュー)の一貫性のあるビューを形成します。

データ可視性規則のバージョンは、この行trx_id、得られたデータの一貫したビューの結果を比較することに基づいています。

図2は、現在のトランザクション数にモーメント開始するため、データ列のバージョンが可能いくつか存在することtrx_id?

このビューは、すべての行trx_idアレイいくつかの異なる状況に分けます。

データ可視性規則の3バージョン

このように、現在のトランザクション、データ列trx_idのバージョンを開始する瞬間のために、いくつかの可能性があります。

1.あなたが緑の部分に落下した場合、現在のバージョンは、自己生成コミットされたトランザクションまたは取引され、このデータが表示されていることを示しています。

2.赤い部分は、低下確かに表示されていない、このバージョンは、将来のトランザクションの開始によって生成されることを示している場合、
それは、2つのケースを含み、前記黄色部分が下がると

アレイ内の行trx_id Aはバージョンが不可視提出トランザクションによって生成されない表す場合;。 既にトランザクションを提出しているバージョンを示す、B列trx_idない配列であれば可視発生。

例えば、図2のデータは、低水位18でトランザクションを、存在する場合、それはデータにアクセスするとき、V4 V3を介してU3から計算され、この行それはそうので、このライン値は11です。

この文、単にトランザクションはそれの内容とは無関係の見られない、続いた更新システムで、参照してください?更新後、生成されたバージョンは、上記のケース2または図3(a)に属している必要があり、それがあること、であるため、
データのいくつかの新しいバージョンが存在していないので、このトランザクションのスナップショットは、の「静的」であります。

だから今、あなたが知っている、ののInnoDB使用この機能の、の「スナップショットを作成するために、第2級」を達成する能力は、「すべてのデータは、複数のバージョンを持っています」。

3.取引の結果が返さステートメント、なぜK = 1である(人間の肉分析は

次に、私たちはなぜ、K = 1である、図では1 3つのトランザクション、トランザクション分析リターンの文を見続けています。

1、人間の肉の分析

ここでは、以下の仮定をしたいです:

1.取引開始前に、唯一のアクティブなシステムがトランザクションID 99である;
2.サービスA、B、C 100、101、バージョン番号と現在のシステム、4つのだけのトランザクションである。
3.スリートランザクションの開始前に、(1,1)の行は、このデータの行が90であるtrx_id。

したがって、ビュートランザクションアレイAが[99100]であり、トランザクションB [99100101]の配列を示す図であり、Cは、トランザクションの配列[99100101102]の図です。

分析を単純化するために、私は最初だけトランザクションとに関連するクエリの論理演算を描画するために、他の干渉文を削除します。

 図4クエリデータトランザクション論理図

図からわかるように、最初のトランザクションが有効な更新C、(1,1)からのデータを(1,2)にあります。このとき、データ列trx_idの最新バージョンは102であり、そして90は、このバージョンは過去のバージョンとなっています。

第2のトランザクションは有効な更新データ(2)から(1,3)へのB、です。102は過去のバージョンになっているが、この時点で、データの最新バージョン(すなわち、行trx_id)は、101です。

あなたは、トランザクションが、クエリ、実際には、トランザクションBが提出されていない場合、ことに気づいたかもしれませんが、それはこのバージョンでは、現在のバージョンとなっています(1,3)を生成します。しかし、トランザクションAのこのバージョンでは、それ以外の場合は、ダーティリードとなり、見えてはいけません。
さて、今私は、データトランザクションAを読んでもらいたい、そして配列のそのビューは[99、100]です。もちろん、データを読み込むことは果たした現在のバージョンから読み込まれます。したがって、トランザクションがデータ読み出し処理のクエリは、このようなものです:

  1. それは、その行trx_id = 101、高及び大水位を判定された場合に見出され(1,3)は、赤色の領域は表示されません。
  2. 次に、行trx_id = 102、高及び大水位を参照して、過去のバージョンを見つけ、赤い領域が表示されていません。
  3. そして、その行trx_id = 90、低水位よりも低い、グリーンゾーンで、目に見える、最後に見つかった、検索するためのフォワード(1,1)を移動

このような期間のデータが変更されているが、ラインの下の実行、が、トランザクション任意の時点でのクエリは、データのこの行の結果を確認することは同じですので、我々は一貫性が読ん呼び出します。

4、結果は、トランザクションステートメントを返さ、なぜK = 1(コード・ロジック分析)

この判定ルールは以上のコード・ロジックからの直接の翻訳ですが、あなたが見ることができるように、人間の肉用可視性分析は非常に面倒です。
だから、私はあなたが翻訳しあげます。トランザクションのデータのバージョンは、独自のアップデートに加えて、それを見る常に表示され、3例があります。

1.コミットされていないバージョン、目に見えない;
2.バージョンは見えなく、提出されましたが、ビューが作成された後に提出されました。
3.バージョンが送信されました、と創造の正面に提出され、目に見えます。

場合トランザクションが開始今、我々は、図4のクエリ結果を決定するために規則を使用クエリトランザクションAの配列を表示し、このときに生成されます。

(3)ケース1に属さないの提出は、表示されていない、
(2)著者が、しかしビューは、アレイを作成した後に送信され、2例であり、表示されていない、
(1,1)の図でありますアレイの作成前に提出され、目に見えます。

あなたが見る、デジタルコントラスト、決定するだけで、時系列順を削除した後、それははるかに簡単ではありません分析します。そこで、我々は後に、このルールの使用を分析する必要があります。

第三に、更新ロジック

注意深い学生は疑問を持っていることがあります。一貫性に合わせて読めば、UPDATE文のトランザクションBが、結果が間違ってああそうですか?

1、トランザクションBの更新ステートメントは、(現在の読み込み)に対処する方法でしょうか?

図5は、トランザクションBの配列を表示(1,2)氏チェンのある、トランザクションが提出された後にC、目に見えないべきではありませんが、どのように(1,3)を計算することができますか?

 図5、図更新論理トランザクションB

トランザクションBは、更新前のデータを照会する場合は、[はい、このクエリは、kの値が実際に1返します。

それは、データを更新するために行く時間だときには、あなたは歴史の中でバージョンを更新、またはCが失われたトランザクションを更新することはできません。したがって、この場合のBセットK = K + 1におけるトランザクションは、(1,2)に基づいて行う操作でオン。

だから、ここでは、そのようなルールで使用されている:更新されたデータは、最初の読み取りで書かれており、この読書、唯一の現在の値を読んで、「現在の読書」(現在の読み込み)と呼ばれます。

、(1,3)後成的データの新しい更新されたバージョンになった(1,2)データを取得するために、現在の読み取りを更新したときしたがって、行trx_idのこの新しいバージョンは101です。

そのため、執行部Bのクエリ時間は、そのバージョン番号を見て、自分の更新は、直接使用することができ、最新データのバージョン番号が101で、101であるので、k個のクエリの値が3で取得します。

ここでは、概念を参照して、現在の読みと呼ばれます。実際には、外部の更新文に加えて、select文も、現在の読み取りをロックしている場合。

2.トランザクションBの更新ステートメントは、それ(ツーフェーズロック)に対処する方法でしょうか?

クエリは、ID = 1のビットを変更ここで、tからトランザクションA *を選択し、プラスモードまたは更新のためのinshareロックのであれば、またあなたは、バージョン番号が返される値は、3 Kで、101のデータで読むことができます。
表面たこれら2つの選択ステートメント読み取りロック(Sロック、共有ロック)とライトロック(Xロック、排他ロック)に添加しました。

トランザクションはすぐに何が起こるか、Cを提出しますが、以下のトランザクションC」になっていないと仮定し、さらに一歩行きますか?

 図6トランザクションA、B、C「の実行フロー

異なるトランザクションC「は、それが提出する前に、トランザクションBの更新ステートメントが最初に立ち上げ、更新後すぐに送信されません。私たちは、取引C「はコミットしなかったが、(1,2)このバージョンでは、生成されたが、前に述べたように、現在はあるとして
、最新バージョン。だから、トランザクションBの更新ステートメントは、それに対処する方法でしょうか?

この時点で、我々は以前の記事で述べた「2フェーズロック・プロトコル」は、それを再生しますトランザクションCは「それはまだリリースされ、このバージョンでは(1)書き込みロックされ、コミットされませんでした。現在のトランザクションBは、最新のバージョンを読み出す必要がある、読み込まれ、
トランザクションC「は、現在の読み取りを継続するためには、ロックを解除するまでロックされなければならないので、それがロックされている、それは待たなければなりません。

 7 Bトランザクション更新ロジック(トランザクションC「はフィット)

ここでは、文字列までの一貫性、および現在の読み取り行ロックをお読みください。

今、私たちは、問題の記事の最初に戻ります:

能力反復可能読み取りトランザクションがどのように達成することですか?

反復可能読み取り一貫性が読み出されるコア(読取り一貫性)のみ電流を読めば、トランザクションがデータを更新します。行は、現在のレコードが他の事項によって占有されてロックした場合は、ロック待機を入力する必要があります。

3、コミット読取りおよび反復可能読み取りの主な違いは?

論理読み取りおよび反復可能読み取りは、同様のロジックを提出し、彼らの主な違いは次のとおりです。

他のクエリの業務は、この一貫したビューで共通しているの後に反復可能読み取り分離レベルでは、唯一、トランザクション一貫性のあるビューの最初に作成する必要があり、
すべての文を読んで分離レベルで提出前に実行される新しいを再計算ビュー。

それでは、読書に分離レベルの下に提出、見てみましょう、トランザクションAとBのトランザクションのクエリをkで見つかった、それぞれ、どのくらいをすべきですか?

;これは、「一貫性のあるスナップショットとの取引を開始し、説明しなければならない 」 この文の意味は、初めからある、トランザクションを通じて継続一貫性のあるスナップショットを作成します。そのため、読み取りが分離レベルの下に提出され、この使用方法は、でしょう
、それは通常の開始トランザクションに相当し、意味を成しません。

ここで状態図を提出読むとき、あなたが変更されているこれらの2つのクエリの配列のビューを作成する機会を見ることができている、つまり、図は、ビューボックスをお読みください。(注:ここでは、C論理トランザクションまたは直接提出ではなく、事務Cを使用「)

 8コミット読取りトランザクション分離レベルの状態図

配列のこの瞬間ビューが作成される前に、この時点で、Aは、この文の実装であるクエリトランザクションのアレイのビューが作成され、配列(1,2)、(1,3)発生時刻。しかし、この時点で:

(3)ケース1に属さないの提出は、表示されていない
(2)提出、および3が見られる状況に属し

だから、今回の取引のクエリがk = 2を返します。明らかに、トランザクションBは、K = 3をもたらします。

IVの概要

データのInnoDBの行がいくつかのバージョンがあり、データの各バージョンは独自の行trx_idを持って、独自の文またはトランザクション一貫性のあるビューを持つ各。共通クエリが読取り一貫性、整合性に従って行trx_idとの一貫したビューに読み出される
データ放出の可視性を決定します。

;反復可能読み取りのために、クエリは専用トランザクションが開始する前に、既に完全なデータを提出認識
提出読み込み用に、クエリが唯一の文が始まる前に、完全なデータを認識提出されました。

常に最新版を読んで、現在の読書は、完了するまでに提出されました。

また、テーブル構造は「反復可能読み取り」をサポートしていない理由を考えることができますか?これはテーブル構造無しに対応するラインデータを、また行trx_idが存在しないので、それは、現在の読み出しの論理に従うことができます。

もちろん、MySQLの8.0はすでに、おそらく将来的には、テーブル反復可能読み取りの構造をサポートする、表構造のInnoDB辞書に置くことができます。

彼は質問の時間に行ってきました。私はテスト環境として、次の表の構造と初期化ステートメントを使用して、トランザクション分離レベルが反復可能読み取りです。今、私は、cのすべての値をしたい「とcがフィールドid値ラインに等しい『は明らかですが、見つかった
のGe』「奇妙な状況を取り除きます。このような状況から構成喜ばれ、その原理を説明。

MySQLの>表'T'(CREATE 
  `id`はint(11)NOT NULL、
  'C'はint(11)は、デフォルトのNULL、
  PRIMARY KEY(` id`)
)ENGINE = InnoDBテーブルと、
(4,4)、(3,3)、T(ID、C)の値(1,1)、(2,2)に挿入します。

  

あなたに再現された後、実際のビジネス開発におけるこのような状況が発生する可能性がありませんもう一度考えてみてください?アプリケーション・コードは、あなたがそれをどのように解決しなかった「ピット」に分類されないのだろうか?

あなたは、私は次の記事を終了し、あなたがこの問題を議論、コメント欄に書かれた自分の考えやアイデアを置くことができます。聴いてくれてありがとう、あなたは一緒に読むためにもっとたくさんの友達にこの共有を送るために歓迎されています。

第五に、時間の問題について

テーブルの最初の10,000行を削除する方法:私はあなたの問題を残しすることで、前回の記事でね。ループは20回つの接続でT限界500から削除実行:複数のメッセージ、すなわち、第二の方法を選択しました。
ケースは確かである、第二の方法は、比較的良好です。

実施例:;大トランザクションだけでなく、マスターからの遅延を引き起こす(すなわち直接実行がT限界10000から削除する)内部、長時間占有する単一の文は、ロック時間が比較的長いです。
第三の実施形態(すなわち、同時にT限界500から削除接続中:20)は、人工的にロック競合を引き起こします。

第六に、選択メッセージ

この理論的な知識は非常に豊富で、あなたは要約する必要があります。

1.innodb支持RCおよびRR分離レベルは、と一貫性のあるビュー(読取り一貫性ビュー)を達成することです

起動時の2情勢は、このスナップショットは、全体のライブラリに基づいて、スナップショットを取得します。

すなわち、ライブラリ全体を修正するためのライブラリ全体の意味に基づいて(スナップショットの読み出し)トランザクションには見えないが、トランザクション内で
のトランザクションは、トランザクション実行さらにDDL tのテーブル内の選択Tテーブルは、発生の時間に応じた場合、または行くことやロックエラーを行くために(第6章を参照してください)

3. MVCCトランザクションは、それを達成する方法ですか?

(1)各トランザクションは、トランザクションIDを持って、トランザクションIDは、(厳密に増加)と呼ばれる
あなたが示さup_limit_idコミットの最大トランザクションIDを見つけ、起動したとき(2)取引。
(3)の代わりにID = 2ウィルID = 1のようなID = 1として取引明細を更新し、前の行は、ログイン元に戻すラインをtrx_id、およびデータ・ページIDの値は2に変更そして、トレッキングヘッドに記録このステートメントのトランザクションIDを変更するために
、ラインのトランザクションIDとの比較を行うup_limit_id、データを表示するには、トランザクションを(4)と、ルールを設定するには、最初のトランザクションを使用する必要があります
up_limit_id場合> =トランザクションIDは、up_limit_id <トランザクションIDた場合、あなただけのログが取ら元に戻すために行くことができます見ることができます。up_limit_idすることよりも、行われる必要があるログデータを元に戻す時、>トランザクションIDを検索し、それがデータを返します。

4.現在の値のみ、現在の読書を読んで、電流による読み取りは、書き込みの前に読み込まれるまで、現在の読書とは何ですか。トランザクションのUp_limit_idは、トランザクショントランザクションIDに更新されます

5.なぜ読まれない再現性のRR RC、2例を達成することができます

(1)スナップショット読み出しの場合は、RR up_limit_idがトランザクション内で更新することができない、とそれぞれがスナップショットの読み取りの前にRCの更新トランザクションID、最新のコミットされたトランザクションをup_limit_idます、あなたは、再読み込みすることはできませんRC
(2)現在の読書次回、レコードロック+ギャップロックを使用してRRが達成されていますが、何のGAP RCは、それが反復可能読み取りのRCません

おすすめ

転載: www.cnblogs.com/luoahong/p/11606766.html