Redo ログと Undo ログに基づく MySQL クラッシュ回復の分析

Redo ログと Undo ログに基づく MySQL クラッシュ回復の分析

MySQLクラッシュ回復プロセス

バッファ プールは、MySQL メモリ構造のコア コンポーネントです。ブラック ボックスとして考えることができます。

1. ブラックボックス下のデータフローを更新する

データをクエリするときは、まずバッファー プールでクエリを実行します。データがバッファ プールに存在しない場合、ストレージ エンジンは最初にデータをディスクからバッファ プールにロードし、次にデータをクライアントに返します。同様に、特定のデータを更新するときに、データがバッファ プールに存在しない場合は、最初にデータがロードされ、次にメモリ内のデータが変更されます。変更されたデータは後でディスクにフラッシュされます。

MySQL クラッシュリカバリ:

このプロセスは問題ないように見えますが、実際には非倫理的です。バッファ プール内のデータを正常に変更したが、データをディスクにフラッシュする前に MySQL がクラッシュしたとします。どうすればよいでしょうか。上図のロジックによれば、更新されたデータはバッファプールにのみ存在します。この時点で MySQL がクラッシュすると、この部分のデータは永久に失われます。

さらに、アップデートの途中で突然エラーが発生し、アップデート前のバージョンにロールバックしたい場合はどうすればいいでしょうか?それは大変です。データの永続性とトランザクションのロールバックさえ保証できないのに、どうやってクラッシュ回復について話せるのでしょうか?

2. やり直しログと取り消しログ

MySQL がクラッシュから回復できるという事実から判断すると、MySQL は何か特別なことをしたに違いありません。そうです、これらは次に紹介する他の 2 つの重要な機能、 Redo LogUndo Logです。

これら 2 つのログは InnoDB ストレージ エンジン ログに属しており、MySQL サーバーの Binlog と同じディメンションではありません。

(1) Redo ログはトランザクションが完了した後のデータの状態を記録し、更新後の値を記録します。 (2) Undo ログはトランザクションが開始される前のデータの状態を記録し、更新前の値を記録します。したがって、これら 2 種類のログには明確な違いがあります。より一般的な例を使用して、これら 2 種類のログについて説明します。

Redo Log は、コマンド ラインに長いコマンドを入力し、Enter キーを押して実行した後、エラー メッセージが表示されたようなものです。この時点で、前のコマンドを取得して再度実行するには、もう一度 ↑ と入力するだけです。

Undo Log は、Git で何かをコミットした後、より複雑な変更を加えたものの、変更を行っている途中で気が狂ってしまい、行った変更が不要になったため、直接git reset --hard $lastCommitId以前のバージョンに戻したような状態です。

3. ログ実装後の更新プロセス

Redo ログと Undo ログを使用して、上記の図を改善してみましょう。

MySQL クラッシュリカバリ:

まず、データを更新するときに、データがバッファ プールに存在するかどうかを判断します。存在しない場合は、データがロードされます。上記でロールバックの問題について説明しました。バッファ プール内のデータを更新する前に、トランザクションが開始する前のデータの状態を Undo ログに書き込む必要があります。更新中にエラーが発生した場合は、Undo ログを使用してトランザクションの開始時点までロールバックできます。

次に、エグゼキュータはバッファ プール内のデータを更新し、更新が成功すると、データの最新の状態を Redo ログ バッファに書き込みます。トランザクションには複数の読み取りおよび書き込み操作が含まれる場合があるため、ディスク ファイルに 1 つずつ書き込むよりも、バッファーにグループ単位で書き込む方がはるかに効率的です。

再実行ログバッファ:

では、Undo Log にも Undo Log バッファーが備わっていなければ、Undo Log が高速化されず、両方が恩恵を受けられないのでしょうか? InnoDB にバッファがあると仮定し、トランザクション開始前のデータの状態を Undo Log Buffer に書き込み、その後データの更新を開始します。

突然、非常に短時間で、予期しないプロセスが原因で MySQL が終了します。このとき、困ったことが起こります。更新されたデータの一部がディスクにフラッシュバックされたが、トランザクションが成功せず、ロールバックする必要がある場合、プロセスの終了とともに Undo ログが消えていることがわかります。このとき、Undo ログを介してロールバックする方法はありません。

メモリが更新された直後に MySQL がクラッシュしたらどうなりますか?このとき、Redo ログ バッファへの書き込みも行われない場合があります。書き込まれたとしても、ディスクにフラッシュされず、Redo ログは失われます。

実際、それは問題ではありません。予期しないダウンタイムのため、トランザクションは成功しませんでした。トランザクションは成功しなかったため、ロールバックする必要があります。MySQL が再起動すると、ディスク上の Redo ログ ファイルが読み込まれ、そのステータスがバッファー プールにロードされます。ディスク Redo ログ ファイルを通じて復元された状態は、ダウンタイム前にトランザクションが開始される前の状態と同じであるため、影響はありません。その後、トランザクションがコミットされるのを待った後、REDO ログと Binlog がディスクにフラッシュされます。

3. プロセスにまだ存在する問題

これは完璧だと思うかもしれませんが、そうではありません。 Redo ログをディスクにフラッシュした後に MySQL が突然クラッシュし、binlog が時間内に書き込まれなかったとします。この時点でシステムを再起動すると、Redo ログで表されるステータスは Binlog で表されるステータスと一致しなくなります。 Redo ログによってバッファー プールに復元された行の A フィールドは 3 ですが、Binlog を監視するデータベースによって読み取られるデータは 2 です。

Redo Log と Binlog の両方がファイルに書き込まれている場合でも、MySQL が配置されている物理マシンまたは VM がクラッシュすると、ログは失われます。ファイルを書き込むと、現在の OS は効率を向上させるために、まず変更されたコンテンツをOS キャッシュに書き込みます。次に、ポリシー (設定したパラメータの影響を受ける) に基づいて、OS キャッシュ内のデータがディスクにフラッシュされます。

4. 2PCに基づく一貫性の保証

このことから、トランザクションがコミットされるときに、Redo Log と Binlog のデータ一貫性を保証する必要があるという重要な問題がわかります。両方が存在するか、どちらも存在しないかのどちらかです。 MySQL は **2PC (2 フェーズ コミット プロトコル)** を通じて実装されています。

MySQL クラッシュリカバリ:

2PC について簡単に紹介します。これは、分散トランザクション データの一貫性を保証するプロトコルです。中国語名は 2 フェーズ コミットで、分散トランザクションの送信を準備とコミット/ロールバックの 2 つの段階に分割します。

2 人のボクサーが試合を始める前に、審判は中央で 2 人のボクサーの状態を確認します。これは「準備はいいですか?」と尋ねるのと似ています。確認後、審判員は「ファイト」と言います。

審判はプレイヤーに状態を尋ねます。これは第一階段Prepareに相当します。肯定的な回答を受け取った後、審判はゲームの正式な開始を宣言します。これは第二階段Commitに相当します。ただし、1 人のプレイヤーの準備ができていない場合、審判はゲームの一時停止を宣言します。これは第 1 段階の失敗に相当し、第 2 段階のステータスは「ロールバック」に変わります。審判は2PCの協調者Coordinatorに相当し、プレーヤーは參與者Participantに相当します。

全体のプロセスを写真で見てみましょう: 2PCフラッシュからディスクへ

準備フェーズでは、REDO ログがファイルに書き込まれ、ディスクにフラッシュされ、内部 XA トランザクションの ID が記録され、REDO ログのステータスが準備に設定されます。 Redo ログが正常に書き込まれると、Binlog もディスクにフラッシュされ、XA トランザクション ID が記録されます。

コミット フェーズでは、トランザクションがコミットされたことを示すコミット フラグがディスク上の Redo ログに書き込まれます。次に、エグゼキュータはストレージ エンジンのインターフェイスを呼び出してトランザクションをコミットします。これが全体のプロセスです。

5. 2PCメカニズムの可用性を確認する

これは 2PC が Redo Log と Binlog を送信するプロセスです。この期間中に例外が発生した場合、2PC メカニズムは本当にデータの一貫性を保証できるのでしょうか?

Redo ログは正常にフラッシュされたが、Binlog をフラッシュする前に MySQL がクラッシュしたと仮定します。再起動後、Redo Log にコミット マーカーがないことがわかります。このとき、記録された XA トランザクションに基づいてこのトランザクションを見つけてロールバックします。

Redo ログが正常にフラッシュされ、Binlog も正常にフラッシュされたが、Redo ログを Prepare から Commit に変更する前に MySQL がクラッシュした場合、再起動すると、Redo ログに Commit フラグがないにもかかわらず、XID によってクエリされた Binlog がディスクに正常にフラッシュされていることがわかります。

この時点では、Redo ログにコミット マークはありませんが、MySQL はトランザクションをコミットする必要があります。 Binlog が書き込まれると、Binlog を消費するスレーブまたは任意のコンシューマーによって消費される可能性があるためです。この時点で MySQL がトランザクションをコミットしない場合、データの不整合が発生する可能性があります。さらに、Redo Log と Binlog は、フラグを除いて、データ レベルから実際に準備されています。

これで、Redo ログと Undo ログに基づく MySQL クラッシュ リカバリ分析に関するこの記事は終了です。MySQL クラッシュ リカバリ プロセスの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL の redo ログと binlog の違いを 1 つの記事で理解する
  • MySQL における redo ログと binlog の違い
  • MySQL の undo、redo、binlog の違いを簡単に分析します
  • MySQLのREDOログとUNDOログの詳細な説明
  • MySQL Undo ログと Redo ログの概要
  • MySQL 8.0 redo ログの詳細な分析
  • MySQL シリーズ: redo ログ、undo ログ、binlog の詳細な説明
  • MySQLのREDOログ(リドゥログ)とロールバックログ(アンドゥログ)の詳しい説明
  • MySQL redo logの詳細な理解 redo log

<<:  Docker Compose は MySQL に接続するために SpringBoot プロジェクトをデプロイしますが、そこで遭遇する落とし穴があります。

>>:  画像の半透明処理 画像と半透明の背景の実装のアイデアとコード

推薦する

Tomcat 7.0 で仮想ディレクトリを設定し、仮想パスを構成する方法

Tomcat7.0は仮想ディレクトリを設定します(1)現在、当社のウェブサイトはデフォルトのディレク...

Docker+nacos+seata1.3.0 のインストールと使用設定チュートリアル

これに先立ち、1日かけてやってみました。Seataは使い方が簡単で超シンプルですが、インストールや設...

Win10 システムに MySQL8.0.13 をインストールする際の問題と解決策

オペレーティングシステム: Windows10 MySQL バージョン: 8.0.13-winx64...

MySQL をベースにしたシンプルな検索エンジンを実装する

目次MySQL ベースの検索エンジンの実装1. ngram全文パーサー2. 全文インデックスを作成す...

ページデザインにおけるテーブルとdivの適切な適用についての簡単な説明

この記事の冒頭で、以前書いた入門記事の間違いを訂正したいと思います。初心者を再び誤解させないように、...

Alipay の Java 決済インターフェースを開発するための詳細な手順

目次最初のステップステップ2ステップ3ステップ4 Alipay 決済インターフェースへの接続に関する...

MySQL でスロークエリログ機能を有効にする方法

MySQL スロー クエリ ログは、問題のあるクエリを追跡するのに非常に役立ちます。現在のプログラム...

良いと思う国内のデザインサイトをいくつか選んでみました。

<br />私が良いと思った国内のデザインサイトをまとめてみました。広告ではありません!...

jQuery を使用してカルーセル効果を実装する

この記事では、jQueryでカルーセルチャートを実装するための具体的なコードを参考までに共有します。...

CSS で画像アダプティブ コンテナを実装するためのサンプル コード

多くの場合、画像をコンテナのサイズに合わせて調整する必要があります。 1. imgタグ方式幅と高さを...

JavaScript で localStorage を使用する方法

.NET の世界に参入したい開発者であれば、何が可能なのかを知る必要があります。 .NET Fram...

Docker Consul コンテナ サービスの更新と見つかった問題の概要

目次1. コンテナサービスの更新とDockerコンサルの検出1. サービス登録と検出とは何ですか? ...

マスタークラスタに再参加する k8s ノードの実装

1. ノードを削除するkubectl delete node node01を実行します。 2. この...

ログインボックスのメールプロンプトを実装するネイティブJS

この記事では、登録またはログイン時に電子メール アドレスを入力する際のドロップダウン プロンプトのネ...