MySQL シリーズ: redo ログ、undo ログ、binlog の詳細な説明

MySQL シリーズ: redo ログ、undo ログ、binlog の詳細な説明

取引の実施

REDO ログはトランザクションの永続性を保証し、UNDO ログはトランザクションのロールバックと MVCC 機能を支援するために使用されます。

InnoDB ストレージ エンジン アーキテクチャ

再実行ログ

先行書き込みログ戦略

トランザクションがコミットされると、最初に REDO ログが書き込まれ、次にページが変更されます。クラッシュによりデータが失われた場合、REDO ログを通じてデータを回復できます。

  • InnoDBはまずREDOログ情報をREDOログキャッシュに格納します。
  • 一定の頻度でログファイルを再実行するために更新する

REDO ログ ファイル: デフォルトでは、InnoDB ストレージ エンジンのデータ ディレクトリに ib_logfile1 と ib_logfile2 という名前の 2 つのファイルがあります。各 InnoDB ストレージ エンジンには少なくとも 1 つの REDO ログ ファイル グループがあり、各ファイル グループには少なくとも 2 つの REDO ログ ファイルがあります。

次の図 1 は、REDO ログ グループが循環書き込みモードで実行されていることを示しています。InnoDB ストレージ エンジンは最初に ib_logfile1 に書き込み、ファイルの末尾に達すると、REDO ログ ファイル ib_logfile2 に切り替えます。

図 2 に示すように、OS バッファーを追加すると、fsync プロセスを理解しやすくなります。

ログ グループは、論理的な概念である REDO ログ グループと呼ばれます。 InnoDB ストレージ エンジンには、実際には 1 つのログ グループしかありません。

ログ グループの最初の REDO ログ ファイルには、最初の 2 KB に 512 バイトのブロックが 4 つ格納されます。

REDOログバッファがディスクにフラッシュされました

次の 3 つの状況が更新されます。

  • マスタースレッドは、1秒ごとにREDOログバッファをREDOログファイルにフラッシュします。
  • 各トランザクションがコミットされると、REDOログバッファはREDOログファイルにフラッシュされます。
  • 再実行ログバッファプールの残りスペースが1/2未満になると、再実行ログは再実行ログファイルにフラッシュされます。

上記の 3 つの状況のうち 2 番目の状況を補足するために、ディスク書き込みプロセスのトリガーは、コミット操作の実行時に REDO ログを処理する方法を示すパラメーター innodb_flush_log_at_trx_commit によって制御されます。

パラメータinnodb_flush_log_at_trx_commitの有効な値は0、1、2です。

  • 0 は、トランザクションがコミットされたときに、トランザクションの REDO ログがディスク上のログ ファイルに書き込まれず、メイン スレッドが 1 秒ごとに更新するのを待機することを意味します。
  • 1はコミットの実行時にREDOログバッファをディスクに同期的に書き込むことを意味します。つまり、fsyncの呼び出しを伴います。
  • 2 は、REDO ログを非同期でディスクに書き込む、つまりファイル システム キャッシュに書き込むことを意味します。コミット時に REDO ログ ファイルが書き込まれるという保証はありません。

0 の場合、データベースがクラッシュすると、一部のログがディスクにフラッシュされないため、最後の期間のトランザクションが失われます。
2. オペレーティング システムがクラッシュすると、ファイル システム キャッシュから REDO ログ ファイルにフラッシュされていないトランザクションの部分は、データベースの再起動後に失われます。

次の図は理解を助ける

REDOログブロック

InnoDB ストレージ エンジンでは、REDO ログは 512 バイトで保存されます。つまり、REDO ログ キャッシュと REDO ログ ファイルはブロック単位で保存され、各ブロックは 512 バイトになります。

REDO ログ ヘッダーは 12 バイト、REDO ログ テールは 8 バイトなので、各 REDO ログ ブロックには実際には 492 バイトを格納できます。

REDOログ形式

REDO ログはページベースの形式で記録されます。デフォルトでは、InnoDB のページ サイズは 16 KB です (innodb_page_size 変数によって制御されます)。ページには多数のログ ブロック (各 512 バイト) を保存でき、ログ ブロックにはデータ ページの変更が記録されます。

ログ本体の形式は 4 つの部分に分かれています。

  • redo_log_type: 1 バイトを占め、REDO ログのログ タイプを示します。
  • space: テーブルスペースの ID を示します。圧縮後、占有スペースは 4 バイト未満になる場合があります。
  • page_no: 圧縮されたページ オフセットを示します。
  • redo_log_body は各 redo ログのデータ部分を表し、リカバリ中に解析のために対応する関数が呼び出されます。たとえば、挿入ステートメントと削除ステートメントによって REDO ログに書き込まれる内容は異なります。

次の図は、挿入と削除の一般的な記録方法を示しています。

REDOログリカバリ

次の LSN (ログ シーケンス番号) はチェックポイントを表します。データベースが LSN 10000 でクラッシュした場合、回復操作では LSN10000 ~ LSN13000 の範囲のログのみが回復されます。

元に戻すログ

UNDOログの役割

Undo は、データベースを論理的に元の状態に復元するだけの論理ログです。すべての変更は論理的にキャンセルされますが、ロールバック後にデータ構造とページ自体が異なる場合があります。

UNDO ログには、ロールバックと複数行バージョン制御 (MVCC) の提供という 2 つの機能があります。

InnoDB ストレージ エンジンがロールバックすると、各 INSERT に対して DELETE が完了し、各 DELETE に対して INSERT が実行され、各 UPDATE に対して逆 UPDATE が実行されて前の行が戻されます。

MVCC: ユーザーがレコードの行を読み取るときに、そのレコードが他のトランザクションによって占有されている場合、現在のトランザクションは元に戻す操作を通じて前の行のバージョン情報を読み取ることができ、ロックなしの読み取りを実現します。

UNDOログ保存方法

InnoDB ストレージ エンジンは、セグメント単位で UNDO を管理します。ロールバック セグメントはロールバック セグメントと呼ばれ、各ロールバック セグメントには 1024 個の UNDO ログ セグメントがあります。

旧バージョンでは、ロールバック セグメントは 1 つしかサポートされていなかったため、記録できる UNDO ログ セグメントは 1024 個だけでした。その後、MySQL 5.5 では 128 個のロールバック セグメント、つまり 128*1024 個の取り消し操作がサポートされるようになりました。また、変数 innodb_undo_logs (バージョン 5.6 より前では、この変数は innodb_rollback_segments でした) を使用してロールバック セグメントの数をカスタマイズすることもできます。デフォルト値は 128 です。

UNDO ログは、デフォルトで共有表領域に保存されます。

トランザクションコミットUNDOログ処理

トランザクションがコミットされると、InnoDB ストレージ エンジンは次の 2 つの処理を実行します。

  • 取り消しログは、後で削除するためにリストに入れられます。取り消しログとそれが配置されているページを最終的に削除できるかどうかは、削除スレッドによって決定されます。
  • UNDO ログが配置されているページが再利用できるかどうかを確認します。再利用できる場合は、次のトランザクションに割り当てます。

トランザクションがコミットされると、まず UNDO ログがリンク リストに入れられ、次に UNDO ページの使用済みスペースが 3/4 未満かどうかが判断されます。そうであれば、UNDO ページを再利用できることを意味し、新しい UNDO ログが現在の UNDO ログの後に記録されます。

元に戻すログは次のように分かれています:

  • 元に戻すログを挿入
  • 元に戻すログを更新

トランザクションの分離により、挿入の UNDO ログは他のトランザクションからは見えません。そのため、トランザクションがコミットされた後、パージ操作を必要とせずに UNDO ログを直接削除できます。

更新元に戻すログには、削除および更新操作によって生成された元に戻すログが記録されます。 UNDO ログは MVCC メカニズムを提供する必要がある可能性があるため、送信時に削除することはできません。

更新には 2 つのケースがあります。

  • 日付列が主キー列でない場合は、UNDO ログに逆の順序で更新方法が直接記録されます。つまり、更新は直接実行されます。
  • 主キーを更新する操作は、次の 2 つのステップに分けられます。
  • まず、元の主キーレコードを削除済みとしてマークし、TRX_UNDO_DEL_MARK_RECタイプのUNDOログを生成する必要があります。
  • その後、新しいレコードが挿入され、TRX_UNDO_INSERT_MARK_REC タイプの UNDO ログが生成されます。

InnoDB がパージを行う際、最初に履歴リストで UNDO ログを検索し、次に UNDO ページで UNDO ログを検索します。これにより、大量のランダム読み取り操作を回避でき、パージの効率が向上します。

MVCC (マルチバージョン同時実行制御)

MVCC は、実際には、レコードの各行の後に 2 つの非表示の列を追加して、作成バージョン番号と削除バージョン番号を記録します。各トランザクションが開始されると、一意の増分バージョン番号が付与されます。

MVCC は、REPEATABLE READ および READ COMMITTED 分離レベルでのみ機能します。コミットされていない読み取りではバージョンの問題は発生せず、シリアル化によってすべての読み取り行がロックされます。

例:

挿入操作: レコードの作成バージョン番号はトランザクションバージョン番号です

レコードを挿入すると、トランザクションIDは1とみなされ、作成バージョン番号も1になります。

id名前バージョンを作成バージョンを削除
1テスト1

更新操作: まず古いバージョン番号を削除済みとしてマークし、バージョン番号を現在のバージョン番号にして、新しいレコードを挿入します。

例えば、トランザクション2は名前フィールドを更新します
テーブルセット名を「新しいテスト」に設定し、ID を 1 に設定します。

元のレコードは削除対象としてマークされ、削除バージョンは2となり、新しいレコードが挿入され、作成バージョンは2となります。

id名前バージョンを作成バージョンを削除
1テスト1 2
1新しいテスト2


削除操作: トランザクションバージョンを削除バージョン番号として使用します

例えば、トランザクション3はレコードを削除します
id = 1 のテーブルから削除します。

id名前バージョンを作成バージョンを削除
1テスト2 3

クエリ操作

次の 2 つの条件を満たすレコードは、トランザクションによって照会できます。

  • InnoDBは、現在のトランザクションバージョンよりも前のバージョンのデータ行のみを検索します。
  • 削除された行のバージョンは未定義か、現在のバージョン番号より大きいため、トランザクションによって読み取られた行はトランザクションの開始前に削除されていないことが保証されます。

MVCCの利点: ロック競合を減らし、パフォーマンスを向上

バイナリログ

バイナリファイルの概念と機能

バイナリログは、MySQLデータベースを変更するすべての操作を記録します(データは変更されないため、SELECT、SHOWなどは除きます)。

バイナリ ファイルの主な機能は次のとおりです。

  • リカバリ: 一部のデータのリカバリにはバイナリログが必要です
  • レプリケーション: バイナリログをコピーして実行することで、リモートのMySQL (スレーブ) を別のMySQLデータベース (マスター) とリアルタイムで同期します。
  • 監査: ユーザーはバイナリ ログ内の情報を監査して、データベースにインジェクション攻撃があるかどうかを判断できます。

3つのバイナリファイル形式

MySQL 5.1 では、STATEMENT、ROW、MIX に設定できる binlog_format パラメータが導入されました。

  • ステートメント: バイナリ ファイルには、ログの論理 SQL ステートメントが記録されます。
  • ROW: テーブル行への変更を記録します。 ROW モードが設定されている場合は、同時実行性を高めるために InnoDB トランザクション分離レベルを READ_COMMITTED に設定できます。
  • MIX: MySQL はデフォルトで STATEMENT 形式を使用してバイナリ ファイルを記録しますが、場合によっては ROW が使用されます。考えられる状況は次のとおりです。
  • テーブルのストレージ エンジンは NDB であり、テーブルに対するすべての DML 操作は ROW 形式で実行されます。
  • UUID()、USER()、CURRENT_USER()、FOUND_ROWS()、ROW_COUNT() などの不確実な関数の使用
  • INSERT DELAYステートメントの使用
  • ユーザー定義関数の使用
  • 一時テーブルの使用

REDOログとバイナリファイルの違い

(バイナリ ファイルは、POINT-IN-TIME (PIT) リカバリとマスター/スレーブ レプリケーション環境の確立に使用されます。

  • バイナリ ファイルには、InnoDB や MyISAM などの他のストレージ エンジンのログを含む、MySQL データベースに関連するすべてのログ レコードが記録されます。 InnoDB ストレージ エンジンの REDO ログには、ストレージ エンジン自体に関連するトランザクション ログのみが記録されます。
  • 記録される内容は異なります。バイナリログファイルの記録形式を、ユーザーが STATEMENT、ROW、MIXED のいずれに設定しても、トランザクションの特定の操作内容が記録される、つまり論理ログとなります。 InnoDB ストレージ エンジンの REDO ログ ファイルには、各ページに対する物理的な変更が記録されます。
  • また、書き込み時間ページが異なります。バイナリ ログ ファイルは、トランザクションがコミットされる前にのみコミットされます。つまり、この時点でのトランザクションの大きさに関係なく、ディスクに書き込まれるのは 1 回だけです。ただし、トランザクション中は、REDO ログ エントリが継続的に REDO ログ ファイルに書き込まれます。

グループコミット

トランザクションが読み取り専用トランザクションでない場合は、トランザクションがコミットされるたびに fsync 操作を実行して、REDO ログがディスクに書き込まれたことを確認する必要があります。ただし、ディスク fsync のパフォーマンスには限界があります。ディスク fsync の効率を向上させるために、現在のデータベースではグループ コミット機能が提供されています。これにより、複数のトランザクション ログを一度に更新して、ファイルに確実に書き込むことができます。

InnoDB グループコミットの場合、2 段階の操作が実行されます。

  • メモリ内のトランザクションに対応する情報を変更し、ログをREDOログバッファに書き込む
  • fsync を呼び出すと、ログが REDO ログ バッファからディスクに書き込まれるようになります。

InnoDB1.2 より前では、バイナリ ファイルが開かれるとグループ コミット機能が失敗します。

バイナリ ファイルを開いた後の手順は次のとおりです。
1) トランザクションがコミットされると、InnoDBストレージエンジンは準備操作を実行します。
2) MySQLデータベースの上位層がバイナリファイルを書き込む
3) InnoDBはREDOログファイルにログを書き込む

a) メモリ内のトランザクションに対応する情報を変更し、ログをREDOログバッファに書き込みます。b) fsyncを呼び出して、ログがREDOログバッファからディスクに書き込まれるようにします。

MySQL データベースの上位バイナリ ファイルの書き込み順序が InnoDB トランザクションのコミット順序と一致するように、MySQL は内部的に prepare_commit_mutex ロックを使用します。そのため、他のトランザクションがステップ b) を実行しているときはステップ 3) のステップ a) を実行できず、行コミット機能が失敗します。

解決策はBLGC(バイナリロググループコミット)です

MySQL 5.6 BLGC 実装は 3 つの段階に分かれています。

  • フラッシュフェーズ: 各トランザクションのバイナリファイルをメモリに書き込む
  • 同期フェーズ: メモリ内のバイナリをディスクに更新します。キューに複数のトランザクションがある場合、バイナリ ログの書き込みを完了するには 1 つの fsync 操作のみが必要です。これが BLGC です。
  • コミットステージ: リーダーはストレージエンジン層のトランザクションコミットを順番に呼び出します。InnoDB はすでにグループコミットをサポートしているため、prepare_commit_mutex のロックによって発生するグループコミットの失敗の問題は解決されています。

MySQL redo ログ、undo ログ、binlog の詳細な説明に関するこの記事はこれで終わりです。MySQL redo ログ、undo ログ、binlog に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

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

<<:  HTML の色に関する参考資料

>>:  Element-UIの10の驚くべきトリックのまとめ

推薦する

txt ブックの内容を Web ページに表示するコード

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1...

HTML テーブルインライン形式の詳細な説明

インライン形式<colgroup>...</colgroup>属性名 属性値...

Webデザインの経験: Webコードを効率的に書く

本来、この第 7 章では、デザインにおけるレイヤーと空間テクニックについて深く議論するはずです。しか...

MySQLでヘッダー付きのCSVファイルをエクスポートする方法

公式ドキュメント http://dev.mysql.com/doc/refman/5.7/en/se...

Vueコンポーネント間のデータ共有の詳細な説明

目次1. プロジェクト開発において、コンポーネント間の最も一般的な関係は次の 2 つのタイプに分けら...

MySQL のストアド プロシージャを使用して 100 万件のレコードをすばやく生成する方法

序文テストを行う際、大量のデータによる負荷に耐えるプロジェクトの能力をテストするために、通常はテスト...

あまり多くのコードを書かずに、ハイパーリンクを使ってシンプルで美しいカスタムチェックボックスを実装できます。

今日ふと、HTML でチェックボックスのスタイルを変更できる範囲が限られていることと、チェックボック...

vue cli で env を使用するガイド

目次序文紹介-公式設定例序文vueCli を使用してプロジェクトを開発したことのある方は、少しがっか...

Dockerコンテナの紹介

1. 概要1.1 基本概念: Docker は、Go 言語をベースにしたオープンソースのアプリケーシ...

CSS3 で半透明の背景画像と不透明なコンテンツを実現する方法の例

以前のブログのログインページを作成していたときに、この問題に遭遇しました。突然、透明な背景画像と不透...

ドラッグ位置プレビューを実装するネイティブJS

この記事では、要素をドラッグするときにプレビューを追加する小さなデモを紹介します。効果は次のとおりで...

uniappのグローバル変数実装の詳細な説明

序文この記事では、uniapp グローバル変数の実装方法をいくつかまとめています。詳細な知識は、uV...

WeChatミニプログラムの基本チュートリアル:Echartの使用

序文まずは最終的な効果を見てみましょう。私が自分で作った小さなデモです。まずEChartsの公式サイ...

異なる列を持つテーブルのクエリ結果のSQLマージ操作

2 つの異なるテーブルをクエリするには、結果をマージする必要があります。たとえば、table1 の列...