ホームページ >データベース >mysql チュートリアル >MySQL ログの REDO ログと UNDO ログの知識ポイントは何ですか?
REDO LOG は REDO ログと呼ばれ、MySQL サーバーが予期せずクラッシュしたりダウンしたりしたときに、コミットされたトランザクションがディスクに永続化されていることを確認します (永続化)。
InnoDB は、ページ単位でレコードを操作します。追加、削除、変更、およびクエリは、ページ全体をバッファ プールにロードします (ディスク -> メモリ)。トランザクション内の変更操作は、データを直接変更しません。代わりに、メモリ内のバッファ プール内のデータが最初に変更され、バックグラウンド スレッドがそのデータを時々ディスクに非同期的に更新します。
バッファ プール: インデックスとデータの保存、読み取りと書き込みの高速化、メモリ内のデータ ページの直接操作が可能で、バッファ プール内のダーティ ページをディスクに書き込む専用のスレッドを備えています。
ディスク上のデータを直接変更しないのはなぜでしょうか?
ディスクデータを直接変更すると、ランダム IO となり、変更されたデータはディスク上の異なる場所に分散され、前後に検索する必要があるため、ヒット率が低く、消費量が多くなります。ページ全体がディスクに更新されず、使用率が低くなります;
対照的に、シーケンシャル IO では、ディスク データはディスクの一部に分散され、したがって、検索プロセスが省略され、シーク時間が節約されます。
バックグラウンド スレッドを使用して特定の頻度でディスクを更新すると、ランダム IO の頻度が減り、スループットが向上します。これがバッファ プールを使用する基本的な理由です。
メモリを変更してディスクに非同期同期する場合の問題:
バッファ プールはメモリ内の領域であるため、システムが予期せずクラッシュするとデータが失われる可能性があります。一部のダーティ データは時間内に更新されない可能性があります。ディスク、トランザクションの耐久性は保証されません。そこで、REDO ログが導入されました。データを変更すると、xx ページの xx オフセットが xx だけ変更されたことを示す追加のログが記録され、システムがクラッシュした場合、ログの内容に基づいて回復できます。
ログの書き込みとディスクの直接リフレッシュの違いは次のとおりです。ログの書き込みは追加書き込み、シーケンシャル IO で高速であり、書き込まれた内容は比較的小さいです。
REDO ログは 2 つの部分で構成されます。 :
REDO ログ バッファ (メモリ レベル、デフォルトは 16M、innodb_log_buffer_size パラメータで変更可能)
REDO ログ ファイル (永続、ディスク)レベル)
変更操作の一般的なプロセス:
ステップ 1: まず、元のデータをディスクからメモリ、データのメモリ コピーを変更し、ダーティ データを生成します
ステップ 2: REDO ログを生成し、REDO ログ バッファに書き込み、データの変更された値を記録します
ステップ 3 : デフォルトでは、トランザクションの送信後に REDO ログ バッファの内容が REDO ログ ファイルにフラッシュされ、REDO ログ ファイルに追加されて書き込みが行われます。
ステップ 4: 変更されたデータを定期的に更新します。ディスクへのメモリ (ここで話しているのは、バックグラウンド スレッドによって時間内にフラッシュされなかったダーティ データです)
一般的に先行書き込みログ (ログ前の永続性) と呼ばれるものは、データ ページを永続化する前に、データ ページを永続化するプロセスに移行し、対応するログ ページがメモリ内に永続化されます。
REDO ログの利点:
必ずしもではありませんが、REDO ログ バッファもメモリ内にあるため、これは REDO ログのフラッシュ戦略に依存します。トランザクションが送信された場合、REDO ログ バッファにはデータを REDO ログにリフレッシュする時間がありません。ファイルを永続化するため、この時点でダウンタイムが発生した場合でも、データは失われます。の解き方?スイープ戦略。
REDO ログ フラッシュ戦略
##値が 0 の場合:
値が 1 の場合:
#コミットするときは、REDO ログ バッファを REDO ログ ファイルにアクティブに更新する必要があります。中間では、トランザクションは失敗しても損失はなく、トランザクションの耐久性が真に保証されます。しかし効率は最悪です。値が 2 の場合: OS に基づいて決定されます。
トランザクションのパフォーマンスを向上させるために 0 または 2 に調整できますが、ACID の特性は失われます
innodb_log_group_home_dir: REDO ログ ファイル グループが配置されているパスを指定します。デフォルト値は ./ で、データベースのデータ ディレクトリにあることを意味します。 MySQL のデフォルトのデータ ディレクトリには ib_logfile0 と ib_logfile1 という名前の 2 つのファイルがあり、ログ バッファ内のログはデフォルトでこれら 2 つのディスク ファイルにフラッシュされます。
innodb_log_files_in_group: REDO ログ ファイルの数を指定します。命名方法は、ib_logfile0、iblogfile1... iblogfilen などです。デフォルトは 2 で、最大値は 100 です。
デフォルトでは、innodb_log_file_size のサイズは 48M に設定されており、これは単一 REDO ログ ファイルのサイズを設定するために使用されます。
Undo ログは、トランザクションの原子性と一貫性を確保するために使用されます。これには 2 つの機能があります: ① ロールバック操作の提供 ② マルチバージョン管理 MVVC
ロールバック操作
先ほどの REDO ログで述べたように、バックグラウンド スレッドはバッファ プール内のデータを時間から更新します。ただし、トランザクションの実行中にさまざまなエラー (ダウンタイム) が発生したり、ロールバック ステートメントが実行された場合は、アトミック性を確保するために以前にブラシ化された操作をロールバックする必要があります。アンドゥ ログはトランザクションのロールバックを提供します。
MVVC
読み取り行が他のトランザクションによってロックされている場合、アンドゥ ログから行レコードの以前のデータ バージョンを分析できるため、ユーザーはそれを前のデータに読み取ることができます。現在のトランザクション操作 - スナップショットの読み取り。
スナップショット読み取り: SQL によって読み取られるデータは履歴バージョンであり、ロックは必要ありません。通常の SELECT はスナップショット読み取りです。
元に戻すログのコンポーネント:
レコードを挿入するときは、ロールバック中にデータを削除できるように、レコードの主キー値を記録する必要があります。
レコードを更新するときは、変更された古い値をすべて記録し、ロールバック中に古い値に更新する必要があります。
削除する場合はすべてのレコードを記録する必要があり、ロールバックする場合はコンテンツのレコードを再挿入する必要があります。
選択操作ではアンドゥ ログは生成されません
InnoDB ストレージ エンジンでは、アンドゥ ログはロールバック セグメントを使用してロールバック セグメントが保存され、各ロールバック セグメントには 1024 個の UNDO ログ セグメントが含まれます。 MySQL5.5 以降では、ロールバック セグメントは合計 128 個になります。つまり、合計 128 * 1024 のアンドゥ操作を記録できます。
各トランザクションは 1 つのロールバック セグメントのみを使用し、1 つのロールバック セグメントは同時に複数のトランザクションを処理できます。
一部のトランザクションでは以前のデータ バージョンの読み取り (スナップショット読み取り) が必要な場合があるため、トランザクションのコミット直後に UNDO ログの削除を実行することはできません。したがって、トランザクションがコミットされると、アンドゥ ログはバージョン チェーンと呼ばれる連結リストに置かれ、アンドゥ ログが削除されるかどうかは、パージと呼ばれるスレッドによって判断されます。
元に戻すログは次のように分割されます:
元に戻すログの挿入
挿入操作の記録はトランザクション自体にのみ表示されるため、トランザクション自体には表示されません。他のトランザクションにそれを確認できるため (これはトランザクション分離の要件です)、トランザクションがコミットされた直後に UNDO ログを削除できます。パージ操作は必要ありません。
update undo log
Undo ログには、削除操作と更新操作に対して行われた変更が記録されます。 MVCC メカニズムをサポートするため、トランザクションがコミットされたときに、UNDO ログをすぐに削除することはできません。送信するときは、それを元に戻すログ リストに追加し、クリーンアップ スレッドが最終的な削除を実行するまで待ちます。
A=1とB=2の2つの値があり、トランザクションによってAが3に、Bが4に変更されるとします。変更プロセスが簡略化できます。 to:
1.begin
2. レコード A=1 を元に戻すログ
3.update A=3
4. レコード A=3 をやり直しログ
5. B=2 を記録して元に戻すログ
6.update B=4
7. B=4 を記録して再実行ログ
8. REDO ログをディスクに更新します
9.commit
begin; INSERT INTO user (name) VALUES ('tom');
データが挿入されるたびに、挿入操作の取り消しログが作成され、データのロールバック ポインタはこのログを指します。 UNDO ログには、UNDO ログのシリアル番号、挿入された主キーの列と値が記録されます。その後、ロールバックを実行するときに、主キーを介して対応するデータを直接削除できます。
UPDATE を実行すると:
更新操作を実行すると、主キーを更新する場合と更新しない場合の 2 つの状況を含む更新取り消しログが生成されます。主キーを更新しています。更新操作が実行されたとします。
UPDATE user SET name='Sun' WHERE id=1;
この時点で、新しい Undo ログ レコードがバージョン チェーンに追加され、その Undo no は 1 で、新しい undo ログ ロールバック ポインタは古い undo ログ (undo no=0) を指します。
ここで次のように仮定します:
UPDATE user SET id=2 WHERE id=1;
主キーを更新する操作では、元のデータの削除マークが最初に開かれ、データは実際には開かれません。この時点で削除されます。実際の削除はクリーニング スレッドの判断に委ねられ、後で新しいデータが挿入されます。新しいデータは元に戻すログも生成され、元に戻すログのシーケンス番号が増加します。
データを変更するたびに、元に戻すログが生成されることがわかります。レコードが複数回変更されると、複数の元に戻すログが生成されます。元に戻すログには、変更前のログとシーケンス番号が記録されます。各アンドゥ ログは増加しているため、ロールバックする場合は、シーケンス番号に従って前に進み、元のデータを見つけます。
上記の例に基づいて、ロールバックが実行されると仮定すると、対応するプロセスは次のようになります:
1. Pass undo no= Use id=2
2 のデータを削除するには 3 のログを使用し、id=1 のデータの削除マークを 0
3 に戻すには undo no=2 のログを使用します。 undo no=1 ログは、id=1 のデータの名前を Tom
4 に復元します。undo no=0 により id=1 のデータを削除します。 log
MySQL MVVC multi -version concurrency control
バイナリ ログ (更新ログとも呼ばれる) は、データベースに加えられた変更を記録するバイナリ形式のログ ファイルの一種です。 ..データベースによって実行されたすべての更新ステートメントが記録されます。
binlog の主なアプリケーション シナリオ:
データ復旧: MySQL が予期せず停止した場合、このログを通じて復元およびバックアップできます
データ レプリケーション: マスターはバイナリ ログをスレーブに渡し、マスターとスレーブ間のデータの整合性を実現します。
show variables like '%log_bin%';
bin ログ ログを表示します:
mysqlbinlog -v "/var/lib/mysql/binlog/xxx.000002"
ログ リカバリ データを使用します:
mysqlbinlog [option] filename|mysql –uuser -ppass;
バイナリ ログの削除:
PURGE {MASTER | BINARY} LOGS TO ‘指定日志文件名' PURGE {MASTER | BINARY} LOGS BEFORE ‘指定日期'
トランザクションの実行中、ログは最初に bin ログ キャッシュに書き込まれ、トランザクションが送信されると、binlog がキャッシュは binlog ファイルに書き込まれます。トランザクションのバイナリログは分割できないため、トランザクションがどれほど大きくても一度に書き込む必要があるため、システムはメモリのブロックをバイナリログキャッシュとして各スレッドに割り当てます。
InnoDB ストレージ エンジン レイヤーによって生成される REDO ログは、記録に使用される物理ログです。 「どのデータページにどのような変更が加えられましたか?」
binlog は論理ログであり、記録された内容はステートメントの元のロジックです。ID=2 の行の c フィールドに 1 を追加するのと似ています。サービス層に属します。
この 2 つの焦点も異なります。REDO ログは InnoDB にクラッシュから回復する機能を提供し、binlog は MySQL クラスター アーキテクチャのデータの一貫性を保証します。
Update ステートメントの実行中に、REDO ログと binlog の 2 つのログが記録されます。基本的なトランザクションに基づいて、REDO ログは更新ステートメントの実行中に継続的に書き込まれることができます。 binlog はトランザクションがコミットされたときにのみ書き込まれるため、REDO ログと binlog の書き込みタイミングは異なります。
REDO ログと binlog の間のロジックに一貫性がない場合、どのような問題が発生しますか?
update ステートメントを例に挙げます。id=2 のレコードのフィールド c の値が 0 であるとします。フィールド c の値を 1 に更新します。SQL ステートメントは update T set c=1 です。 ID=2。
実行プロセス中に REDO ログが書き込まれた後、binlog ログの書き込み中に例外が発生したとします。何が起こりますか?
binlog が存在するため、binlog ログの書き込み中に例外が発生します。 Write が異常中断されたため、対応する変更レコードがありません。したがって、binlog ログを使用してデータを復元する場合、またはスレーブがマスターの binlog を読み取る場合、この更新は省略されます。復元された行の c 値は 0 ですが、元のデータベースでは、REDO ログの復元により、c 値は 0 になります。この行の値は 1 です。最終的なデータは矛盾しています。
InnoDB ストレージ エンジンは、2 フェーズ コミット スキームを使用して、2 つのログ間の論理一貫性の問題に対処します。 2 段階の送信とは、REDO ログを準備とコミットの 2 つのステップに分割することを指します。
REDO ログと bin ログの最終コミットを結合させます。前述したように、トランザクションがコミットされるとき、デフォルトでは、コミットが成功する前に REDO ログを同期する必要があります。 bin Log には、データが失われないようにするこの機能もあります。
2 フェーズ コミットを使用した後、バイナリ ログの書き込み時に例外が発生しても影響はありません。これは、MySQL が REDO ログ ログに基づいてデータを復元するときに、 REDO ログがまだ準備段階にあり、対応する binlog ログがない場合、送信は失敗し、データはロールバックされます。
別のシナリオでは、REDO ログのコミット フェーズ中に例外が発生しました。トランザクションはロールバックされますか?
はトランザクションをロールバックせず、上の図に示されているロジックを実行します。REDO ログは準備段階にありますが、対応する binlog ログが見つかります。トランザクション ID. を使用するため、MySQL はトランザクションが完了したと判断し、トランザクションを送信してデータを復元します。
以上がMySQL ログの REDO ログと UNDO ログの知識ポイントは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。