#その他の関連する無料学習の推奨事項:mysql チュートリアル (ビデオ)
MySQL は自動を使用します。」デフォルトでは送信 ( AUTOCOMMIT) モードです。つまり、トランザクションを明示的に開始しない場合、各クエリはコミット操作を実行するトランザクションとして扱われます。現在の接続では、自動コミット モードを有効または無効にするには、 AUTOCOMMIT 変数”
永続性 トランザクションが正常にコミットされると、データベースへの影響は永続的になります。この時点でシステムがクラッシュしても、変更されたデータは失われません。 InnoDBはMySQLのストレージエンジンであり、データはディスク上に保存されますが、データの読み書きに毎回ディスクIOが必要となると効率が非常に悪くなります。このため、InnoDB はデータベースにアクセスするためのバッファーとしてキャッシュ (バッファー プール) を提供し、データベースからデータを読み取るときは、まずバッファー プールから読み取ります。バッファー プールにない場合は、それが読み込まれます。データをディスクからバッファ プールに書き込みます。データベースにデータを書き込むときは、最初にバッファ プールに書き込まれ、バッファ プール内の変更されたデータが定期的にディスクに更新されます。
このような設計では、対応する問題も発生します。データが送信され、データがまだバッファ プール内にある場合 (ディスクがまだフラッシュされていない場合)、MySQL がダウンしたり電源が失われた場合はどうすればよいでしょうか?データは失われますか?
答えは「いいえ」です。MySQL は redo_log メカニズムを通じて耐久性を保証します。 redo_log は redo log です。簡単に言うと、データが変更されると、バッファー プール内のデータの変更に加えて、操作も redo_log に記録されます。トランザクションが送信されると、fsync インターフェイスが記録されます。 redo_log. プレートをフラッシュするために呼び出されます。 MySQL がダウンした場合、redo_log 内のデータを読み取り、再起動時にデータベースを回復できます。
簡単に言えば、分離レベルは、トランザクション内のデータの変更、どのトランザクションが表示され、どのトランザクションが表示されないかを規定します。分離とは、複数の同時読み取りおよび書き込み要求のアクセス シーケンスを管理することです。
MySQL 分離の具体的な実装については後で説明します。具体的には:
また、Next-Key ロックを使用することで、ファントム読み取りの問題もある程度解決できます。 。これについては後で説明します。
この分離レベルでは、トランザクションはシリアルに実行されます。 自動コミットが無効になっている場合、InnoDB はすべての通常の SELECT ステートメントを暗黙的に SELECT ... LOCK IN SHARE MODE に変換します。つまり、読み取り共有ロックが読み取り操作に暗黙的に追加されるため、ダーティ読み取り、反復不可能な読み取り、ファントム読み取りの問題が回避されます。
一般的に使用されている MySQL を例に挙げると、MySQL の InnoDB エンジンは MVCC を実装しています。マルチバージョン同時実行制御 (MCC または MVCC) は、データベースへの同時アクセスを提供するためにデータベース管理システムによって一般的に使用される同時実行制御方法であり、トランザクション メモリ (MCC または MVCC) を実装するためにプログラミング言語で使用される同時実行制御方法です。データベースを構築し、プログラミング言語でトランザクション ストレージを実装します。
簡単に言えば、これはデータベースが同時実行性を制御するために使用する方法です。各データベースには、MVCC の実装が異なる場合があります。
MVCC はどのような問題を解決できますか?
次の図は、「High Performance MySQL」(第 3 版) からのものです
この本はよく書かれ、よく翻訳されています。私の最初の MySQL の体系的な理解も、この本を読んだおかげです。しかし、個人的には、MVCC の実装方法の説明にはいくつかの問題があると思います。
問題がどこにあるのか見てみましょう
まず、MySQL の公式ドキュメントを見てみましょう。 5.6、および 5.7。document[1] の 2 つのバージョンにおける MVCC のこの部分の説明は、ほぼ同じです。
ドキュメントによると、各データに 3 つの非表示列が追加されていることは明らかです。
その前に、 undo_log の概念について話しました。各 undo ログには、roll_pointer 属性があります。その後、すべてのバージョンは、roll_pointer 属性によってリンク リストに接続されます。このリンク リストをバージョン チェーンと呼びます。バージョン チェーンのヘッド ノードは、最新の値です現在のレコードの。
読むビューカラムとバージョン チェーンを非表示にすることで、MySQL はデータを指定されたバージョンに復元できますが、具体的にどのバージョンに復元するかは ReadView に基づいて決定する必要があります。いわゆる ReadView とは、トランザクション (トランザクション A として記録される) がある瞬間にトランザクション システム全体 (trx_sys) のスナップショットを取得することを意味し、後で読み取り操作が実行されるときに、読み取られたデータ内のトランザクション ID と比較されます。 trx_sys スナップショットを使用して、データが ReadView に表示されるかどうか、つまりトランザクション A に表示されるかどうかを判断します。 これまでのところ、MVCC は隠しフィールド、undo_log チェーン、ReadView に基づいて実装されていることがわかりました。 Read commit 分離レベルで MVCC を使用するソリューションについては前に説明しました。ダーティリードの問題。
ここでは 2 つの記事を参照します: InnoDB は、バージョンが現在のトランザクション バージョンよりも古いデータ行のみを検索します (つまり、行のバージョン番号はトランザクション バージョンのシステム バージョン番号以下)、これにより、データによって読み取られた行がトランザクションの開始前にすでに存在しているか、トランザクション自体によって挿入または変更されたことが保証されます。 したがって、ダーティリードは発生しません。 読み取りがコミットされました 分離レベルでの反復不可能な読み取りの発生は、読み取りビューの生成メカニズムが原因です。 Read commit レベルでは、現在のステートメントが実行される前にコミットされたデータが表示されます。各ステートメントの実行中に、読み取りビューが閉じられ、現在の読み取りビューが再作成されます。このようにして、読み取りビューのトランザクション間隔は、現在のグローバル トランザクション リストに基づいて作成できます。簡単に言えば、読み取りコミット分離レベルでは、MVCC は選択ごとにスナップショット バージョンを生成するため、各選択では異なるバージョンのデータが読み取られるため、したがって反復不可能な読み取りが発生します。 コミットされた読み取りとは異なり、反復読み取りの分離レベルでは、トランザクションが作成されると、現在のグローバル読み取りビューが生成され、トランザクションが終了するまで維持されます。これにより、反復読み取りが可能になります。 snapshot read (スナップショット読み取り) と呼び、現在のバージョンのデータベース データを読み取る方法を current read (現在の読み取り) と呼びます。 Reference[3] におけるファントム リーディングの問題を解決するには、MySQL を使用します。トランザクションはネクストキーロックを使用します。 反復読み取りは、ネクスト キー ロック メカニズムによるファントム読み取りを回避します。 InnoDB ストレージ エンジンには、次の 3 つの行ロック アルゴリズムがあります。
Read commit の MVCC
#Repeatable read の MVCC
Repeatable Read 分離レベルは、トランザクション内の繰り返し不可能な読み取りの問題を解決します。複数の読み取り異なる結果が生成されることはなく、反復可能な読み取りが保証されます。前回の記事では、Repeatable readには2つの実装方法があり、1つは悲観的ロック方法、その逆のMVCCは楽観的ロック方法であると述べました。 反復可能な読み取り分離レベルによって反復不可能な読み取りの問題が解決できる根本的な理由は、実際には、読み取りビューの生成メカニズムがコミットされた読み取りの生成メカニズムと異なるためです。
#ファントムリードとネクストキーロック
現在のリードとスナップショット読み取り
MVCC メカニズムを通じて、データは繰り返し読み取ることができますが、読み取るデータはデータベースの現在のデータではなく、過去のデータや時期外のデータである可能性があります。データ!この履歴データの読み取り方法を
現在の読書
InnoDB がインデックス レコードをスキャンすると、最初に行ロック (レコード ロック) がインデックス レコードに追加され、次にギャップ ロック (ギャップ ロック) がインデックス レコードの両側のギャップに追加されます。ギャップ ロックを追加すると、他のトランザクションはこのギャップ内のレコードを変更したり挿入したりできなくなります。 クエリされたインデックスに一意の属性が含まれている場合、Next-Key Lock は最適化され、範囲ではなくインデックス自体のみをロックする Record Lock にダウングレードされます。
以上がMySQL のロック、トランザクション、MVCC についての簡単な理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。