序文 最近、面接中に、MySQL の InnoDB エンジンがどのようにトランザクションを実装しているか、または ACID 機能をどのように実装しているかを尋ねられました。その時は良い答えができなかったため、自分なりに要約して記録しました。 ACIDトランザクションの4つの特徴 トランザクションの 4 つの主要な特性は、ACID、A-原子性、C-一貫性、I-独立性、および D-永続性です。一貫性は最終的な目標であり、原子性、分離性、永続性は一貫性を確保するための手段です。つまり、私が書いた順序は ACID に基づいていません。一貫性を最後に置いたため、順序は ADIC になります。 原子性(A) アトミック性とは、トランザクションが分割できない作業単位であることを意味します。中間状態はなく、トランザクションの一部のみが実行されることなく、すべてが正常に実行されるか、すべてが失敗します。 MySQL の InnoDB エンジンは、元に戻すログ (ロールバック ログ) を通じて実装されており、トランザクションがロールバックされたときに、正常に実行されたすべての SQL ステートメントが元に戻されることを保証できます。 UNDO ログは、SQL 実行に関連する情報を記録する論理ログです。トランザクションによってデータベースが変更されると、InnoDB は対応する UNDO ログを生成します。トランザクションの実行に失敗した場合、またはロールバックが呼び出されてトランザクションがロールバックされた場合、InnoDB エンジンは、UNDO ログ内のレコードに基づいてデータを以前の状態にロールバックします。 持続性(D) 永続性とは、トランザクションがコミットされると、データベースに対する操作が永続的になり、その後の他の操作や異常な障害がそれに影響を与えないことを意味します。 そのため、InnoDB は MySQL 用のバッファ プールを提供し、そこにディスク上のいくつかのデータ ページのマッピングが含まれます。 バッファ プールは MySQL の読み取りと書き込みの効率を向上させますが、新たな問題ももたらします。つまり、データがバッファ プールに更新されたばかりで、まだディスクに更新されていないときに MySQL が突然クラッシュすると、データが失われ、トランザクションの耐久性が保証されなくなります。 トランザクションがコミットされると、REDO ログがディスクに同期されるため、MySQL がクラッシュしても、REDO ログをディスクから読み取ってデータを回復することができ、トランザクションの永続性が保証されます。 REDO ログは、ログを記録するために事前書き込み方式を使用します。つまり、最初にログが記録され、次にバッファー プールが更新されます。これにより、データが REDO ログに保存されている限り、ディスク上に保存されることが保証されます。 これには説明が必要です。REDO ログもディスクに書き込まれ、フラッシュもディスクに書き込まれます。直接フラッシュするのではなく、最初に REDO ログを記録する必要があるのはなぜですか? 主な理由は、REDO ログがフラッシュよりもはるかに高速であることです。 1 つ目のポイントは、REDO ログは追加操作ログであり、シーケンシャル IO であるのに対し、ダーティ フラッシュは、毎回更新されるデータが必ずしも隣接しているわけではない、つまりランダムであるため、ランダム IO であるということです。 2 つ目のポイントは、ダーティ フラッシュがデータ ページ単位で行われることです (つまり、毎回少なくとも 1 ページ分のデータがディスクからメモリに読み込まれるか、少なくとも 1 ページ分のデータがディスクにフラッシュされます)。MySQL のデフォルトのページ サイズは 16KB です。ページを変更する場合は、ページ全体をディスクにフラッシュする必要があります。また、REDO ログには、実際にディスクに書き込む必要がある操作ログのみが含まれます。 MySQL には、binlog と呼ばれる操作を記録するログもあります。では、redo ログと binlog の違いは何でしょうか?
REDO ログは、MySQL がクラッシュしてもトランザクションの永続性が影響を受けないように更新キャッシュを記録するために使用されます。バイナリ ログは、主に時点を指定して、どの操作がいつ実行されたかを記録し、データを特定の時点に復元できることを保証するために使用されます。また、データのマスター スレーブ同期にも使用されます。
REDO ログはストレージ エンジン InnoDB によって実装されます (MyISAM には REDO ログがありません)。一方、バイナリ ログは MySQL サーバー レベルの他のストレージ エンジンでも使用できます。
デフォルトでは、トランザクションがコミットされると、REDO ログはディスクにフラッシュされます。パラメータ innodb_flush_log_at_trx_commit によってポリシーを変更できるため、REDO ログは、トランザクションがコミットされるまで待機せずにディスクにフラッシュされます。 隔離(I) アトミック性と耐久性はどちらも単一のトランザクションに基づく尺度ですが、独立性は複数のトランザクションが互いに分離され、互いに影響を及ぼさないという特性です。
ロック機構 MySQLのロックは主に 機能に応じて:読み取りロックと書き込みロック。アクションの範囲に応じて:テーブルレベル ロックと行レベル ロック。 読み取りロック: 「共有ロック」とも呼ばれ、複数のトランザクションがロックを共有し、データにアクセスすることはできても変更することはできないことを意味します。 書き込みロック: 「排他ロック」とも呼ばれ、他のトランザクションとデータを共有できません。トランザクションがデータの一部に対して排他ロックを取得した場合、他のトランザクションは、共有ロックや排他ロックなど、その行に対して他のロックを取得できません。 テーブル レベル ロック: テーブル全体をロックすることを意味しますが、パフォーマンスは低下します。ストレージ エンジンによってサポートされるロックの粒度は異なります。MyISAM エンジンはテーブル レベル ロックをサポートし、InnoDB エンジンはテーブル レベル ロックと行レベル ロックの両方をサポートします。 行レベルのロック: 操作が必要な対応する行がロックされ、パフォーマンスが向上します。 インテンション ロック: インテンション ロックはテーブル レベルのロックです。トランザクションがすでにテーブル内の特定のデータに排他ロックまたは共有ロックを追加している場合は、インテンション ロックを追加できます。このようにして、次のトランザクションがテーブルをロックしようとしたときに、インテンション ロックがすでに存在することが判明すると、最初にブロックされます。インテンション ロックが追加されていない場合、2 番目のトランザクションがテーブルをロックしようとしたときに、ロックされているデータがあるかどうかを確認するために、一度に 1 行ずつトラバースする必要があります。 ギャップ ロック: ギャップ ロックは、ファントム リードを防ぐために追加されるロックです。ギャップ ロックは、2 つのインデックス レコード間、または最初のインデックス レコードの前または最後のインデックス レコードの後のスペース (現在のレコードは含まれません) にある、存在しない空き領域に追加されます。これにより、ギャップ ロックが実行されると、新しく追加されたデータがブロックされ、トランザクション内の 2 つのクエリによって取得されるレコード数が一定になります。 次のキー ロック: 次のキー ロックは行レベル ロックとギャップ ロックの組み合わせです。ギャップ ロックは現在のレコードをロックしませんが、次のキー ロックは現在のレコードもロックします。 たとえば、テーブルに 3 つのレコードがある場合:
次に、SQL を実行すると: select * from table where number = 17 for update、ギャップ ロックがロックされます。番号の範囲は (16, 17)、(17, 20) ですが、Next-Key Lock は次のようにロックします: ロック メカニズムは複数のトランザクション間の書き込み操作の分離を保証しますが、複数のトランザクション間の読み取りおよび書き込み操作の保証は MVCC メカニズムによって保証される必要があります。 MVCC メカニズム
MVCC は主に、各レコード行に隠し列を追加し、元に戻すログを使用することで実装されます。隠し列には主に、データ行によって作成されたバージョン番号 (増分)、削除時間、元に戻すログへのポインタなどが含まれます。 では、MVCC はどのようにして読み取りと書き込みの分離を保証するのでしょうか?主に、スナップショット読み取りと現在の読み取りという 2 つの操作を使用します。
同時実行の効率性を確保するために、MVCC はデータの読み取り時にロックを行いません。select (ロックなしの通常の select) を実行すると、最初に現在のデータのバージョン番号が読み取られます。select が結果を返す前にトランザクションがこのデータ行を変更すると、バージョン番号は select が実行されたときよりも大きくなります。したがって、select によって読み取られるデータの一貫性を確保するために、現在のバージョン以下のデータのみが読み取られます。この履歴バージョンのデータは、undo ログから取得されます。
挿入、更新、または削除を実行すると、最新バージョンのデータが読み取られ、操作中に他のトランザクションによってバージョン番号が変更されないように、現在のレコードがロックされます。 たとえば、通常の選択はスナップショット読み取りであり、読み取られるのはデータの履歴バージョンである可能性があります。 挿入、更新、削除、選択...共有モードでロックし、選択...更新の場合は現在のデータを読み取ります。つまり、最新バージョンのデータを読み取ります。 実際、分離レベルを Serializable に設定することでも読み取り/書き込み分離を実現できますが、同時実行効率が大幅に低下するため、一般的にはほとんど使用されません。ただし、MVCC は読み取り時にロックせず、書き込み時にのみロックするため、同時実行効率が向上します。 MVCC メカニズムは、複数のトランザクション間の読み取り/書き込み分離を保証し、それによってトランザクション分離を実現します。 一貫性(C) 一貫性とは、トランザクションが実行される前と実行された後のデータの一貫性を指します。トランザクションの前後のデータの整合性は破壊されておらず、データの状態は合法です。
インデックスの整合性(一意のインデックス、重複なしなど)、データ列の完了(フィールドタイプ、長さ、サイズが要件を満たしている)、外部キー制約など。
原子性、永続性、独立性を保証します。これらの特性が保証できない場合、一貫性も保証できません。データベースレベルでは、上記の機能の保証に加えて、フィールドの一貫性を確保するための対策があります。たとえば、整数文字を渡すことはできませんし、文字列の長さや時間形式などは列制限を超えることはできません。ただし、開発者自身がアプリケーション レベルでこれを保証する必要があります。 さらに、MySQL は 2 フェーズ トランザクション コミットを通じて、REDO ログと binlog 間のデータの一貫性も保証します。 上で永続性を紹介したとき、REDO ログと binlog の違いについて説明しました。3 番目の違いは、デフォルトでは、トランザクションがコミットされると、REDO ログと binlog の両方が書き込まれるという点です。では、どのように一貫性が調整されるのでしょうか。トランザクションが正常にコミットされたかどうかを判断するために書き込まれるログはどれですか?
再実行ログをディスクに送信し、状態を準備状態に変更します。バイナリログに対して操作を実行しないでください。
1. トランザクション操作のバイナリログを生成し、そのバイナリログをディスクに書き込みます。 2. エンジンのトランザクション コミット インターフェイスを呼び出して、REDO ログのステータスを準備からコミットに変更し、トランザクションがコミットされます。 要約する MySQL トランザクションの ACID と一貫性が最終的な目標です。
上記は、MySQL がトランザクションの ACID を実装する方法の詳細です。MySQL がトランザクションの ACID を実装する方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Vueモバイル端末に最適な適応ソリューションについての簡単な説明
>>: Linux gzip コマンドのファイル圧縮実装原理とコード例
目次1. はじめに2. インターフェース3. 簡単な例4. 結論1. はじめにMDN の公式 Web...
ユーザーグループLinux では、すべてのユーザーはグループに属する必要があり、Linux には次の...
目次1. Docker の 2375 ポートを別のポートに変更します。これは一時的な対策にすぎません...
この記事では、MySQL 8.0.12のインストールされていないバージョンを設定して起動するための具...
シナリオ: laradock 開発環境 (php7.3+mysql5.7) がローカルに構築されてい...
設置環境WIN10 VMware Workstation Pro 15.0.0 ビルド 101344...
序文403 クロスオリジン エラーが発生しNo 'Access-Control-Allow-...
注意: docker-compose.yml ファイルを書き込むときは、すべてのコロン (:) とダ...
1. 最初の方法は、ローカルのTomcatを起動してJSPを表示することです。 tomcatのweb...
xhtml+css のウェブサイト再構築、ウェブ標準などについては、記事が多すぎるので繰り返しません...
ウェブサイトにとって、これは最も基本的な機能です。それでは、登録プロセスに含まれる手順を見てみましょ...
1: 速度と読み込み方法の違いdivとtableの違いは速度ではなく、読み込み方法です。速度はネット...
最近、MySQL を使用してテーブル データを Excel ファイルにエクスポートしました。MySQ...
目次1.Nuxtサーバーサイドレンダリングアプリケーションの展開(SSRサーバーレンダリング)利点:...
「私たちは次の一連のモバイル製品を HTML5 で作成しています。」 「ええ、最近は多くの人が Ap...