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 ログ ファイルに書き込まれます。
1 番目と 4 番目のケースでは、必ず REDO ログの書き込みが実行されます。2 番目と 3 番目のケースの実行は、パラメータ インデックスの作成には、REDO ログの記録も必要です。 1.5 プロセス全体をやり直す例更新トランザクションを例に挙げます。
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 には、ログをディスクにフラッシュする戦略を制御するためのパラメータ
この方法では、システムがクラッシュしてもデータは失われませんが、各送信がディスクに書き込まれるため、IO パフォーマンスは低下します。
これは実際には、ユーザーが設計したバッファをメモリ内に保持することと同等であり、OS バッファ間のデータ転送が削減され、パフォーマンスが向上します。 システムがクラッシュした場合、ディスクが毎秒書き込まれると 1 秒分のデータが失われます。
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万件のレコードが挿入されます。 Ⅰ テスト> proc(100000) を呼び出す [2021-07-25 13:22:02] 27秒350ミリ秒で完了 最大27.35秒かかります。 Ⅱ テスト> @@global.innodb_flush_log_at_trx_commit=2 を設定します。 テスト> test_flush_log を切り捨てます。 テスト> proc(100000) を呼び出す [2021-07-25 13:27:33] 5秒774ミリ秒で完了 所要時間はわずか 5.774 秒で、パフォーマンスが大幅に向上します。 III テスト> @@global.innodb_flush_log_at_trx_commit=0 を設定します。 テスト> test_flush_log を切り捨てます。 テスト> proc(100000) を呼び出す [2021-07-25 13:30:34] 3秒537ミリ秒で完了 わずか 3.537 秒で、パフォーマンスが向上します。 明らかに、 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 つのプロトコルに従う必要があります。
最も厳格なのは完全同期です。fsync は、レコードが返される前にディスクにフラッシュされることを保証し、データのセキュリティを最大限に高めます。 2 番目のレベルは書き込み専用であり、レコードがオペレーティング システムに書き込まれることが保証されます。これにより、プロセスレベルのクラッシュが発生してもデータが存続できるようになります。 最も厳密でないのは no-sync で、これはレコードをメモリ バッファーに保持し、ファイル システムへの即時書き込みを保証しません。 ログの再送信を強制します。つまり、Force-log-at-commit では、トランザクションがコミットされたときにすべてのミニトランザクション ログをディスクにフラッシュする必要があります。 1.7 REDOログの書き込みプロセス上の図は、REDO ログがログ バッファに書き込まれる様子を示しています。各ミニトランザクションは、更新ステートメントなどの各 DML 操作に対応します。
1.8 ログブロックREDO ログはブロック単位で保存され、各ブロックのサイズは 512 バイトです。メモリ REDO ログ バッファ、オペレーティング システム バッファ、または REDO ログ ファイルのいずれの場合でも、512 バイトのブロックに格納されます。 各ログブロックヘッダーは次の4つの部分で構成されています。
1.9 ロググループログ グループは、同じサイズの複数の REDO ログ ファイルで構成される REDO ログのグループ化を表します。パラメータ このグループは論理的な概念ですが、グループ ディレクトリは変数 2 元に戻すログ 2.1 元に戻すログについて UNDO ログの目的は、データベース トランザクションの原子性を保証することです。 アトミック性とは、トランザクションが分割できない作業単位であり、トランザクション内のすべての操作が実行されるか、まったく実行されないかのいずれかであることを意味します。
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 パラメータを使用してロール 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 種類のチェックポイントがあります。
マスタースレッドのチェックポイント。マスター スレッドによって制御され、一定の割合のダーティ ページが 1 秒ごとまたは 10 秒ごとにディスクにフラッシュされます。 ダーティ ページのフラッシュは完了するまでに一定の時間がかかるため、各フラッシュが完了するたびに、レコード チェックポイントの場所が REDO ログにマークされます。 3.2 LS-N3.2.1 LSNコンセプト LSN はログの論理シーケンス番号と呼ばれ、InnoDB では 8 バイトを占めます。 LSN を通じて以下の情報を知ることができます。
LSN は次の 2 つの場所に存在します。
明らかに、ページ内の LSN 値が REDO ログ内の 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を実行すると、以下のようになります。
その後、別の削除ステートメントが実行され、LSN は 150 に増加します。 12:00:01 に、REDO ログ フラッシュ ルールがトリガーされます (ルールの 1 つは、innodb_flush_log_at_timeout によって制御されるデフォルトのログ フラッシュ頻度が 1 秒であることです)。この時点で、ディスク上の REDO ログ ファイル内の LSN は、バッファー内の REDO ログ内の LSN と同じに更新されるため、両方とも 150 になります。この時点で、図の ② の位置にある show engine innodb status を実行すると、結果は次のようになります。
その後、更新文が実行され、キャッシュ内の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 をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: CSS グリッドレイアウトを使用してレスポンシブな縦棒グラフを作成する方法
>>: HTMLページ埋め込み動画とJSコントロール切り替え動画例の詳しい説明
私がデザインした最初の Web ページは次のとおりです。 私はこの業界に7年間在籍し、プログラミング...
この記事では、参考までに、簡単な計算機を実装するためのJavaScriptの具体的なコードを紹介しま...
概要実際のビジネス シナリオ アプリケーションでは、ビジネス条件に基づいて対象データを取得およびフィ...
Apollo オープンソース アドレス: https://github.com/ctripcorp/...
[LeetCode] 184. 部門最高給与従業員テーブルにはすべての従業員が保存されます。すべて...
導入dockerコンテナとdocker-composeに基づいて、Linux環境でのdockerの基...
opencv2 の簡単なインストール: conda インストール --channel https:/...
目次1. MySQLレプリケーションプロセス2. MySQLの遅延問題の分析3. プロモーション期間...
目次ターゲット思考分析コード着陸要約するターゲットトークンの有効期限切れシナリオの処理トークンは、ユ...
序文ブロガーはアイデアIDEを使用しています。アイデア公式が最近サードパーティのアクティベーションサ...
1. ダウンロードリンクをダウンロードするダウンロードをクリックします。Oracle アカウントにロ...
SFTPの概念sftp は、安全なファイル転送プロトコルである Secure File Transf...
1. nginxシェルスクリプトを保存するフォルダを作成する /usr/local/タスク/ngin...
目次序文関数のオーバーロードマッピングタイプ部分的、読み取り専用、Null 可能、必須選択、記録除外...
MySQL テーブルでの接続方法は実は非常に簡単なので、ここではその特徴を簡単にリストします。テーブ...