序文MySQL の実装について初めて学んだとき、REDO ログ、WAL (先行書き込みログ)、UNDO ログなどのキーワードを常に耳にしていました。REDO ログは主にトランザクションの永続性を実現するために使用されていることを知りました。 redo ログをさらに理解するために、関連するコード (ソース コード バージョン: MySQL 8.0.12) を確認しました。ここでは、redo ログがどのように生成されるか、どのようにディスクに書き込まれるか、そして最終的にユーザーに通知される方法を中心に、簡単にまとめます。 REDOログの生成読み取り/書き込みトランザクションの実行中、REDO ログが継続的に生成されます。データ ページの適用、データ ページの変更、UNDO ログの記録などを行うと、REDO ログが生成されます。 MySQL は、ユーザー トランザクションを mtr (ミニ トランザクション) に分割します。REDO ログは、最初に生成されると mtr に記録され、mtr の送信とともにコミットされ、最終的にハード ディスクに保存されます。 REDOログ送信mtr が送信されると、mtr 内の redo ログがシステム変数 log_sys のログ バッファーに書き込まれます。 MySQL 8.0 の新機能は、ロックフリーの REDO ログ送信です。 8.0 より前では、各ユーザー スレッドがミューテックスを競合し、ログ バッファーにシリアルに書き込んでいたため、LSN がギャップなく順番に増加していました。 8.0 では、ユーザー スレッドは同時にログ バッファーに書き込むことができます。ユーザー スレッドがログ バッファーに正常に書き込み、その後ディスクに書き込んだ LSN の前にログ バッファーをフラッシュすると、他のユーザー スレッドが書き込みを完了する前にログ バッファーをフラッシュする可能性があります。 この問題を解決するために、MySQL 8.0 ではログ バッファ ホールを回避する Link_buf データ構造が導入されました。 Link_buf は、実際には固定長の配列であり、スライディング ウィンドウのようにログ バッファーのセクションの書き込みステータスを追跡し、連続した REDO ログがログ バッファーに書き込まれるにつれて前進します。 Link_buf のデータ構造は次のとおりです。 ユーザーがログ バッファーの start_lsn と end_lsn の間に REDO ログを書き込むと、Link_buf の対応する位置がマークされます。つまり、m_link[start_lsn%m_capacity] に end_lsn-start_lsn の値が割り当てられます。 ログ バッファへの REDO ログ記録のプロセスは次のとおりです。 1. まず、各ユーザー スレッドが redo ログを書き込むときに、redo ログの長さに応じて、システム グローバル アトミック変数 log_sys.sn から redo ログの start_lsn と end_lsn を取得します。アトミック変数 sn は、各スレッドによって取得される start_lsn-end_lsn 間隔が穴なく連続していることを保証できます。 2. ユーザー スレッドが start_lsn-end_lsn 間隔を適用した後、Link_buf が使用可能な位置まで進むまで待機する必要があります。 図に示すように、start_lsn0-end_lsn0、start_lsn2-end_lsn2、start_lsn3-end_lsn3 は、3 つのユーザー スレッドに新しく適用された LSN 間隔です。start_lsn1-end_lsn1 に対応する間隔は link_buf にマークされています。start_lsn3-end_lsn3 は末尾から離れすぎているため、link_buf が進むまで待機してから使用する必要があります。 3. ログ バッファーに書き込んだ後、start_lsn->end_lsn の範囲を link_buf にマークします (注: link_buf は start_lsn%capacity の位置にのみマークされるため、end_lsn が (m_tail、m_tail+m_capacity) を超えても影響を受けません)。 4. ユーザー スレッドがトランザクションをコミットすると、イベント log_sys.writer_event が設定され、log_writer スレッドがログを redo ログ バッファーからシステム キャッシュに書き込むようにトリガーされます (log_writer スレッド自体も link_buf をポーリングして、新しいログが書き込まれたかどうかを判断します)。 5. log_writer スレッドは m_tail を進め、m_tail の前のログ バッファーをディスクに書き込みます。 REDOログの保存と通知前のセクションでは、REDO ログがどのように送信されるかについて簡単に説明しました。REDO ログが送信され、ディスクに書き込まれるときには、複数のスレッドが関与します。それらの関係は次のとおりです。 ユーザー スレッドが読み取り/書き込みトランザクションをコミットすると、mtr がコミットされるときにいくつかの redo ログが生成され、redo ログ バッファーに記録されます。次に、ユーザー スレッドは writer_event を設定して log_writer スレッドによるログの書き込みをトリガーし、独自の flush_events[i] イベントをリッスンしようとします。 log_writer スレッドは Link_buf.m_tail を進め、最大連続 LSN の前の redo ログをシステム キャッシュに書き込み、log_flusher スレッドをトリガーする flusher_event を設定します。 log_flusher スレッドは、システム キャッシュに書き込まれたログをディスクにフラッシュし、flush_notifier_event を設定して log_flush_notifier スレッドをトリガーし、ユーザーに通知します。 log_flush_notifier は、フラッシュされたディスクの LSN に基づいてトリガーする必要があるイベントを計算し、ユーザー スレッドに通知します。 具体的な実装では、log_sys 内のいくつかのメンバー変数を使用して、REDO ログの書き込みステータスを追跡します。 log_sys.recent_writtern.m_tail はログ バッファーの最大連続範囲を示します。log_sys.write_lsn はデータがシステム キャッシュに書き込まれる場所を示します。log_sys.flushed_to_disk_lsn はデータがディスクにフラッシュされた場所を示します。各マークの昇格プロセスは次のとおりです。 ユーザースレッドに通知ユーザーがトランザクションをコミットすると、innodb_flush_log_at_trx_commit パラメータに従って log_wait_for_write または log_wait_for_flush が呼び出され、REDO ログがシステム キャッシュに書き込まれるか、ハード ディスクにフラッシュされるまで待機します。ユーザー スレッドの通知は、log_sys.flush_events イベント配列を通じて実装されます。一度に通知される flush_events が多すぎるのを避けるために、flush_events はバケットのように異なるユーザー スレッドに分割されます。REDO ログはログ ブロックに分割されます。log_sys.flush_events 配列の長さが m であると仮定すると、n 番目のログ ブロックのフラッシュは flush_events[n%m] イベントによって監視されます。ログ バッファーの L1 番目のログ ブロックから L2 番目のログ ブロックまでがディスクにフラッシュされると、L1 と L2 の間のログ ブロックの flush_events が設定され、L1 と L2 の間の redo ログのユーザー スレッドが通知を受け取ります。 要約するMySQL 8.0 では、REDO ログをロックフリーにすることで、ユーザー スレッドが REDO ログを書き込むときにロック競合によって発生するパフォーマンスへの影響を解決します。同時に、REDO ログのファイル書き込みと REDO ログのフラッシュはユーザー スレッドから分離され、別のスレッドに抽出されます。ユーザー スレッドは、REDO ログをログ バッファに書き込むことだけを担当し、ディスクへの REDO ログのフラッシュの詳細については気にする必要がなくなります。log_writer スレッドまたは log_flusher スレッドからの通知を待つだけで済みます。 上記は、MySQL 8.0 redo ログの徹底的な分析の詳細な内容です。MySQL 8.0 redo ログの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
>>: 複数の Docker コンテナが同じポート番号を持たない場合の解決策
echartsワードクラウドはechartsの拡張版ですhttps://echarts.apache...
フォームのアクションは URL ジャンプとは異なります。フォームはバックグラウンドにデータを渡すこと...
目次1. サービスの開始と停止の手順1.1 Windows での MySQL 5.7 の公式 MSI...
Anaconda は、大規模なデータ処理、予測分析、科学計算のための最も人気のある Python デ...
目次1. イベントとは何ですか? 2. イベントの使い方3. バインドタップとキャッチタップの違い4...
スタックフローからの回答:単に<br>だけで十分です。その他の形式は、XHTML との互...
ファイル内の文字列の数を数えることは、実際には砂の中の石を探すようなものです。ある人は、石を見た後に...
検索エンジン最適化 (SEO) では実行すべきタスクが多数ありますが、その中でもコードの最適化は重要...
公式ドキュメント http://dev.mysql.com/doc/refman/5.7/en/se...
この記事では、マルチカラムレイアウトドラッグを実装するためのVueの具体的なコードを参考までに共有し...
関連記事:初心者が学ぶ HTML タグ (1)初心者は、いくつかの HTML タグを理解することで ...
一般的なブラウザでテスト ページを開き、Fiddler で http リクエストを表示してください。...
この記事では、bootstrapテーブルの使い方を参考までに紹介します。具体的な内容は次のとおりです...
セレクタのグループ化h2 要素と段落の両方を灰色にしたいとします。これを行う最も簡単な方法は、次のス...
目次序文webSocket の操作と例について:ウェブソケット1. webSocketについて2. ...