MySQL マスタースレーブ同期、トランザクションロールバックの実装原理

MySQL マスタースレーブ同期、トランザクションロールバックの実装原理

ビンログ

BinLog は、データベース テーブル構造の変更 (テーブルの作成、変更など) とテーブル データの変更 (挿入、更新、削除) をすべて記録するバイナリ ログです。BinLog ファイルは、マスターとスレーブのデータベース同期に使用されます。 BinLog ログ ファイルには 3 つのモードがあります。

ステートメントモード

内容: Binlog はデータの変更を引き起こす SQL ステートメントのみを記録します

利点: このモードでは実際のデータが記録されないため、ログの量と IO 消費量が非常に少なく、パフォーマンスが最適になります。

デメリット: ただし、一部の操作は確実ではありません。たとえば、uuid() 関数は一意の識別子をランダムに生成します。binlog 再生に依存する場合、この操作によって生成されるデータは元のデータとは異なる必要があり、予期しない結果が発生する可能性があります。

ROWモード

内容: このモードでは、binlog は各操作のソース データと変更されたターゲット データを記録します。StreamSets にはこのモードが必要です。

利点: 絶対的な精度でデータを復元できるため、データのセキュリティと信頼性が確保され、レプリケーションとデータ回復のプロセスを同時に実行できます。

デメリット: デメリットは、binlog のボリュームが非常に大きくなることです。同時に、変更されたレコードが多く、フィールド長が長い操作の場合、記録中のパフォーマンスの消費が非常に深刻になります。データを読み取るには特別な命令も必要です。

混合モード

内容: 上記の 2 つのモード (STATEMENT と ROW) を組み合わせたものです。

詳細: ほとんどの操作では、バイナリログを記録するために STATEMENT が使用されます。ROW を使用して実装される操作は、テーブル ストレージ エンジンが NDB であること、uuid() などの不確実な関数が使用されていること、挿入遅延ステートメントが使用されていること、一時テーブルが使用されていることのみです。

マスタースレーブ同期プロセス:

1. マスター ノードは、データベース データを変更するすべてのイベントを記録するためにバイナリ ログを有効にする必要があります。

2. スレーブ ノードは、MySQL クライアントとして機能するスレッド (I/O スレッド) を開始し、MySQL プロトコルを介してマスター ノードのバイナリ ログ ファイル内のイベントを要求します。

3. マスターノードは、自身のバイナリログ内のイベントをチェックし、相手側から要求された位置と比較するためのスレッド(ダンプスレッド)を開始します。要求位置パラメータがない場合、マスターノードは最初のログファイルの最初のイベントをスレーブノードに1つずつ送信します。

4. スレーブノードはマスターノードから送信されたデータを受信し、リレーログファイルに配置します。また、マスター ノードのどのバイナリ ログ ファイル内にリクエストが送信されたかという具体的な場所を記録します (マスター ノードには複数のバイナリ ファイルが存在します)。

5. ノードから別のスレッド (SQL スレッド) を開始し、リレー ログ内のイベントを読み取り、ローカルで再度実行します。

MySQL のデフォルトのレプリケーション モードは非同期であり、並列レプリケーション機能を備えています。マスター データベースは、ログをスレーブ データベースに送信し、それを無視します。これにより問題が発生します。マスター データベースがクラッシュし、スレーブ データベースが処理に失敗した場合、スレーブ データベースがマスター データベースに昇格した後にログが失われます。ここから 2 つの概念が生まれます。

  • 完全同期レプリケーション

マスターデータベースが binlog を書き込んだ後、ログをスレーブデータベースに強制的に同期します。すべてのスレーブデータベースの実行が完了すると、ログがクライアントに返されます。ただし、この方法はパフォーマンスに重大な影響を与えることは明らかです。

  • 準同期レプリケーション

半同期レプリケーションのロジックは、スレーブ データベースがログを正常に書き込んだ後、マスター データベースに ACK 確認を返すというものです。マスター データベースは、少なくとも 1 つのスレーブ データベースから確認を受信すると、書き込み操作が完了したと見なします。

やり直しログ

binlog と redolog の違い:

  • redo ログは InnoDB エンジンに固有のものですが、binlog は MySQL のサーバー層で実装されており、すべてのエンジンで使用できます。
  • REDO ログは、データ ページにどのような変更が加えられたかを記録する物理ログです。一方、バイナリ ログは、ID=2 の行の c フィールドに 1 を追加するなど、ステートメントの元のロジックを記録する論理ログです。
  • Redo ログはサイクルで書き込まれ、そのスペースは最終的に不足します。一方、binlog は追加形式で書き込むことができます。追加書き込みとは、binlog ファイルが特定のサイズに達すると、次のファイルに切り替わり、以前のログは上書きされないことを意味します。

MySQL では、すべての更新操作をディスクに書き込む必要があり、ディスクも対応するレコードを見つけて更新する必要があるため、プロセス全体の IO コストと検索コストが非常に高くなります。最初にログを書き込み、次にディスク BinLog と RedoLog を書き込みます。

1. レコードが更新されると、InnoDB エンジンはまずレコードを RedoLog に書き込み、メモリを更新します。同時に、InnoDB エンジンはアイドル状態のときに操作レコードをディスクに更新します。

2. RedoLog が処理できる更新が多すぎる場合は、まず RedoLog データの一部をディスクに書き込み、その後 RedoLog データの一部を消去する必要があります。

RedoLog 書き込み位置とチェックポイント

RedoLogには書き込み位置とチェックポイントがあります

write pos: は現在のレコードの位置です。書き込み中は後方に移動します。ファイル番号 3 の末尾まで書き込んだ後は、ファイル番号 0 の先頭に戻ります。

チェックポイント: データベースのリカバリ時間を短縮します。バッファ プールのスペースが不足している場合、ダーティ ページはディスクにフラッシュされます。REDO ログが使用できない場合、ダーティ ページはフラッシュされます。

REDO ログの順次書き込みは、実際には複数の固定ファイルをループで書き込み、1 ラウンドが完了すると最初から上書きされます。チェック ポイントと書き込み位置の 2 つの場所が含まれます。書き込み位置は書き込まれる位置で、ループ内で増加します。チェック ポイントは消去される現在の位置です。 2 つの間のスペースは書き込み可能です。書き込み位置がチェックポイントに追いつくと、更新が停止し、一部のレコードが上書きされてから、REDO ログの書き込みが続行されます。

クラッシュセーフなREDOログ

MySQL は、コミット時にログ バッファー内のログをログ ファイルにフラッシュする方法をユーザーがカスタマイズすることをサポートしています。この制御は、変数 innodb_flush_log_at_trx_commit の値によって決まります。この変数には 0、1、2 の 3 つの値があり、デフォルトは 1 です。ただし、この変数はコミット アクションがログ バッファーをディスクにフラッシュするかどうかのみを制御することに注意してください。

  • 1 に設定すると、トランザクションがコミットされるたびに、ログ バッファー内のログが OS バッファーに書き込まれ、fsync() が呼び出されてディスク上のログ ファイルにフラッシュされます。この方法では、システムがクラッシュしてもデータは失われませんが、各送信がディスクに書き込まれるため、IO パフォーマンスは低下します。
  • 0 に設定すると、トランザクションがコミットされたときにログ バッファー内のログは OS バッファーに書き込まれません。代わりに、ログは 1 秒ごとに OS バッファーに書き込まれ、fsync() が呼び出されてディスク上のログ ファイルに書き込まれます。つまり、0 に設定すると、ディスクに書き込まれたデータは (およそ) 1 秒ごとに更新されます。システムがクラッシュすると、1 秒分のデータが失われます。
  • 2 に設定すると、各コミットは OS バッファにのみ書き込まれ、その後 fsync() が 1 秒ごとに呼び出され、OS バッファ内のログがディスク上のログ ファイルに書き込まれます。

マスタースレーブレプリケーション構造では、トランザクションの永続性と一貫性を確保するために、ログ関連の変数を次のように設定する必要があります。

  • バイナリ ログが有効になっている場合は、sync_binlog=1 を設定します。これは、各トランザクションが同期的にディスクに書き込まれることを意味します。
  • 常に innodb_flush_log_at_trx_commit=1 に設定します。つまり、各トランザクションはコミットされるたびにディスクに書き込まれます。

上記の 2 つの変数を設定すると、各トランザクションがバイナリ ログとトランザクション ログに書き込まれ、コミット時にディスクにフラッシュされるようになります。

InnoDB では、REDO ログを使用することで、データベースが異常に再起動した場合でも、以前に送信されたレコードが失われないことを保証できます。この機能はクラッシュセーフと呼ばれます。 Redolog 2 フェーズ コミット: binlog と redolog 間のロジックを一貫させます。提出手順は次のとおりです。

1 準備段階 --> 2 binlog の書き込み --> 3 コミット

1. ステップ 2 の前にプロセスがクラッシュした場合、再起動後にコミットがないことがわかり、プロセスがロールバックされます。バックアップと復元: binlog なし。一貫性
2. 手順 3 の前にクラッシュが発生した場合、再起動リカバリでは、コミットはないものの、準備と binlog が完了していることが検出されるため、再起動後にコミットが自動的に実行されます。バックアップ: binlog を使用。一貫性あり

元に戻すログ

UNDOログには、ロールバックと複数行バージョン管理(MVCC)を提供するという2つの機能があります。主に2つのタイプに分けられます。

データが変更されると、REDO だけでなく、対応する UNDO も記録されます。トランザクションが失敗したり、何らかの理由でロールバックしたりした場合は、UNDO の助けを借りてロールバックできます。レコードが削除されると、対応する挿入レコードが UNDO ログに記録され、その逆も同様です。レコードが更新されると、対応する反対の更新レコードが記録されます。

ロールバックを実行すると、UNDO ログ内の論理レコードから対応する内容を読み取ってロールバックすることができます。

  • 元に戻すログを挿入

トランザクションが新しいレコードを挿入するときに生成される UNDO ログを表します。これはトランザクションがロールバックされるときにのみ必要であり、トランザクションがコミットされた直後に破棄できます。

  • 元に戻すログを更新

トランザクションが更新または削除しているときに生成される UNDO ログ。トランザクションのロールバック時だけでなく、スナップショットの読み取り時にも必要となるため、安易に削除することはできません。高速読み取りまたはトランザクションのロールバックにログが含まれない場合のみ、対応するログはパージ スレッドによって一律にクリアされます。

上記は、MySQL マスタースレーブ同期とトランザクションロールバックの実装原理の詳細な内容です。MySQL マスタースレーブ同期とトランザクションロールバックの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL マスター スレーブ データベースが同期されない問題を解決する 2 つの方法
  • Mysql データベースのマスタースレーブ同期構成
  • この記事では、MySQLのマスタースレーブ同期の原理を説明します。
  • Docker環境でMySQLを実行し、Binlogを有効にしてマスタースレーブ同期を構成する方法
  • MySQLデータベースのマスタースレーブ同期の実際のプロセスの詳細な説明
  • MySQL マスタースレーブ同期における server-id の例の詳細な説明
  • MySQLデータベースのマスタースレーブ同期構成と読み取り書き込み分離
  • MySQL マスタースレーブ同期の原理と応用

<<:  Docker デプロイメント RabbitMQ コンテナ実装プロセス分析

>>:  3つのDocker Nginxログの処理の詳細な説明

推薦する

Linux lnコマンドの使用

1. コマンドの紹介ln コマンドは、ファイルのリンクを作成するために使用されます。リンクは、ハード...

Dockerを使用してOracle_11gをインストールする方法

DockerでOracle_11gをインストールする1. oracle_11gイメージを取得する d...

Mysql クラシック高レベル/コマンドライン操作 (クイック) (推奨)

サーバーとデータベースの構築方法を学ぶ必要があるため、最近は SQL 言語を独学で学び始めました。デ...

トークンの有効期限が切れたときにページを更新するときに繰り返しプロンプトが表示されないようにする Vue について

トークンの有効期限が切れたら、ページを更新します。ページの読み込み時にバックエンドに複数のリクエスト...

MySQL 8.0 のデフォルトのデータディレクトリを変更する (設定なしの簡単な操作)

使用シナリオ: Alibaba Cloud を使用しており、データディスクを別途購入しました (大容...

JSは画像の滝の流れの効果を実現します

この記事では、画像ウォーターフォールフローを実現するためのJSの具体的なコードを参考までに共有します...

MySQL 8.0 でリモートアクセス権限を設定する方法

前回の記事では、MySQL パスワードをリセットする方法を説明しました。一部の学生から、データベース...

アニメーションとトランジションの違い

CSS3アニメーションとJSアニメーションの違いJSはフレームアニメーションを実装しますCSS3はト...

MySQL の自動増分主キーが使い果たされた場合の対処方法

面接では、次のようなシナリオを経験する必要があります。インタビュアー: 「MySQL を使用したこと...

Linux に nginx をインストールする方法

Nginx は C 言語で開発されており、Linux で実行することをお勧めします。もちろん、Win...

MySQL 5.7 でルートパスワードを変更する方法

MySQL 5.7 以降では、多くのセキュリティ更新が追加されました。旧バージョンのユーザーは慣れて...

HTML で複数のフォームのテキスト ボックスを揃える方法

フォームのコードは図の通りです。スタイルシートがまだ追加されていないため、フォームが整列されておらず...

MySQL5.7 マスタースレーブ構成例の分析

MySQL5.7マスタースレーブ構成の実装方法、具体的な内容は次のとおりですインストール環境:マスタ...

Linux 上の Vim で色とテーマを変更する方法

Vim は Linux でよく使用されるテキスト エディターです。 Vim は、Sublime や ...

ウェブページデザインのための4つの実践的なヒント

関連記事: Web コンテンツ ページを作成するための 9 つの実用的なヒント<br />...