トランザクションは、MySQL を NoSQL と区別する重要な機能であり、リレーショナル データベースのデータの一貫性を確保するための重要なテクノロジです。 1 つ以上の SQL ステートメントで構成される基本的な実行単位は、データベースに対するトランザクションの操作とみなすことができます。これらのステートメントが実行されると、すべてが実行されるか、まったく実行されません。
トランザクションの実行には、主にコミットとロールバックの 2 つの操作が含まれます。
送信: コミットし、トランザクションの実行結果をデータベースに書き込みます。
ロールバック: ロールバック、実行されたすべてのステートメントをロールバックし、変更前のデータを返します。
MySQL トランザクションには、4 つの ACID キングとして知られる 4 つの特性が含まれています。
トランザクションのアトミック性は、UNDO ログによって実現されます。トランザクションをロールバックする必要がある場合、InnoDB エンジンは SQL ステートメントを元に戻すために undo ログを呼び出します。データのロールバック。原子性: ステートメントは完全に実行されるか、まったく実行されません。これはトランザクションの中核機能です。トランザクション自体は原子性によって定義され、実装は主に UNDO ログに基づいています。
Durability (永続性): トランザクション送信後のダウンタイムなどでデータが失われないことを保証します。主に REDO ログに基づいて実装されます。トランザクションの実行は可能な限り可能です 他のトランザクションの影響を受けません; InnoDB のデフォルトの分離レベルは RR です。RR の実装は主に、ロック メカニズム、データの非表示列、元に戻すログ、ネクスト キー ロック メカニズムに基づいています。
一貫性: トランザクション 追求される最終目標である一貫性の実現には、データベース レベルとアプリケーション レベルの両方での保証が必要です。トランザクション アトミック操作と同様に、トランザクションをさらに分割できないことを意味します。すべての操作が完了するか、まったく操作が完了しないかのどちらかです。トランザクション内の SQL ステートメントの実行に失敗した場合、実行されたステートメントもロールバックする必要があります。 、データベースはトランザクション前の状態に戻ります。0 と 1 のみで、他の値はありません。
トランザクションのアトミック性は、トランザクションが全体であることを示します。トランザクションが正常に実行できない場合、すべてトランザクション内で実行されたステートメントはロールバックする必要があるため、データベースはトランザクションが最初に開始されていない状態に戻ります。
#トランザクションの耐久性は、InnoDB ストレージ エンジンの REDO ログによって実現されます。具体的な実装アイデアは以下を参照してください。
分離トランザクションには SQL ステートメントが 1 つだけ含まれているわけではないため、トランザクションの実行中にエラーが発生する可能性があります。他のトランザクションが実行を開始します。したがって、複数トランザクションの同時実行では、トランザクション間の操作を相互に分離する必要があります。
ロック メカニズム多くのシナリオでは、データの保護と同期にさまざまなロックを使用するため、ロック メカニズムは馴染みのないものではありません。概念: MySQL では、ロックはさまざまな分割基準に従ってさまざまなタイプに分割することもできます。
粒度に応じて分割: 行ロック、テーブル ロック、ページ ロック用途に応じて分割: 共有ロック、排他ロック
アイデアに応じて分割: 悲観的lock 、 Optimistic lockingロック機構については多くの知識点がありますが、スペースの都合上、すべて説明します。ここでは、粒度に従って分割されたロックについて簡単に紹介します。
行ロック: 最小粒度のロック。現在の操作の行のみがロックされていることを示します。粒度: データ ウェアハウスのデータ ユニットに保存されているデータの精製度または包括性のレベルを指します。精製度が高いほど粒度は小さくなり、逆に精製度が低いほど粒度は大きくなります。
MySQL は、ロックの粒度に応じて行ロック、テーブル ロック、ページ ロックに分類できます。
ページ ロック: 行レベルのロックとテーブル レベルのロックの間の粒度を持つロック、つまりページをロックすることを意味します。テーブル ロック:最大の粒度、現在の操作がテーブル全体をロックすることを示します;
#データベースの粒度の分割これら 3 種類のロックは、異なるレベルでデータをロックします。粒度が異なるため、次のような利点がもたらされます。デメリットも異なります。
テーブル ロックはデータ操作時にテーブル全体をロックするため、同時実行パフォーマンスが低下します。
行ロックは操作が必要なデータのみをロックするため、同時実行パフォーマンスは良好です。ただし、ロック自体がリソースを消費するため (ロックの取得、ロックの確認、ロックの解放などはすべてリソースを消費します)、ロックされたデータが多い場合にはテーブル ロックを使用するとリソースを大幅に節約できます。
MySQL のさまざまなストレージ エンジンは、さまざまなロックをサポートできます。 MyIsam はテーブル ロックのみをサポートしますが、InnoDB はテーブル ロックと行ロックの両方をサポートします。パフォーマンス上の理由から、ほとんどの場合、行ロックが使用されます。
同時読み取りと書き込みの問題
MySQL の同時読み取りと書き込みにより、ダーティ リード、非再現性、ファントム読み取りという 3 種類の問題が発生する可能性があります。 。
(1) ダーティ読み取り: 現在のトランザクションは、他のトランザクションからコミットされていないデータを読み取ります。これはダーティ データです。
上記のシナリオ例では、トランザクション A が記事の読書量を読み取るときに、トランザクション B がまだ送信していないデータを取得します。最終的にトランザクション B が正常に送信されず、トランザクションがロールバックされた場合、読み取り量は実際には正常に変更されませんが、トランザクション A は変更された値を読み取ります。これは明らかに不合理です。
(2) 反復不可読み取り: トランザクション A で同じデータが 2 回読み取られますが、2 回の読み取り結果は異なります。ダーティ リードとノンリピータブル リードの違いは、前者は他のトランザクションによってコミットされていないデータを読み取るのに対し、後者は他のトランザクションによって送信されたデータを読み取ることです。
たとえば、トランザクション A が記事読み取りデータを順番に読み取ると、異なる結果が得られます。これは、トランザクション A の実行中に、他のトランザクションによって読み取りボリュームの値が変更されたことを意味します。これにより、データ クエリの結果は信頼できなくなり、非現実的になります。
書き換え後:トランザクションAにおいて、ある条件に従って2つのデータベースクエリを実行すると、クエリ結果の行数が異なり、ファントムリードが発生します。元の単語は次のように書き換えることができます。 ファントム読み取りと比較すると、反復不可能な読み取りはデータの変更、つまりデータの行数の変更に似ています。
上の図は例で、0分離レベル
上記の 3 つの問題に基づいて、データベースの分離特性の異なる程度を示す 4 つの分離レベルが生成されました。 実際のデータベース設計では、分離レベルが高くなるほどデータベースの同時実行効率が低下し、分離レベルが低すぎると、データベースの読み取りおよび書き込みプロセス中にエラーが発生すると、あらゆる種類のやっかいな問題が発生します。 したがって、ほとんどのデータベース システムでは、デフォルトの分離レベルはコミット読み取り (Oracle など) または反復読み取り RR (MySQL の InnoDB エンジン) です。MVCC
またしても噛み砕くのが難しい大きな作品。 MVCC は、RR を繰り返し読み取ることができる上記の 3 番目の分離レベルを実装するために使用されます。マルチバージョン同時実行制御 (MVCC とも呼ばれる) は、複数のバージョンのデータをサポートできる同時実行制御プロトコルです。MVCC の特徴は、異なるトランザクションで異なるバージョンのデータを同時に読み取ることができるため、ダーティ リードや反復不可能な読み取りの問題が解決されることです。 MVCC は実際に、データの非表示列とロールバック ログ (UNDO ログ) を通じて、複数のバージョンのデータの共存を実現します。この利点は、MVCC を使用してデータを読み取るときにロックする必要がないため、同時読み取りと書き込みの競合が回避されることです。 MVCC を実装すると、バージョン番号、現在の行が作成されたときの削除時刻、UNDO ログへのロールバック ポインタなど、いくつかの追加の非表示列がデータの各行に保存されます。ここでのバージョン番号は実際の時間値ではなく、システムのバージョン番号です。新しいトランザクションが開始されるたびに、システムのバージョン番号が自動的に増加します。トランザクションの開始時に、クエリされたレコードの各行のバージョン番号と比較するために、システム バージョン番号にトランザクション バージョン番号が割り当てられます。 各トランザクションには独自のバージョン番号があり、トランザクション内でデータ操作が実行されるとき、バージョン番号を比較することでデータのバージョン管理の目的が達成されます。 さらに、InnoDB によって実装された分離レベル RR は、ネクスト キー ロック メカニズムによって実現されるファントム読み取り現象を回避できます。
next-key ロックは、実際には行ロックの一種ですが、現在の行レコード自体をロックするだけでなく、範囲もロックする点が異なります。たとえば、上記のファントム リーディングの例では、0
ギャップ ロック: インデックス レコードのギャップをブロックします。
InnoDB はファントム リードの問題を回避するためにネクスト キー ロックを使用しますが、これは真にシリアル化可能な分離ではありません。別の例を見てみましょう。
最初に質問します:
トランザクション A がトランザクションをコミットした後の T6 時点で、記事 A と記事 B の読書量を推測します。いくらですか?
答えは、記事 AB の閲覧数が 10,000 に変更されたことです。これは、トランザクション B の送信が実際にトランザクション A の実行に影響を与えることを意味し、さらに 2 つのトランザクションが完全に独立していないことを示しています。ファントムリード現象は回避できますが、シリアル化できるレベルには達しません。
シリアル化可能な分離レベルを達成するために必要な条件は、ダーティ リード、非反復読み取り、ファントム リードを回避することですが、これだけでは十分ではありません。シリアル化可能性により、ダーティ リード、ノンリピータブル リード、ファントム リードを回避できますが、ダーティ リード、ノンリピータブル リード、ファントム リードを回避しても必ずしもシリアル化可能性が実現するとは限りません。
一貫性
一貫性とは、トランザクションの実行後、データベースの整合性制約が破壊されず、トランザクションの実行前後のデータ状態が正当であることを意味します。実行されました。
一貫性はトランザクションによって追求される究極の目標であり、実際にはデータベース状態の一貫性を確保するために原子性、耐久性、分離性が存在します。
これ以上は言いません。丁寧に味わっていただきます。
MySQL の基本構造を学習した後、MySQL の実行プロセスを比較的正確に理解できるようになりました。次にロギングシステムについて紹介します。
MySQL ログ システムはデータベースの重要なコンポーネントであり、データベースの更新と変更を記録するために使用されます。データベースに障害が発生した場合、別のログ レコードを通じてデータベースの元のデータを復元できます。したがって、実際には、ログ システムが MySQL 操作の堅牢性と堅牢性を直接決定します。
MySQL には、バイナリ ログ (binlog)、エラー ログ、クエリ ログ、スロー クエリ ログなど、多くの種類のログがあります。さらに、InnoDB ストレージ エンジンは、次の 2 種類のログも提供します。REDO ログ ( redo ログ)と undo ログ(ロールバック ログ)。ここでは InnoDB エンジンに焦点を当て、REDO ログ、ロールバック ログ、バイナリ ログの 3 種類を分析します。
Redo ログ (redo ログ)
REDO ログ (redo ログ) は、InnoDB エンジン層のログであり、原因となったデータの変更を記録するために使用されます。トランザクション操作による、データ ページの物理的な変更です。
日記のやり直し機能は実はわかりやすいので例えてみましょう。データベース内のデータの変更は、自分で書いた論文のようなものですが、ある日その論文を紛失してしまったらどうなるでしょうか?このような不幸な出来事を防ぐために、論文を書くときに、すべての変更を記録する小さなノートを用意し、特定のページにいつ、どのような変更が加えられたかを記録することができます。これはやり直しログです。
InnoDB エンジンは、最初に更新レコードを REDO ログに書き込み、次にシステムがアイドル状態のときまたは設定された更新戦略に従ってログの内容をディスクに更新することによってデータを更新します。いわゆる、先行書き込みログ技術 (Write Ahead logg) です。このテクノロジーにより、IO 操作の頻度が大幅に削減され、データ更新の効率が向上します。
ダーティデータフラッシュ
REDOログのサイズは固定であることに注意してください.更新レコードを継続的に書き込むために、REDOでは2つのフラグ位置が設定されますログには、checkpoint と write_pos があり、それぞれ消去が記録された位置と書き込みが記録された位置を示します。 REDO ログのデータ書き込み図を次の図に示します。
write_pos マークがログの末尾に達すると、ログの末尾から先頭にジャンプして再循環書き込みを行います。したがって、REDO ログの論理構造は直線的ではなく、循環運動とみなすことができます。 write_pos と Checkpoint の間のスペースは新しいデータの書き込みに使用でき、書き込みと消去は 1 サイクル内で前後に実行されます。
write_pos がチェックポイントに追いつくと、REDO ログがいっぱいになったことを意味します。現時点では、新しいデータベース更新ステートメントを実行し続けることはできません。最初にいくつかのレコードを停止して削除し、チェックポイント ルールを実行して書き込み可能な領域を解放する必要があります。
チェックポイント ルール: チェックポイントがトリガーされた後、バッファ内のダーティ データ ページとダーティ ログ ページの両方をディスクにフラッシュします。
ダーティ データ: ディスクにフラッシュされていないメモリ内のデータを指します。
REDO ログの最も重要な概念はバッファ プールです。これはメモリ内に割り当てられる領域であり、データベースにアクセスするためのバッファとしてディスク内の一部のデータ ページのマッピングが含まれます。
データの読み取りをリクエストすると、まずバッファ プールにヒットがあるかどうかが判断され、ミスがあった場合は、ディスク上でデータが取得され、バッファ プールに置かれます。
##データの書き込み要求が行われると、まずそのデータがバッファー プールに書き込まれ、バッファー プール内の変更されたデータが定期的にディスクに更新されます。このプロセスはブラッシングとも呼ばれます。したがって、データが変更されると、バッファー プール内のデータの変更に加えて、操作が REDO ログにも記録され、トランザクションが送信されるとデータがフラッシュされます。 REDO ログレコードに基づくプレート。 MySQL がダウンした場合でも、再起動時に REDO ログ内のデータを読み取ってデータベースを復元できるため、トランザクションの耐久性が確保され、データベースのクラッシュセーフ機能が得られます。
ダーティ ログのフラッシュ
上記のダーティ データのフラッシュに加えて、実際には、REDO ログが記録されるときに、ログ ファイルを作成するには、ログ レコードをメモリからディスクに書き込むプロセスも実行する必要があります。 REDO ログのログは、揮発性メモリ上に存在するキャッシュログ REDO ログ buff と、ディスク上に保存された REDO ログファイル REDO ログファイルの 2 つに分けられます。 各レコードをディスク上のログに確実に書き込むために、REDO ログ バッファ内のログが REDO ログ ファイルに書き込まれるたびに、オペレーティング システムの fsync 操作が呼び出されます。fsync 関数: UNIX システム ヘッダー ファイル #include書き込み時には、オペレーティング システムのカーネル空間のキャッシュも通過する必要があります。 REDO ログの書き込みプロセスを次の図に示します。 REDO ログ フラッシュ プロセスに含まれており、メモリ内で変更されたすべてのファイル データをストレージ デバイスに同期するために使用されます。
バイナリ ログ (binlog)
バイナリ ログ binlog はサービス層です。ログはアーカイブ ログとも呼ばれます。 Binlog は、データベースの変更を含む、データベース内のすべての更新操作を記録します。データ変更を伴うすべての操作はバイナリ ログに記録する必要があります。したがって、binlog はデータのコピーとバックアップが簡単にできるため、マスター/スレーブ ライブラリの同期によく使用されます。 binlog と REDO ログの記憶内容は似ていますが、実際には異なります。 REDO ログは特定のデータに対する実際の変更を記録する物理ログですが、binlog は SQL ステートメントの元のロジックを記録する論理ログです。たとえば、「ID=2 の行のフィールドを指定する」などです。プラス1」。 binlog ログの内容はバイナリであり、ログ形式パラメータに応じて、SQL ステートメント、データ自体、またはその 2 つの混合に基づく場合があります。一般によく使用されるレコードは SQL ステートメントです。 ここでの物理と論理の概念についての私の個人的な理解は次のとおりです:物理ログは、実際のデータベースのデータ ページの変更情報とみなすことができ、 「どのような方法でこの結果になったか」は重要ではなく、 論理ログとは、ある方法や操作方法によるデータの変化とみなして、論理的な操作を記録したものです。同時に、REDO ログは MySQL クラッシュ後のデータ回復を保証するクラッシュ リカバリに基づいており、一方、binlog はポイントインタイム リカバリに基づいており、サーバーがデータに基づいてデータを回復できることを保証します。時点、またはデータのバックアップを作成します。 実は、MySQL には最初は REDO ログがありませんでした。当初、MySQL には InnoDB エンジンがなかったため、組み込みエンジンは MyISAM でした。 Binlog はサービス層のログであるため、すべてのエンジンで使用できます。ただし、binlog ログだけではアーカイブ機能しか提供できず、クラッシュ セーフ機能を提供できないため、InnoDB エンジンは Oracle から学んだ技術、つまり REDO ログを使用してクラッシュ セーフ機能を実現します。ここでは、REDO ログと binlog の特性をそれぞれ比較します。
##REDO ログと binlog の特性の比較
MySQL が update ステートメントを実行すると、 REDO ログと binlog ログの読み取りと書き込みが含まれます。 update ステートメントの実行プロセスは次のとおりです。
MySQL update ステートメントの実行プロセス
#上図からわかるように、MySQL が実行されると、 update ステートメントを実行し、サービス層でステートメントの解析と実行、エンジン層でデータの抽出と保存を行うと同時に、サービス層で binlog を書き込み、InnoDB で REDO ログを書き込みます。
それだけでなく、REDO ログの書き込みには 2 つの段階があります。1 つはバイナリログが書き込まれる前の準備状態の書き込み、もう 1 つはバイナリログが書き込まれた後のコミット状態の書き込みです。 。
このような 2 段階の提出を設定したのには、当然のことながら理由があります。ここで、2 段階の送信を使用する代わりに、「単一段階」の送信、つまり、最初に REDO ログを書き込んでから binlog を書き込むか、最初に binlog を書き込んでから REDO ログを書き込むかのいずれかを採用すると仮定できます。これら 2 つの方法で送信すると、元のデータベースの状態と復元されたデータベースの状態が一致しなくなります。
最初に REDO ログを書き込み、次に binlog を書き込みます:
REDO ログを書き込んだ後、現時点ではデータにはクラッシュ セーフ機能があるため、システムがクラッシュし、データがトランザクション開始前の状態に復元されます。 REDO ログが書き込まれた後、binlog が書き込まれる前にシステムがクラッシュした場合は...現時点では、binlog は上記の更新ステートメントを保存しないため、binlog を使用してデータベースをバックアップまたは復元すると、上記の更新ステートメントが失われます。その結果、id=2の行のデータは更新されません。
REDO ログを最初に書き込み、次に binlog を書き込む問題
最初に binlog を書き込み、次に REDO ログを書き込みます:
バイナリログの書き込み後、すべてのステートメントが保存されるため、バイナリログを通じてコピーまたは復元されたデータベースの行 id=2 のデータは a=1 に更新されます。ただし、REDO ログが書き込まれる前にシステムがクラッシュした場合、REDO ログに記録されたトランザクションは無効となり、実際のデータベースの id=2 行のデータは更新されません。
最初に binlog を書き込み、次に redo ログを作成する問題
2 段階の送信は、上記の問題を回避するために binlog を作成するためであることがわかります。 REDO ログと REDO ログに保存される情報は一貫しています。
ロールバック ログ (元に戻すログ)
InnoDB エンジンは、データのロールバック操作に使用されるロールバック ログを提供します。トランザクションがデータベースを変更すると、InnoDB エンジンは REDO ログを記録するだけでなく、対応する UNDO ログも生成します。トランザクションの実行が失敗するかロールバックが呼び出され、トランザクションがロールバックされた場合、UNDO ログ内の情報はデータを復元するために使用できます。変更前の状態までスクロールします。
ただし、UNDO ログは REDO ログとは異なり、論理的なログです。 SQL ステートメントの実行に関連する情報を記録します。ロールバックが発生すると、InnoDB エンジンは、元に戻すログのレコードに基づいて、前の作業の逆を実行します。たとえば、各データ挿入操作 (insert) に対して、ロールバック中にデータ削除操作 (delete) が実行され、各データ削除操作 (delete) に対して、ロールバック中にデータ挿入操作 (insert) が実行されます。 update 操作 (update)、ロールバックする場合、データを元に戻すために逆データ更新操作 (update) が実行されます。 Undo ログには 2 つの機能があります。1 つはロールバックを提供することで、もう 1 つは MVCC を実装することです。
マスター/スレーブ レプリケーションの概念は非常に単純で、元のデータベースから同一のデータベースをコピーすることです。はマスター データベースと呼ばれ、レプリケートされたデータベースはスレーブ データベースと呼ばれます。スレーブ データベースはデータをマスター データベースと同期して、2 つのデータベース間のデータの一貫性を維持します。
マスター/スレーブ レプリケーションの原理は、実際には bin ログを通じて実装されます。 bin log ログにはデータベース内のすべての SQL ステートメントが保存されており、bin log ログ内の SQL ステートメントをコピーして実行することで、スレーブ データベースとマスター データベースの間で同期を実現できます。
マスター/スレーブ レプリケーション プロセスを次の図に示します。マスター/スレーブ レプリケーション プロセスは主に 3 つのスレッドによって実行され、送信スレッドはマスター サーバーで実行され、binlog ログをスレーブ サーバーに送信するために使用されます。スレーブ サーバー上では、さらに 2 つの I/O スレッドと SQL スレッドが実行されます。 I/O スレッドは、メイン サーバーから送信された binlog ログの内容を読み取り、それをローカル リレー ログにコピーするために使用されます。 SQL スレッドは、データ更新を含む SQL ステートメントをリレー ログから読み取り、これらのステートメントに基づいて操作を実行して、マスター/スレーブ データベース内のデータの一貫性を確保します。
マスター/スレーブ レプリケーションの原則
マスター/スレーブ レプリケーションを実装する必要がある理由は、実際には、実際のアプリケーション シナリオによって決まります。マスター/スレーブ レプリケーションによってもたらされる利点は次のとおりです:
1. データのオフサイト バックアップはレプリケーションによって実現され、マスター データベースに障害が発生した場合、スレーブ データベースを切り替えることでデータ損失を回避できます。
2. アーキテクチャの拡張が可能で、業務量が大きくなりI/Oアクセス頻度が高すぎる場合、マルチデータベースストレージを利用することでディスクI/Oアクセス頻度を低減し、業務効率を向上させることができます。単一マシンの効率、I/O パフォーマンス。
3. 読み取りと書き込みの分離を実現できるため、データベースはより優れた同時実行性をサポートできます。
4. 顧客のクエリの負荷をマスター サーバーとスレーブ サーバーに分散して、サーバーの負荷分散を実装します。
以上がMySQL トランザクション ログの特徴は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。