序文データベース トランザクションに関して言えば、トランザクションの 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 の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
この記事では、ネストされたタブ機能を実装するためのjQueryの具体的なコードを参考までに紹介します...
目次使用シナリオ解決1. globalDataを使用して実装する2. ローカルキャッシュストレージを...
初心者は、いくつかの HTML タグを理解することで HTML を学習できます。この入門書は、初心者...
目次まず、スクロール バーのスタイルを変更するには、疑似要素-webkit-scrollbarを使用...
説明するこのインターフェースを呼び出すときは、次の点に注意する必要があります。パブリック IP アド...
1 Dockerサービスを開始するまず、docker サービスを開始する方法を知っておく必要がありま...
目次1. ダウンロード2. インストール3. my.ini ファイルを設定する(デフォルトのエンコー...
今日は、Linux ホスト上で 4 つの MySQL データベースを起動する方法について説明します。...
この記事では、ウィンドウ表示効果を実現するためのJavaScriptの具体的なコードを参考までに紹介...
序文フロントエンドページを書くとき、小さなアイコンなどの画像を使うことが多いです。画像を使うとコード...
初心者は、いくつかの HTML タグを理解することで HTML を学習できます。この入門書は、初心者...
Unix/Linux システムの nobody ユーザーとは何ですか? 1. Windows システ...
最近、React プロジェクトで初めてhtml-webapck-pluginプラグインを使用しました...
目次1. リバースプロキシの準備1. LinuxシステムにTomcatをインストールする2. Tom...
1. 複数の国境[1]背景: ボックスシャドウ、アウトライン使用シナリオの多様性を考慮すると、複数の...