序文データベース トランザクションに関して言えば、トランザクションの ACID 特性、分離レベル、解決される問題 (ダーティ リード、非反復読み取り、ファントム リード) など、トランザクションに関連する多くの知識が誰の頭にもすぐに浮かびますが、これらのトランザクション特性がどのように実装されているか、また 4 つの分離レベルがなぜあるのかを実際に理解している人はほとんどいないでしょう。 前回の記事では、MySQL におけるトランザクション分離の実装原則について学びました。今日は、引き続き MySQL 永続性の実装原則についてお話ししましょう。 もちろん、MySQL は広範かつ奥深いため、この記事で省略される部分があることは避けられません。批判や訂正は大歓迎です。 例示する MySQL のトランザクション実装ロジックはエンジン層にあり、すべてのエンジンがトランザクションをサポートしているわけではありません。次の手順は InnoDB エンジンに基づいています。 InnoDB のデータの読み取りと書き込みの原理先に進む前に、InnoDB がデータを読み書きする方法を理解する必要があります。データベースのデータはディスクに保存され、ディスク I/O のコストが非常に高いこともわかっています。データの読み取りまたは書き込みのたびにディスクにアクセスする必要がある場合、データベースの効率は非常に低くなります。この問題を解決するために、InnoDB はデータベース データにアクセスするためのバッファーとしてバッファー プールを提供します。 バッファ プールはメモリ内に配置され、ディスク上のいくつかのデータ ページのマッピングが含まれています。データの読み取りが必要な場合、InnoDB はまずバッファ プールからデータを読み取ろうとします。データを読み取れない場合は、ディスクから読み取ってバッファ プールに格納します。データを書き込む場合は、まずバッファ プール ページに書き込み、そのページをダーティとしてマークし、特別なフラッシュ リストに格納します。これらの変更されたデータ ページは、将来のある時点でディスクにフラッシュされます (このプロセスはダーティ フラッシュと呼ばれ、他のバックグラウンド スレッドが担当します)。次の図に示すように: この設計の利点は、大量のディスク I/O をメモリの読み取りと書き込みに変換し、ページに対する複数の変更を 1 つの I/O 操作にマージ (ダーティになったページ全体をフラッシュ) することで、読み取りおよび書き込み操作ごとにディスクにアクセスする必要がなくなり、データベースのパフォーマンスが大幅に向上することです。 持続性の定義永続性とは、トランザクションがコミットされると、データベースへの変更が永続的になり、その後の操作や障害がこのトランザクションの変更に影響を与えないことを意味します。 前回の紹介から、InnoDB はバッファ プールを使用して読み取りと書き込みのパフォーマンスを向上させることがわかりました。ただし、バッファ プールはメモリ内にあり、揮発性です。トランザクションがコミットされた後に MySQL が突然クラッシュし、その時点でバッファ プール内の変更されたデータがディスクに更新されていない場合、データは失われ、トランザクションの永続性は保証されません。 この問題を解決するために、InnoDB はデータ変更の永続性を実現する REDO ログを導入しました。データが変更されると、InnoDB はバッファー プール内のデータを変更するだけでなく、その操作を REDO ログに記録し、対応するページよりも前に (通常はトランザクションがコミットされたときに) REDO ログがディスクに書き込まれるようにします。これは WAL と呼ばれることがよくあります。 MySQL が突然クラッシュし、データがディスクにフラッシュバックされていない場合、再起動後、MySQL はディスクに書き込まれた REDO ログを使用して、ディスクにフラッシュされていないデータ ページを回復します。 実装原則: redo ログパフォーマンスを向上させるために、データ ページと同様に、REDO ログも 2 つの部分で構成されます。1 つは揮発性のメモリ内のログ バッファーで、もう 1 つは永続的なディスク上の REDO ログ ファイルです。 REDO ログは、データベース内の物理ページの状態を記録する物理ログです。 データが変更されると、InnoDB はバッファ プール内のデータを変更するだけでなく、その操作を REDO ログ バッファに記録します。トランザクションがコミットされると、REDO ログ バッファはディスクにフラッシュされ、REDO ログ ファイルに記録されます。 MySQL がクラッシュした場合は、再起動時に REDO ログ ファイルのデータを読み取ってデータベースを復元できます。この方法では、トランザクションが送信されるたびにデータをリアルタイムでフラッシュする必要がなくなります。 執筆プロセス注記:
利点トランザクションがコミットされるとき、REDO ログに書き込むと、ログを直接フラッシュするよりも 3 つの主な利点があります。 フラッシュはランダム I/O ですが、REDO ログの書き込みはシーケンシャル I/O です。シーケンシャル I/O はランダム I/O よりもはるかに高速であるため、必要ありません。 最初に REDO ログを書き込む必要がありますか、それとも最初にデータを変更する必要がありますか?DML 操作には、データの変更と REDO ログの記録が含まれる場合があります。それらはどのような順序で実行されますか?インターネット上の記事の中には、まずデータを変更し、その後で REDO ログを記録するべきだと書いてあるものもありますが、一方で、まず REDO ログを記録し、その後でデータを変更するべきだと書いてあるものもあります。では、実際のところはどうなのでしょうか? まず、上記の説明から、トランザクションがコミットされたときに redo ログ バッファが redo ログ ファイルに書き込まれ、フラッシュはその後のいつか行われることがわかります。したがって、最初に redo ログが記録され、後でデータ ページが変更されることは確かです (もちろん、WAL ログが最初に書き込まれます)。 次の質問は、最初に REDO ログ バッファを書き込むか、最初にバッファ プールを変更するかです。この問題を理解するには、まず InnoDB での DML の実行プロセスを理解する必要があります。 DML の実行プロセスには、データの変更、ロック、ロック解除、REDO ログの記録、UNDO ログの記録が含まれ、これらにも原子性を保証する必要があります。InnoDB は、MTR (ミニトランザクション) を使用して、DML 操作の原子性を保証します。 まず、MTR の定義を見てみましょう。
MTR は短いアトミック操作であり、それ自体がアトミックであるためロールバックできません。データ ページへの変更は MTR を経由する必要があります。MTR は、DML 操作によって発生したデータ ページへの変更を REDO ログに記録します。 MTR プロセスを簡単に見てみましょう。
このことから、InnoDB はまずバッファ プールを変更し、次に REDO ログ バッファを書き込むことがわかります。 データの回復プロセスいずれの場合でも、InnoDB は起動時にリカバリ操作を実行しようとします。リカバリ プロセス中は、REDO ログが必要であり、binlog が有効になっている場合は、binlog と UNDO ログも必要です。データはバイナリログに書き込まれているが、REDO ログがディスクにフラッシュされる前にデータベースがクラッシュした可能性があります (トランザクションは InnoDB エンジンの機能であり、変更されたデータがコミットされない可能性がありますが、バイナリログは MySQL サービス レイヤーの機能であり、変更されたデータが記録されます)。このとき、コミットされていないトランザクションがあるかどうかを判断し、コミットされていないトランザクションをロールバックまたはコミットするために、REDO ログ、バイナリログ、および UNDO ログが必要です。 以下は、REDO ログのみを使用してデータを復元するプロセスの簡単な説明です。
LSNとは何ですか?LSN はログ シーケンス番号とも呼ばれ、単調に増加する 64 ビットの符号なし整数です。 REDO ログとデータ ページの両方に LSN が格納されており、これをデータ回復の基礎として使用できます。 LSN が大きいほど、参照されたログ レコードによって記述された変更が後で発生したことを示します。 チェックポイントとは何ですか?チェックポイントは保存ポイントを表し、このポイント (ログ LSN < チェックポイント LSN) より前のデータ ページへのすべての変更がディスク ファイルに書き込まれています。 InnoDB は、各ディスク フラッシュ後にチェックポイントを記録し、チェックポイント LSN に最新の redo ログ LSN を記録します。これは、データを復元するときに開始点を決定するのに便利です。 上記は、MySQL におけるトランザクションの永続性の実装原理の詳細な説明です。MySQL トランザクションの永続性の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
目次1. Windows システムでの Nginx のインストールと起動プロセス: 2. 起動時にN...
以下の内容では、隣接リストを使用してツリー構造を保存する MYSQL のプロセスとソリューションを紹...
この記事では、CentOS 7 環境でソース コードから MySQL 5.7 をインストールする方法...
この記事では主に、MySQL 8.0 ドライバーと Alibaba Druid バージョン間の互換性...
序文: Jenkins のマスター スレーブ分散アーキテクチャは、主に、Jenkins に単一ポイン...
この記事の例では、クールなフロントエンドページのスライド検証の具体的なコードを参考までに共有していま...
1.html <div class="ログインボディ"> <...
1 はじめにApache Storm は、Hadoop と同様に、大量のデータを処理するために使用で...
Linux のufw (Uncomplicated Firewall) を見て、ファイアウォールに変...
質問LINUX では、定期的なタスクは通常、cron デーモン プロセス [ps -ef | gre...
変数の宣言グローバル変数の設定@a='新しい変数' を設定します。関数やストアドプロ...
Vue3.0 がリリースされてからしばらく経ちましたが、勉強を始める必要があります。まず、達成したい...
Dreamweaver または FrontPage を使用して HTML Web ページを作成する場...
この記事の例では、画像の切り取りを実現するためのjsの具体的なコードを参考までに共有しています。具体...
シンプルなアプリケーションの展開1. ディレクトリ構造: └── Pythonpro #ディレクトリ...