推奨学習: mysql ビデオ チュートリアル
REDO LOG は、REDO ログと呼ばれます。 MySQL サーバーが予期せずクラッシュまたはダウンした場合でも、送信されたトランザクションはディスクに保持されることが保証されます (永続性)。
InnoDB は、ページ単位でレコードを操作します。追加、削除、変更、およびクエリは、ページ全体をバッファ プールにロードします (ディスク -> メモリ)。トランザクション内の変更操作は、データを直接変更しません。代わりに、メモリ内のバッファ プール内のデータが最初に変更され、バックグラウンド スレッドがそのデータを時々ディスクに非同期的に更新します。
バッファ プール: インデックスとデータの保存、読み取りと書き込みの高速化、メモリ内のデータ ページの直接操作が可能で、バッファ プール内のダーティ ページをディスクに書き込む専用のスレッドを備えています。
ディスク上のデータを直接変更しないのはなぜでしょうか?
ディスクデータを直接変更すると、ランダム IO となり、変更されたデータはディスク上の異なる場所に分散され、前後に検索する必要があるため、ヒット率が低く、消費量が多くなります。ページ全体がディスクに更新されず、使用率が低くなります;
対照的に、シーケンシャル IO では、ディスク データはディスクの一部に分散されます。 , そのため、検索プロセスが省略され、シーク時間が節約されます。
バックグラウンド スレッドを使用して特定の頻度でディスクを更新すると、ランダム IO の頻度が減り、スループットが向上します。これがバッファ プールを使用する基本的な理由です。
メモリを変更してディスクに非同期同期する場合の問題:
バッファ プールはメモリ内の領域であるため、システムが予期せずクラッシュするとデータが失われる可能性があります。一部のダーティ データは時間内に更新されない可能性があります。ディスク、トランザクションの耐久性は保証されません。そこで、REDO ログが導入されました。データを変更すると、xx ページの xx オフセットが xx だけ変更されたことを示す追加のログが記録され、システムがクラッシュした場合、ログの内容に基づいて回復できます。
ログの書き込みとディスクの直接リフレッシュの違いは次のとおりです。ログの書き込みは追加書き込み、シーケンシャル IO で高速であり、書き込まれた内容は比較的小さいです。
REDO ログは 2 つの部分で構成されます。 :
変更操作の一般的なプロセス:
ステップ 1: まず、元のデータをディスクからメモリに読み取り、データのメモリ コピーを変更して、ダーティ データ
ステップ 2: REDO ログを生成し、REDO ログ バッファに書き込みます。記録されるのは、データの変更された値です。
ステップ 3: デフォルトでは、トランザクション後がコミットされると、REDO ログ バッファは次のようになります。内容が REDO ログ ファイルに更新され、REDO ログ ファイルが追加されます。
ステップ 4: メモリ内の変更されたデータを定期的にディスクに更新します (ここでは、バックグラウンド スレッドによって時間内に更新されなかったデータ (ディスク上のダーティ データ) について話している)
いわゆる先行書き込みログ (ログ前の永続性) とは、対応するログ ページを永続化することを指します。データページを永続化する前のメモリ。
REDO ログの利点:
REDO ログはトランザクションの耐久性を保証できますか?
必ずしもではありませんが、REDO ログ バッファもメモリ内にあるため、これは REDO ログのフラッシュ戦略によって異なります。トランザクションが送信された場合、REDO ログ バッファにはデータを REDO ログにリフレッシュする時間がありません。ファイルを永続化するため、この時点でダウンタイムが発生した場合でも、データは失われます。の解き方?スイープ戦略。
InnoDB は、REDO ログ バッファーが REDO ログ ファイルにフラッシュされるタイミングを制御するための innodb_flush_log_at_trx_commit パラメータの 3 つの戦略を提供します。 0: バックグラウンド スレッドを開始し、1 秒ごとにディスクに更新します。トランザクションを送信するときに更新する必要はありません。
1秒間隔のため、最悪の場合1秒分のデータが失われます。
値が 1 の場合:コミット時には、REDOログバッファをREDOログファイルに積極的にリフレッシュする必要があり、途中でクラッシュしても、トランザクションは損失なく失敗し、トランザクションの耐久性が真に保証されます。しかし効率は最悪です。
値が 2 の場合: OS に基づいて決定されます。
トランザクションのパフォーマンスを向上させるために 0 または 2 に調整できますが、ACID 機能は失われます
Undo ログは、トランザクションの原子性と一貫性を確保するために使用されます。これには 2 つの機能があります: ① ロールバック操作の提供 ② マルチバージョン管理 MVVC
ロールバック操作
先ほどの REDO ログで述べたように、バックグラウンド スレッドはバッファ プール内のデータを時間から更新します。ただし、トランザクションの実行中にさまざまなエラー (ダウンタイム) が発生したり、ロールバック ステートメントが実行された場合は、アトミック性を確保するために以前にブラシ化された操作をロールバックする必要があります。アンドゥ ログはトランザクションのロールバックを提供します。
MVVC
読み取り行が他のトランザクションによってロックされている場合、アンドゥ ログから行レコードの以前のデータ バージョンを分析できるため、ユーザーはそれを前のデータに読み取ることができます。現在のトランザクション操作 - スナップショットの読み取り。
スナップショット読み取り: SQL によって読み取られるデータは履歴バージョンであり、ロックは必要ありません。通常の SELECT はスナップショット読み取りです。
UNDO ログのコンポーネント:
選択操作ではアンドゥ ログは生成されません
InnoDB ストレージ エンジンでは、アンドゥ ログはストレージにロールバック セグメント ロールバック セグメントを使用します。各ロールバック セグメントには 1024 個の UNDO ログ セグメントが含まれます。 MySQL5.5 以降では、ロールバック セグメントは合計 128 個になります。つまり、合計 128 * 1024 のアンドゥ操作を記録できます。
各トランザクションは 1 つのロールバック セグメントのみを使用し、1 つのロールバック セグメントは同時に複数のトランザクションを処理できます。
トランザクションの送信後すぐに元に戻すログを削除することはできません。トランザクションによっては、以前のデータ バージョンの読み取り (スナップショット読み取り) が必要な場合があります。したがって、トランザクションがコミットされると、アンドゥ ログはバージョン チェーンと呼ばれる連結リストに置かれ、アンドゥ ログが削除されるかどうかは、パージと呼ばれるスレッドによって判断されます。
元に戻すログは次のように分割されます:
元に戻すログの挿入
挿入操作の記録はトランザクション自体にのみ表示されるため、トランザクション自体には表示されません。他のトランザクションにそれを確認できるため (これはトランザクション分離の要件です)、トランザクションがコミットされた直後に UNDO ログを削除できます。パージ操作は必要ありません。
update undo log
update undo log は、削除および更新操作によって生成された Undo ログを記録します。 Undo ログは、トランザクションがコミットされたときに削除できないように、MVCC メカニズムを提供する必要がある場合があります。送信するときは、それを元に戻すログ リストに入れて、パージ スレッドが最終的な削除を実行するまで待ちます。
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
InnoDB エンジンの場合、レコード自体のデータに加えて、各行レコードにはいくつかの非表示の列もあります。 :
INSERT を実行するとき:
begin; INSERT INTO user (name) VALUES ('tom');
挿入されたデータは挿入取り消しログを生成し、データのロールバック ポインタはそれを指します。 UNDO ログには、UNDO ログのシリアル番号、挿入された主キーの列と値が記録されます。その後、ロールバックを実行するときに、主キーを介して対応するデータを直接削除できます。
UPDATE を実行すると:
更新操作に対して更新取り消しログが生成され、主キーを更新するものと更新するものに分けられます。今すぐ実行するとします:
UPDATE user SET name='Sun' WHERE id=1;
この時点で、新しい undo ログ レコードがバージョン チェーンに追加され、その undo no は 1 で、ロールバックされます。新しいアンドゥ ログのポインタは古いアンドゥ ログ (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 は、バイナリ ログ、バイナリ ログ ファイルで、変更ログ (更新ログ) とも呼ばれます。データベースによって実行されたすべての更新ステートメントが記録されます。
binlog の主なアプリケーション シナリオ:
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 キャッシュは次の場所に書き込まれます。バイナリログファイル。トランザクションのバイナリログは分割できないため、トランザクションがどれほど大きくても一度に書き込む必要があるため、システムはメモリのブロックをバイナリログキャッシュとして各スレッドに割り当てます。
この 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 ログの書き込み中に例外が発生します。は書き込まれません 最後に例外が発生します この時点では、バイナリログに対応する変更レコードはありません。したがって、binlog ログを使用してデータを復元する場合、またはスレーブがマスターの binlog を読み取る場合、この更新は省略されます。復元された行の c 値は 0 ですが、元のデータベースでは、REDO ログの復元により、c 値は 0 になります。この行の値は 1 です。最終的なデータは矛盾しています。
2 つのログ間の論理的一貫性の問題を解決するために、InnoDB ストレージ エンジンは 2 フェーズ コミット スキームを使用します。 REDO ログを準備とコミットの 2 つのステップに分割します。これは 2 段階のコミットです。
REDO ログと bin ログの最終コミットを結合させます。前述したように、トランザクションがコミットされるとき、デフォルトでは、コミットが成功する前に REDO ログを同期する必要があります。 bin Log には、データが失われないようにするこの機能もあります。
2 フェーズ コミットを使用した後、バイナリ ログの書き込み時に例外が発生しても影響はありません。これは、MySQL が REDO ログ ログに基づいてデータを復元するときに、 REDO ログがまだ準備段階にあり、対応する binlog ログがない場合、送信は失敗し、データはロールバックされます。
別のシナリオでは、REDO ログのコミット フェーズ中に例外が発生しました。トランザクションはロールバックされますか?
はトランザクションをロールバックせず、上の図に示されているロジックを実行します。REDO ログは準備段階にありますが、対応する binlog ログが見つかります。トランザクション ID. を使用するため、MySQL はトランザクションが完了したと判断し、トランザクションを送信してデータを復元します。
推奨学習: mysql ビデオ チュートリアル
以上がMySQL ログの特別な配置: REDO ログと UNDO ログの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。