MySQL はどのようにしてデータの整合性を確保するのでしょうか?

MySQL はどのようにしてデータの整合性を確保するのでしょうか?

オンライン ビジネスにとってデータの一貫性と整合性が重要であることは明らかです。データが失われないようにするにはどうすればよいでしょうか?今日は、データの整合性と強力な一貫性に関して MySQL がどのような改善を行ったかについて説明します。

1. MySQL 2フェーズコミット

Oracle や MySQL などのリレーショナル データベースでは、先行書き込みログ戦略が重要です。ログがディスクに保持されている限り、MySQL の異常な再起動後もデータが失われないことが保証されます。 MySQL では、ログについて話すときには、REDO ログと binlog について言及する必要があります。

1. 再実行ログ

REDO ログ (REDO ログ ファイルとも呼ばれます) は、各データ ページのデータ行への変更を詳細に記録し、データが変更された後の値を記録します。 REDO ログはデータベースのクラッシュ回復に使用され、データのセキュリティを確保するための最も重要な機能の 1 つです。

REDO ログは順次かつ周期的に書き込まれます。REDO ログのファイル サイズと数は、innodb_log_file_size と innodb_log_files_in_group の 2 つのパラメータによって制御されます。 REDO ログをディスクに書き込む前に、まず REDO ログ バッファに書き込まれます。そのサイズは innodb_log_buffer_size によって制御されます。ログは、REDO ログ バッファに書き込まれた後、どのようにディスクに保存されますか? Redo ログの書き込み戦略を制御するために、Innodb は innodb_flush_log_at_trx_commit パラメータの異なる値に応じて異なる戦略を採用します。3 つの異なる値があります。

  • 1. 0 に設定した場合: トランザクションがコミットされると、MySQL バックグラウンド マスター スレッドは 1 秒ごとにキャッシュ ファイルをログ ファイルに更新します。
  • 2. 1 に設定すると、トランザクションがコミットされるたびに REDO ログがディスクに直接保存され、トランザクション ログが失われないことが保証されますが、データベースのパフォーマンスに若干の影響が出ます。
  • 3. 2 に設定すると、トランザクションがコミットされるたびに、REDO ログのみがログ ファイルに書き込まれ、ディスクはフラッシュされません。ファイル システムはディスクを自動的にフラッシュします。

3 つのモードのうち、0 はパフォーマンスが最も優れていますが、安全ではありません。MySQL プロセスがクラッシュすると、1 秒分のデータが失われます。オプション 1 はセキュリティが最も高いですが、パフォーマンスへの影響が最も大きくなります。オプション 2 は、主にオペレーティング システムによるディスク フラッシュ時間を制御します。MySQL のみがクラッシュした場合は、データに影響はありません。ホストが異常クラッシュした場合は、データも失われます。

2. バイナリログ

binlog はバイナリ ログとも呼ばれ、選択操作と表示操作を除く、MySQL データベースを変更するすべての操作を記録します。主に、リカバリ、レプリケーション、監査の機能を果たします。 Binlog 形式には、主にステートメント、行、混合が含まれます。

ステートメント: 操作に基づく SQL ステートメントが binlog に記録されます。これは推奨されません。

行: 行変更の記録に基づいて、行変更の前後のコンテンツを記録します。行モードは、データベースがデータ損失を防ぐための重要な保証でもあるため、使用することをお勧めします。

混合: 最初の 2 つのモードの混合。推奨されません。

Binlog の書き込みロジックも比較的単純です。トランザクションの実行中に、まず binlog キャッシュに書き込まれ、次にトランザクションがコミットされたときに binlog ファイルに書き込まれます。 binlog キャッシュは、binlog_cache_size および max_binlog_size パラメータによって制御されます。各スレッドには binlog キャッシュが割り当てられますが、binlog ファイルは共有されます。

Binlog のログ ファイル書き込みメカニズムは sync_binlog によって制御されます。

  • 1. sync_binlog=0 の場合、各トランザクションは fsync なしでのみ書き込まれることを意味します。
  • 2. sync_binlog=1 の場合、トランザクションが送信されるたびに fsync が実行され、データがディスクにフラッシュされます。
  • 3. sync_binlog=N (N>1) の場合、n 個のトランザクションがコミットされた後、MySQL は fsync アクションを実行して、binlog キャッシュ内のデータをディスクにフラッシュすることを意味します。

innodb_flush_log_at_trx_commit と sync_binlog の両方を 1 に設定すると、MySQL データの従来のダブルワン モードになり、データベースのデータが失われないようにすることができます。

MySQL データは、各ダーティ データのフラッシュによって発生するパフォーマンスへの影響を軽減するために WAL メカニズムを採用しています。「ダブル ワン」戦略が設定されている場合、データベースのパフォーマンスに影響しますか?実際、これは主に、REDO ログと binlog の両方が順次書き込まれるという事実によるものです。ディスクの順次書き込み速度は、ランダム書き込み速度よりもはるかに高速です。さらに、MySQL 内のグループ コミット メカニズムにより、ディスクの IOPS 消費が大幅に削減されました。

3. 2フェーズコミット

MySQL では、2 フェーズ コミット (2pc) が導入されています。MySQL は通常のトランザクションを XA トランザクション (内部分散トランザクション) として扱い、各トランザクションに一意の ID (XID) を自動的に割り当てます。COMMIT は、準備とコミットの 2 つのフェーズに受動的に分割されます。

フェーズ 1: トランザクション準備フェーズ

この時点で、SQL は正常に実行され、xid 情報と redo および undo メモリ ログが生成されました。次に、準備メソッドを呼び出して最初のフェーズを完了し、トランザクション ステータスを TRX_PREPARED に設定し、REDO ログをディスクにフラッシュします。

フェーズ2: コミットフェーズ

トランザクションの最初のフェーズが準備フェーズに入ると、生成されたバイナリログがファイルに書き込まれ、ディスクにフラッシュされます。この時点で、トランザクションはコミットされることになります。

特定の異常シナリオ分析:

1. 準備フェーズでトランザクションがクラッシュし、データベースがバイナリ ログに書き込まれず、リカバリ中にストレージ エンジンがコミットされない場合、トランザクションはロールバックされます。

2. トランザクションが binlog フェーズでクラッシュすると、ログはディスクに正常に書き込まれません。トランザクションは開始時にロールバックされます。 3. バイナリログがディスクに fsync() された後にトランザクションがクラッシュし、InnoDB がコミットする時間がなかった場合、MySQL データベースはリカバリ中にバイナリログの Xid_log_event を読み取り、これらの XID を持つトランザクションをコミットするように InnoDB に指示します。InnoDB はこれらのトランザクションをコミットした後、他のトランザクションをロールバックして、ストレージ エンジンとバイナリ ログの一貫性を保ちます。

MySQL の 2 フェーズ コミットにより、異常なシャットダウンによりデータベースが再起動された後でもデータが失われないことが保証されます。

2. 二重書き込み

前述したように、REDO ログ、バイナリログ、および 2 フェーズ コミットにより、MySQL の異常な再起動後にロールフォワードとロールバックを通じてデータを回復できるようになります。 MySQL はリカバリに redo ログを使用します。 redo ログにはページ上の物理的な操作が記録されますが、問題があります。部分的な書き込みの問題 (ページ サイズは 16K です。メモリ内のダーティ ページをデータベースに書き込むときに、4K が書き込まれ、突然電源が切れたとします。つまり、最初の 2 つの 4K は新しく、最後の 12K は古いため、このデータ ページは不完全で、不良データ ページです) など、ページ自体に問題がある場合、 redo リカバリではデータ ページの整合性を検証します。この時点で、データ ページはすでに破損しているため、 redo ログをリカバリに使用できず、データが失われます。

二重書き込みの原則:

1. バッファ プールのダーティ ページを更新する場合、ダーティ ページはデータ ファイルに直接書き込まれるのではなく、最初にダブル書き込みバッファにコピーされます。

2. 次に、ダブル書き込みバッファをディスク上の共有テーブルスペースに 2 回 (1 回につき 1 MB) 書き込みます。

3. 最後に、ダブル書き込みバッファからデータ ファイルを書き込みます。データは常に 2 回書き込まれますが、二重書き込みは順番に書き込まれるため、実際にはシステム パフォーマンスが約 10% 低下します。

これにより、ディスク上の共有テーブルスペースにデータ ページのコピーが存在するため、前述の部分的な書き込み失敗の問題を解決できます。ページをデータ ファイルに書き込むプロセス中にデータベースがクラッシュした場合、インスタンスを復元すると、共有テーブルスペースにページのコピーが見つかり、コピーされて元のデータ ページが上書きされ、その後、REDO ログを適用できます。

3. まとめ

今日は、MySQL の 2 フェーズ コミットと二重書き込みメカニズムについて説明しました。これらはそれぞれ、MySQL がクラッシュして再起動する場合と部分的なページ書き込みの場合のシナリオで、MySQL がデータ損失を防ぐ方法を解決します。では、オペレーティング システムがクラッシュして起動できない場合はどうすればよいでしょうか?データが失われないようにするために、MySQL はクラスター アーキテクチャでどのような最適化を行いましたか?次の章では、クラスター アーキテクチャにおける MySQL の最適化と改善について説明します。

以下もご興味があるかもしれません:
  • MySQL: データの整合性
  • MySQL データベースに基づくデータ制約の例と 5 つの整合性制約の紹介
  • データベースの削除から逃走までの MySQL の徹底分析_上級編 (I) - データ整合性
  • MySQLはmysqldump+binlogを使用して、削除されたデータベースの原理分析を完全に復元します。
  • DjangoでMySQLデータベースを構成するための完全な手順
  • PHP は、mysqli および pdo 拡張機能を使用して、mysql データベースの実行効率をテストおよび比較します。完全な例
  • PHP は、mysqli および pdo 拡張機能を使用して、mysql データベースへの接続の効率をテストおよび比較します。完全な例
  • Spring MVCはMySQLデータベースの追加、削除、変更、チェックの完全な例を実装します
  • MySQLデータベースをアンインストールするための完全な手順
  • C# から MySQL データベースへの接続の完全な例
  • PHPでMYSQLトランザクションを実行して、不完全なデータ書き込みなどの問題を解決します

<<:  集める価値のある 15 個の JavaScript 関数

>>:  nginxフロー制御とアクセス制御の実装

推薦する

格納可能なセカンダリメニューを実装するための JavaScript

JavaScriptで格納可能なセカンダリメニューを実装するための具体的なコードは参考までに。具体...

雨滴効果を実現する JavaScript キャンバス

この記事の例では、雨滴効果を実現するためのキャンバスの具体的なコードを参考までに共有しています。具体...

JavaScript の実行コンテキストとコールスタックの詳細な説明

目次1. 実行コンテキストとは何か2. 実行コンテキスト スタックとは何ですか? 3. 実行コンテキ...

MySQL マスタースレーブレプリケーション 読み書き分離の設定方法の詳細説明

1. 説明前回は、MySQL のインストールと構成、MySQL ステートメントの使用、MySQL デ...

ウェブデザインの教育または学習プログラム

セクションコース内容営業時間1 ウェブデザインの概要2 2 HTML 基本タグとフォーマットタグ 2...

テキストエリアタグはサイズ変更できず、マウスでドラッグすることもできません

テキストエリアタグのサイズは不変ですコードをコピーコードは次のとおりです。 <textarea...

Linuxのファイルとフォルダの権限を操作する方法

Linux のファイル権限まず、現在のディレクトリ内のファイルの内容を確認しましょう。 ls -l ...

写真とテキストによる MySQL と sqlyog のインストール チュートリアル

1. MySQL 1.1 MySQLのインストールmysql-5.5.27-winx64 ダウンロー...

MySQL で大量のデータ (数千万) を素早く削除するためのいくつかの実用的なソリューションの詳細な説明

著者は最近、仕事でパフォーマンスのボトルネックの問題に遭遇しました。MySQL テーブルには毎日約 ...

Windows 10 64 ビット版に MySQL 5.6.35 をインストールするためのグラフィック チュートリアル

1. MySQL Community Server 5.6.35をダウンロードするダウンロードアドレ...

Tomcat サーバー入門の超詳細なチュートリアル

目次1. Tomcat の概念–1、サーバー–2、ウェブサーバー–3、Tomcatサーバー次にTom...

初心者のためのWebページ作成: HTMLのハイパーリンクAタグの使い方を学ぶ

ハイパーリンク a タグはリンク ポイントを表し、英語の単語「anchor」の略語です。その機能は、...

一般的なDockerコマンドの概要

Dockerのインストール1. 要件: Linuxカーネルバージョン3.10以上 表示: uname...

JavaScript 関数呼び出し、適用、バインド メソッドのケース スタディ

要約する1. 類似点どちらも、ターゲット関数が実行されると内部の this ポインターを変更できます...

Linux での Python スクリプトの自動起動とスケジュール起動の詳細な手順

1. Pythonは起動時に自動的に実行されますPython の自己起動スクリプトがauto.pyで...