MySQLのREDOログとUNDOログの詳細な説明

MySQLのREDOログとUNDOログの詳細な説明

MySQL ログ システムで最も重要なログは、REDO ログとアーカイブ ログです。後者は MySQL サーバー レイヤーのログであり、前者は InnoDB ストレージ エンジン レイヤーのログです。

1 回のやり直しログ

1.1 REDOログとは何か

REDO ログは、ACID の D であるトランザクションの耐久性を確保するために使用されます。

永続性: トランザクションがコミットされると、データベース内のデータに加えられた変更は永続的になり、その後のデータベース障害の影響を受けません。

REDO ログには、物理​​ REDO ログと論理 REDO ログの 2 種類があります。 InnoDB では、REDO ログはほとんどの場合物理ログであり、データ ページ (実際のデータ値) の物理的な変更を記録します。

1.2 REDOログの機能

REDO ログの主な機能は、データベースがクラッシュしたときにデータを回復することです。

1.3 REDOログの構成

REDOログは次の2つの部分に分けられます。

メモリに保存されたREDOログバッファとディスクに保存されたREDOログファイル

1.4 REDOログを記録するタイミング

データの変更が完了すると、ダーティ ページはディスクにフラッシュされる前に、REDO ログ バッファに書き込まれます。つまり、最初に変更してから書き込みます。

ダーティ ページ: ディスク上のデータと一致しないメモリ内のデータ (悪くない!)

以下の場合、REDO ログは REDO ログ バッファからディスク上の REDO ログ ファイルに書き込まれます。

  • 再実行ログ バッファのログが再実行ログ バッファの合計容量の半分を占めると、再実行ログはディスクに書き込まれます。
  • トランザクションがコミットされると、その REDO ログがディスクにフラッシュされ、データが失われることがなくなります (最も一般的なケース)。この時点では、メモリ内のすべてのダーティ ページがディスクに書き込まれていない可能性があることに注意してください。
  • バックグラウンド スレッドは定期的に更新され、1 秒ごとに REDO ログをディスクに書き込むバックグラウンド スレッドがあります。
  • MySQL がシャットダウンされると、REDO ログがディスクに書き込まれます。

1 番目と 4 番目のケースでは、必ず REDO ログの書き込みが実行されます。2 番目と 3 番目のケースの実行は、パラメータinnodb_flush_log_at_trx_commitの設定値に依存します。これについては、以下で詳しく説明します。

インデックスの作成には、REDO ログの記録も必要です。

1.5 プロセス全体をやり直す例

更新トランザクションを例に挙げます。

  • 元のデータをメモリに読み込み、データのメモリ内コピーを変更します。
  • REDO ログを生成し、REDO ログ バッファに書き込みます。REDO ログには、変更後の新しい値が格納されます。
  • トランザクションがコミットされると、REDO ログ バッファの内容が REDO ログ ファイルにフラッシュされます。
  • その後、メモリ内のダーティ ページは通常どおりディスクにフラッシュバックされます。

1.6 永続性の保証

1.6.1 コミット時のログ強制メカニズム

コミット時の強制ログ メカニズムは、トランザクションの永続性を実装します。メモリ内で操作する場合、ログは REDO ログ バッファに書き込まれます。ただし、トランザクションをコミットする前に、まずすべてのログをディスク上の REDO ログ ファイルに書き込む必要があります。

各ログが確実に REDO ログ ファイルに書き込まれるようにするには、fsync システム コールを使用して、OS バッファー内のログがディスク上のログ ファイルに完全に書き込まれるようにする必要があります。

fsync システム コール: 入力パラメータとして fd を渡す必要があります。その後、システム コールはこの fd が指すファイルに対して機能します。 fsync は、ディスク書き込み操作が完了するまで返されないことを保証します。そのため、プログラムがこの関数を使用して正常に返された場合、データはディスクに安全に書き込まれたことを意味します。したがって、fsync はデータベースなどのプログラムに適しています。

1.6.2 innodb_flush_log_at_trx_commit パラメータ

InnoDB には、ログをディスクにフラッシュする戦略を制御するためのパラメータinnodb_flush_log_at_trx_commitが用意されています。

  • innodb_flush_log_at_trx_commit値が 1 (デフォルト) の場合。トランザクションがコミットされるたびに、ログ バッファー内のログを OS バッファーに書き込み、それをディスクに書き込むために fsync() を呼び出す必要があります。

この方法では、システムがクラッシュしてもデータは失われませんが、各送信がディスクに書き込まれるため、IO パフォーマンスは低下します。

  • innodb_flush_log_at_trx_commit値が 0 の場合。トランザクションがコミットされると、ログ バッファは OS バッファに書き込まれません。代わりに、ログ バッファは 1 秒ごとに OS バッファに書き込まれ、fsync() が呼び出されてディスク上のログ ファイルに書き込まれます。

これは実際には、ユーザーが設計したバッファをメモリ内に保持することと同等であり、OS バッファ間のデータ転送が削減され、パフォーマンスが向上します。

システムがクラッシュした場合、ディスクが毎秒書き込まれると 1 秒分のデータが失われます。

  • innodb_flush_log_at_trx_commit値が 2 の場合。各コミットは OS バッファにのみ書き込まれ、その後 fsync() が 1 秒ごとに呼び出され、OS バッファ内のログがディスク上のログ ファイルに書き込まれます。

OS バッファ内のログをディスク上のログ ファイルに書き込むために、毎秒 fsync() を呼び出しますが、他の時間に fsync が呼び出されなくても、データは徐々に自律的にディスクに入力されます。したがって、システムクラッシュが発生した場合、2 番目のケースと比較して失われるデータが少なくなります。

しかし同時に、各送信は OS バッファーに書き込まれるため、パフォーマンスは 2 番目のケースよりも悪くなりますが、最初のケースよりは向上します。

どちらの場合でも

1.6.3 小規模なパフォーマンステスト

オプション間のパフォーマンスの差は大きいです。簡単なテストをしてみましょう。

#テスト テーブルを作成します。存在する場合はテーブルを削除します。test_flush_log;
テーブル test_flush_log(id int,name char(50)) を作成します。engine=innodb;

# 指定された数の行をテスト テーブルに挿入するストアド プロシージャを作成します。drop procedure if exists proc;
区切り文字 $$
プロシージャ proc(i int) を作成する
始める
    s int をデフォルト 1 として宣言します。
    c char(50)をデフォルトとして宣言します。repeat('a',50);
    s<=i の場合
        トランザクションを開始します。
        test_flush_logに値(null,c)を挿入します。
        専念;
        s=s+1 と設定します。
    終了しながら;
終わり$$
区切り文字 ;

以下に10万件のレコードが挿入されます。

innodb_flush_log_at_trx_commit値が1の場合

テスト> proc(100000) を呼び出す
[2021-07-25 13:22:02] 27秒350ミリ秒で完了

最大27.35秒かかります。

innodb_flush_log_at_trx_commit値が2の場合

テスト> @@global.innodb_flush_log_at_trx_commit=2 を設定します。    
テスト> test_flush_log を切り捨てます。

テスト> proc(100000) を呼び出す
[2021-07-25 13:27:33] 5秒774ミリ秒で完了

所要時間はわずか 5.774 秒で、パフォーマンスが大幅に向上します。

III innodb_flush_log_at_trx_commit値が0の場合

テスト> @@global.innodb_flush_log_at_trx_commit=0 を設定します。
テスト> test_flush_log を切り捨てます。

テスト> proc(100000) を呼び出す
[2021-07-25 13:30:34] 3秒537ミリ秒で完了

わずか 3.537 秒で、パフォーマンスが向上します。

明らかに、 innodb_flush_log_at_trx_commit値が 1 の場合、パフォーマンスは非常に低くなります。これを 0 と 2 に変更すると、パフォーマンスが大幅に向上します。0 は高速ですが、2 とそれほど変わりません。

0 と 2 に変更するとパフォーマンスが大幅に向上しますが、セキュリティに重大な影響を及ぼします。ストアド プロシージャを変更し、トランザクションの作成と送信をループの外側に置き、統一された方法で送信して、IO 頻度を減らすことができます。

プロシージャが存在する場合はプロシージャを削除します。
区切り文字 $$
プロシージャ proc(i int) を作成する
始める
    s int をデフォルト 1 として宣言します。
    c char(50)をデフォルトとして宣言します。repeat('a',50);
    トランザクションを開始します。
    s<=i の場合
        test_flush_log に値(null,c) を挿入します。
        s=s+1 と設定します。
    終了しながら;
    専念;
終わり$$
区切り文字 ;

1.6.4 ミニトランザクション

ミニトランザクションは、InnoDB が小さなトランザクションを処理するために使用するメカニズムです。同時トランザクション操作やデータベース例外が発生した場合でも、データ ページ内のデータの一貫性を確保できます。

ミニトランザクションは次の 3 つのプロトコルに従う必要があります。

  • ルールを修正します。書き込み時には排他ロックを使用し、読み取り時には共有ロックを使用する必要があります。とにかく、ロックする必要があります。
  • 先行書き込みログ。先行書き込みログ (WAL)データを永続化する前に、まずログをメモリ内に永続化する必要があります。各ページには LSN (ログ シーケンス番号) があります。データをディスクに書き込む前に、シーケンス番号が LSN より小さいメモリ内のログをまずディスクに書き込む必要があります。 WALは3つの永続モードを提供する

最も厳格なのは完全同期です。fsync は、レコードが返される前にディスクにフラッシュされることを保証し、データのセキュリティを最大限に高めます。

2 番目のレベルは書き込み専用であり、レコードがオペレーティング システムに書き込まれることが保証されます。これにより、プロセスレベルのクラッシュが発生してもデータが存続できるようになります。

最も厳密でないのは no-sync で、これはレコードをメモリ バッファーに保持し、ファイル システムへの即時書き込みを保証しません。

ログの再送信を強制します。つまり、Force-log-at-commit では、トランザクションがコミットされたときにすべてのミニトランザクション ログをディスクにフラッシュする必要があります。

1.7 REDOログの書き込みプロセス

上の図は、REDO ログがログ バッファに書き込まれる様子を示しています。各ミニトランザクションは、更新ステートメントなどの各 DML 操作に対応します。

  • 各データの変更はミニトランザクションのプライベート バッファーに書き込まれます。
  • 更新ステートメントが完了すると、REDO ログがミニトランザクション プライベート バッファからメモリ内のパブリック ログ バッファに書き込まれます。
  • 外部トランザクションがコミットされると、REDO ログ バッファが REDO ログ ファイルにフラッシュされます。

1.8 ログブロック

REDO ログはブロック単位で保存され、各ブロックのサイズは 512 バイトです。メモリ REDO ログ バッファ、オペレーティング システム バッファ、または REDO ログ ファイルのいずれの場合でも、512 バイトのブロックに格納されます。

各ログブロックヘッダーは次の4つの部分で構成されています。

  • log_block_hdr_no: (4 バイト) REDO ログ バッファ内のログ ブロックの場所 ID。
  • log_block_hdr_data_len: (2 バイト) このログ ブロックに記録されるログのサイズ。ログ ブロックがいっぱいになると、0x200 となり、512 バイトを意味します。
  • log_block_first_rec_group: (2 バイト) ログ ブロック内の最初のログの開始オフセット位置。
  • lock_block_checkpoint_no: (4 バイト) チェックポイント情報が書き込まれる場所。

1.9 ロググループ

ログ グループは、同じサイズの複数の REDO ログ ファイルで構成される REDO ログのグループ化を表します。パラメータinnodb_log_files_groupによって決定され、デフォルトは 2 です。
[外部リンク画像転送に失敗しました。ソースサイトには盗難防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-h01w68EG-1627284031849)(G:\markdown\MySQL\image-20210726131134489.png)].png)]

このグループは論理的な概念ですが、グループ ディレクトリは変数innodb_log_group_home_dirによって定義できます。REDO ログ ファイルは、デフォルトでは datadir の下にあるこのディレクトリに配置されます。

2 元に戻すログ

2.1 元に戻すログについて

UNDO ログの目的は、データベース トランザクションの原子性を保証することです。

アトミック性とは、トランザクションが分割できない作業単位であり、トランザクション内のすべての操作が実行されるか、まったく実行されないかのいずれかであることを意味します。

  • EDO ログはトランザクションの動作を記録し、一貫性を確保してデータを「やり直す」ことができます。しかし、トランザクションをロールバックする必要がある場合があり、この場合には UNDO ログが必要になります。レコードを変更する場合、データの古いバージョンを記録する UNDO ログを生成する必要があります。古いトランザクションがデータを読み取る必要がある場合は、UNDO チェーンをたどって、可視性を満たすレコードを見つけることができます。
  • UNDO ログは通常、論理ログの形式で存在します。レコードが削除されると、元に戻すログによって対応する挿入レコードが生成され、その逆も同様であると想定できます。レコードが更新されると、カウンター更新レコードが生成されます。
  • UNDO ログはセグメントに記録されます。各 UNDO 操作は、記録時に 1 つの UNDO ログ セグメントを占有します。
  • UNDO ログも永続的な保護を実現する必要があるため、UNDO ログは REDO ログも生成します。

UNDO ログは通常、論理ログの形式で存在します。レコードが削除されると、元に戻すログによって対応する挿入レコードが生成され、その逆も同様であると想定できます。レコードが更新されると、カウンター更新レコードが生成されます。

UNDO ログはセグメントに記録されます。各 UNDO 操作は、記録時に 1 つの UNDO ログ セグメントを占有します。

UNDO ログも永続的な保護を実現する必要があるため、UNDO ログは REDO ログも生成します。

2.2 UNDOログセグメント

同時操作中にそれぞれの UNDO ログを書き込むときにトランザクションが競合しないようにするために、nnodb は UNDO ログをセグメントで管理します。ロールバック セグメントはロールバック セグメントと呼ばれ、各ロールバック セグメントには 1024 個の UNDO ログ セグメントがあります。 MySQL バージョン 5.5 以降では、128 個のロールバック セグメントがサポートされており、128*1024 個の操作を保存できます。innodb_undo_logs パラメータを使用してロールinnodb_undo_logsセグメントを定義することもできます。

2.3 パージ

MySQL は、クラスター化インデックス列の操作においてこのように設計されています。削除文の場合

a = 1 の t から削除

にクラスター化インデックス (主キー) がある場合、実際の削除は実行されません。代わりに、主キー列が 1 に等しいレコードの削除フラグが 1 に設定され、レコードは B+ ツリーに保存されます。同様に、更新操作の場合、レコードを直接更新するのではなく、古いレコードが削除済みとしてマークされ、新しいレコードが作成されます。

では、古いバージョンのレコードは実際にいつ削除されるのでしょうか?

InnoDB は、UNDO ログを使用して古いバージョンを削除します。この操作はパージ操作と呼ばれます。 InnoDB はパージ スレッドを開いてパージ操作を実行し、パージ スレッドの数を制御できます。各パージ スレッドは 10 秒ごとにパージ操作を実行します。

InnoDB の UNDO ログ設​​計

複数のトランザクションの UNDO ログが 1 ページに存在することが可能であり、UNDO ログの保存順序は任意です。 InnoDB は、トランザクションがコミットされた順序で UNDO ログを接続する履歴リンク リストを維持します。

パージ処理中、InnoDB ストレージ エンジンはまず履歴リストから消去する必要がある最初のレコード (ここでは trx1) を見つけます。クリーンアップ後、InnoDB ストレージ エンジンは trx1 がある Undo ページで消去できるレコードを探し続けます。ここで、トランザクション trx3 が見つかり、次に trx5 が見つかりますが、trx5 は他のトランザクションによって参照されており、消去できないことがわかります。そのため、履歴リストを再度検索し、最後のレコードが trx2 であることがわかります。次に、trx2 がある Undo ページが見つかり、trx6 と trx4 が順番にクリーンアップされます。Undo ページ 2 のすべてのレコードがクリーンアップされたため、Undo ページは再利用できます。

InnoDB ストレージ エンジンの設計モードは、最初に履歴リストで UNDO ログを検索し、次に Undo ページで UNDO ログを検索することで、大量のランダム読み取り操作を回避し、パージの効率を向上させます。

3 InnoDB リカバリ操作

3.1 データページのフラッシュルールとチェックポイント

ディスクにフラッシュされていないメモリ (バッファ プール) 内のデータは、ダーティ データと呼ばれます。データとログは両方ともページの形式で存在するため、ダーティ ページはダーティ データとダーティ ログを表します。

InnoDB では、チェックポイントはデータをディスクにフラッシュするための唯一のルールです。チェックポイントがトリガーされると、メモリ内のダーティ データがディスクにフラッシュされます。

InnoDB ストレージ エンジンには 2 種類のチェックポイントがあります。

  • シャープ チェックポイント: REDO ログ ファイルを再利用する場合 (たとえば、ログ ファイルを切り替える場合)、REDO ログに記録されているすべてのダーティ データがディスクにフラッシュされます。
  • ファジー チェックポイント: すべてのダーティ ログをディスクにフラッシュするのではなく、ログの小さな部分だけが一度にディスクにフラッシュされます。このチェックポイントは、次の状況でトリガーされます。

マスタースレッドのチェックポイント。マスター スレッドによって制御され、一定の割合のダーティ ページが 1 秒ごとまたは 10 秒ごとにディスクにフラッシュされます。
flush_lru_list チェックポイント。 MySQL 5.6 以降では、innodb_page_cleaners 変数を使用して、ダーティ ページをディスクにフラッシュするページ クリーナー スレッドの数を指定できます。このスレッドの目的は、lru リストに使用可能な空きページがあることを確認することです。
非同期/同期フラッシュチェックポイント。同期または非同期のディスク フラッシュ。たとえば、まだディスクにフラッシュされていないダーティ ページが多数ある場合 (多すぎるかどうかは比率によって制御されます)、それらを同期的にディスクにフラッシュすることを選択しますが、これはめったに発生しません。ダーティ ページがそれほど多くない場合は、それらを非同期的にディスクにフラッシュすることを選択できます。ダーティ ページがほとんどない場合は、一時的にダーティ ページをディスクにフラッシュしないようにすることができます。
ダーティ ページのチェックポイントが多すぎます。ダーティ ページが多すぎてキャッシュ内に十分な空き領域がないと、チェックポイントがトリガーされます。過剰比率は変数 innodb_max_dirty_pages_pct によって制御されます。MySQL 5.6 のデフォルト値は 75 です。これは、ダーティ ページがバッファー プールの 75% を占めると、一部のダーティ ページが強制的にディスクにフラッシュされることを意味します。

ダーティ ページのフラッシュは完了するまでに一定の時間がかかるため、各フラッシュが完了するたびに、レコード チェックポイントの場所が REDO ログにマークされます。

3.2 LS-N

3.2.1 LSNコンセプト

LSN はログの論理シーケンス番号と呼ばれ、InnoDB では 8 バイトを占めます。

LSN を通じて以下の情報を知ることができます。

  • データページのバージョン情報。
  • 書き込まれたログの合計量。
  • チェックポイントの場所。

LSN は次の 2 つの場所に存在します。

  • REDO ログ レコード内。
  • 各データ ページのヘッダーには、このページの最終的な LSN 値を記録するための変数fil_page_lsnがあります。

明らかに、ページ内の LSN 値が REDO ログ内の LSN 値よりも小さい場合、データが失われていることを意味します。

show engine innodb statusを使用すると、現在の InnoDB 操作情報を表示できます。この情報には、lsn に関するレコードを含む列ログがあります。

  • ログ シーケンス番号は、現在の REDO ログ (バッファー内) 内の LSN を記録します。
  • フラッシュされたログは、ディスクにフラッシュされた REDO ログ ファイル内の LSN です。
  • フラッシュされたページは、ディスク データ ページにフラッシュされた LSN です。
  • 最後のチェックポイントは、最後のチェックポイントの場所の LSN です。

3.2.2 LSN処理フロー

(1)まず、メモリ内のデータページを変更し、データページ内のLSNを記録します。これをdata_in_buffer_lsnと呼びます。

(2)データページが変更されると(ほぼ同時に)、REDOログがREDOログインバッファに書き込まれ、対応するLSNが記録されます。これは一時的にredo_log_in_buffer_lsnと呼ばれます。

(3)ログをバッファに書き込んだ後、いくつかのログフラッシュルールがトリガーされると、REDOログはディスク上のREDOログファイルにフラッシュされ、対応するLSNがファイルに記録されます。このファイルは一時的にredo_log_on_disk_lsnと呼ばれます。

(4) データページは永久にメモリ内に留まることはできません。場合によっては、チェックポイントがトリガーされ、メモリ内のダーティページ(データダーティページとログダーティページ)がディスクにフラッシュされます。そのため、チェックポイントダーティページフラッシュが完了すると、チェックポイントのLSN位置がREDOログに記録され、一時的にcheckpoint_lsnと呼ばれます。

(5) チェックポイントの位置を素早く記録するには、フラグを設定するだけで済みます。ただし、データページのフラッシュは高速ではない場合があります。たとえば、このチェックポイントではフラッシュするデータページが多数あります。つまり、すべてのデータ ページをフラッシュするには、ある程度の時間がかかります。途中でフラッシュされた各データ ページには、現在のページの LSN が記録され、一時的に data_page_on_disk_lsn と呼ばれます。

上の図では、上から下の水平線は、タイムライン、バッファー内のデータ ページに記録された LSN (data_in_buffer_lsn)、ディスク上のデータ ページに記録された LSN (data_page_on_disk_lsn)、バッファー内の REDO ログに記録された LSN (redo_log_in_buffer_lsn)、ディスク上の REDO ログ ファイルに記録された LSN (redo_log_on_disk_lsn)、およびチェックポイントに記録された LSN (checkpoint_lsn) を表しています。

開始時 (12:0:00) にすべてのログ ページとデータ ページがディスクにフラッシュされ、チェックポイント LSN が記録されているものとします。この時点で、それらの LSN は完全に一貫しています。

トランザクションが開始され、更新操作がすぐに実行されると仮定します。実行が完了すると、バッファ内のデータ ページと REDO ログの両方に更新された LSN 値が記録されます。この値は 110 であると想定されます。この時、各LSNの値、つまり図の①の位置ステータスを確認するためにshow engine innodb statusを実行すると、以下のようになります。

ログシーケンス番号(110) > ログがフラッシュされた場所(100) = フラッシュされたページ数 = 最後のチェックポイント

その後、別の削除ステートメントが実行され、LSN は 150 に増加します。 12:00:01 に、REDO ログ フラッシュ ルールがトリガーされます (ルールの 1 つは、innodb_flush_log_at_timeout によって制御されるデフォルトのログ フラッシュ頻度が 1 秒であることです)。この時点で、ディスク上の REDO ログ ファイル内の LSN は、バッファー内の REDO ログ内の LSN と同じに更新されるため、両方とも 150 になります。この時点で、図の ② の位置にある show engine innodb status を実行すると、結果は次のようになります。

ログシーケンス番号(150) = ログがフラッシュされた最大数 > ページがフラッシュされた最大数(100) = 最後のチェックポイント

その後、更新文が実行され、キャッシュ内のLSNは図の③の位置である300に増加します。

その後、チェックポイントが発生したと仮定します。これは、図の ④ の位置です。前述のように、チェックポイントはデータ ページとログ ページのディスクへのフラッシュをトリガーしますが、完了するまでに一定の時間がかかります。したがって、データ ページのフラッシュが完了する前は、チェックポイントの LSN は前のチェックポイントの LSN のままですが、この時点でディスク上のデータ ページとログ ページの LSN は増加しています。つまり、

ログシーケンス番号 > ログがフラッシュされた場所とページがフラッシュされた場所 > 最後のチェックポイント

ただし、ログのフラッシュはデータのフラッシュよりも速い場合もあれば、等しい場合や遅い場合もあるため、フラッシュされるログのサイズとフラッシュされるページのサイズを特定することはできません。ただし、チェックポイント メカニズムにより、データ ディスクのフラッシュがログ ディスクのフラッシュよりも遅くなるのを防ぎます。データ ディスクのフラッシュ速度がログ ディスクのフラッシュ速度を超えると、ログ ディスクのフラッシュの進行がデータ ディスクのフラッシュの進行を超えるまで、データ ディスクのフラッシュは一時的に停止されます。

データ ページとログ ページがディスクにフラッシュされると、つまり位置 ⑤ に到達すると、すべての LSN は 300 になります。

時間が経つと、図の⑥の位置である12:00:02に、ログフラッシュルールが再度トリガーされます。ただし、この時点ではバッファ内のログLSNとディスク内のログLSNが一致しているため、ログフラッシュは実行されません。つまり、この時点でshow engine innodb statusを実行すると、すべてのLSNが等しくなります。

次に挿入文が実行され、バッファ内のLSNが図の⑦の位置である800に増加したとします。このとき、各種LSNのサイズは位置①と同じになります。

次にコミットアクション(位置 ⑧)が実行されます。デフォルトでは、コミット アクションはログのフラッシュをトリガーしますが、データのフラッシュはトリガーしません。そのため、show engine innodb status の結果は次のようになります。

ログシーケンス番号 = フラッシュされたログ > フラッシュされたページ = 最後のチェックポイント

最後に、時間が経つと、図の⑨の位置であるチェックポイントが再び現れます。ただし、チェックポイントが発生する前にログの LSN が同期されているため、このチェックポイントではログ フラッシュはトリガーされません。データがディスクにフラッシュされる速度が非常に速く、瞬時に完了し、ステータスの変更をキャプチャできないと仮定します。この場合、show engine innodb status の結果は、すべての LSN が等しいということになります。

3.3 InnoDB のリカバリ動作

InnoDB を起動すると、前回の終了の理由に関係なく、リカバリ操作が実行されます。

チェックポイントは、ディスク上のデータ ページの LSN が完全にフラッシュされたことを示します。そのため、リカバリ中は、チェックポイントから始まるログ部分のみを復元する必要があります。たとえば、最後のチェックポイントの LSN が 10000 で、トランザクションがコミットされた状態のときにデータベースがクラッシュした場合などです。データベースが起動すると、ディスク上のデータ ページの LSN がチェックされます。データ ページの LSN がログ内の LSN より小さい場合、チェックポイントからリカバリが開始されます。

クラッシュ前にチェックポイントがディスクにフラッシュされており、データ ページのフラッシュの進行がログ ページのフラッシュの進行を上回るという別の状況もあります。このとき、コンピュータがクラッシュすると、データ ページに記録された LSN がログ ページの LSN よりも大きくなります。この状況は、再起動の回復プロセス中にチェックされます。このとき、ログの進行状況を超えた部分はやり直されません。これは、それ自体が、実行されたことをやり直す必要がないことを意味するためです。

さらに、トランザクション ログはべき等性があるため、同じ結果を生成する複数の操作はログに 1 回だけ記録されます。ただし、バイナリ ログはべき等ではありません。複数の操作が記録されます。リカバリ中は、バイナリ ログ内のレコードが複数回実行されるため、処理速度が大幅に低下します。たとえば、あるレコードの id の初期値が 2 で、更新によって値が 3 に設定され、その後再び 2 に設定された場合、トランザクション ログには変更されていないページが記録されるため、リカバリは必要ありません。ただし、バイナリには 2 つの更新操作が記録され、リカバリ時にもこの 2 つの更新操作が実行されるため、トランザクション ログのリカバリよりも遅くなります。

これで、MySQL の redo ログと undo ログに関するこの記事は終了です。MySQL の redo ログと undo ログの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

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

<<:  CSS グリッドレイアウトを使用してレスポンシブな縦棒グラフを作成する方法

>>:  HTMLページ埋め込み動画とJSコントロール切り替え動画例の詳しい説明

推薦する

ブログデザイン ウェブデザイン デビュー

私がデザインした最初の Web ページは次のとおりです。 私はこの業界に7年間在籍し、プログラミング...

JavaScript ベースのシンプルな計算機の実装

この記事では、参考までに、簡単な計算機を実装するためのJavaScriptの具体的なコードを紹介しま...

MySQL 完全崩壊: クエリフィルタ条件の詳細な説明

概要実際のビジネス シナリオ アプリケーションでは、ビジネス条件に基づいて対象データを取得およびフィ...

CentOS7 で docker を使用して Apollo 構成センターをデプロイする実装

Apollo オープンソース アドレス: https://github.com/ctripcorp/...

LeetCode の SQL 実装 (184. 部門内で最も高い給与)

[LeetCode] 184. 部門最高給与従業員テーブルにはすべての従業員が保存されます。すべて...

Nginxはリバースプロキシを使用して負荷分散プロセス分析を実装します

導入dockerコンテナとdocker-composeに基づいて、Linux環境でのdockerの基...

UbuntuでOpenCVをコンパイルしてインストールする方法

opencv2 の簡単なインストール: conda インストール --channel https:/...

MySQL のレイテンシ問題とデータフラッシュ戦略プロセスの分析

目次1. MySQLレプリケーションプロセス2. MySQLの遅延問題の分析3. プロモーション期間...

VUEトークンの無効化プロセスの詳細な説明

目次ターゲット思考分析コード着陸要約するターゲットトークンの有効期限切れシナリオの処理トークンは、ユ...

ローカルアイデアアクティベーションサーバーの構築に関する詳細なチュートリアル

序文ブロガーはアイデアIDEを使用しています。アイデア公式が最近サードパーティのアクティベーションサ...

写真とテキストによる MySQL 8.0.21 インストール チュートリアル

1. ダウンロードリンクをダウンロードするダウンロードをクリックします。Oracle アカウントにロ...

Linux sftp コマンドの使用法

SFTPの概念sftp は、安全なファイル転送プロトコルである Secure File Transf...

一般的な nginx コマンドをシェル スクリプトに組み込む方法の詳細な説明

1. nginxシェルスクリプトを保存するフォルダを作成する /usr/local/タスク/ngin...

知らないかもしれない実用的なTypeScriptのヒント

目次序文関数のオーバーロードマッピングタイプ部分的、読み取り専用、Null 可能、必須選択、記録除外...

MySQLでテーブルを接続するいくつかの方法

MySQL テーブルでの接続方法は実は非常に簡単なので、ここではその特徴を簡単にリストします。テーブ...