この記事の目的は、これらの概念とその機能の関係を明らかにすることです。 Mysql がトランザクションを開くときの、各 SQL ステートメントのロック操作と MVCC バージョン制御を理解します。議論を簡潔にするために、この記事では GAP ロック (ギャップ ロック、範囲ロック) は無視します。 多くの場合、高い同時実行性と高い可用性が求められます。質と量の観点から評価することを意味します。何でもこの2つの観点から分析することができます。 MySQL データベースでは、品質を確保するためにトランザクションが使用され、量を確保するために MVCC が使用されます。 取引トランザクションを使用して、各 SQL ステートメントの結果が期待どおりに実行されるようにします。トランザクションには ACID プロパティが必須であると言われています。 ACID の 3 つ、つまり原子性、一貫性、永続性は、実際には同じことを表しており、SQL 実行結果の信頼性を保証します。分離はより複雑です。同時実行シナリオにおけるデータベースのパフォーマンスを表します。ただし、同時実行の量は固定されておらず、ビジネスによって要件が異なる場合があります。データベースをさまざまな同時実行シナリオに適応させるために、優れた人々が 4 つの分離レベルを定義しました。Read Uncommitted、Read Committed (RC)、Repeatable Read (RR)、および Serializable です。データベースの分離レベルが高くなると、データの同時実行能力は低下します。 分離レベル標準分離レベルでのデータベースの動作については、https://www.jb51.net/article/116477.htm を参照してください。ここでは、共有ロックと排他ロック、読み取りと共有ロック、書き込みと排他ロックの概念についてのみ説明します。 RC 分離レベルでは、データが変更されると排他ロックが追加されます。トランザクションが終了するとロックが解除され、他のトランザクションはロックを読み取ることができなくなるため、ダーティ リードの問題が解決されます。 (共有ロックはその場で解除されます) 実際、すべての操作はシリアル化されています。そして、Mysql はそれを最適化しました。1 つのトランザクションが読み取り中は、他のトランザクションは書き込みできません。また、1 つのトランザクションが書き込み中は、他のトランザクションは読み取りできません。これを実行しなくても、ダーティ リードと非反復読み取りの問題を解決することができます。 MVCCが登場しました。 (これにより、問題はますます複雑になり、RR 分離レベルで違いが現れ始めます。MySQL のデフォルトの分離レベルは RR です。) MVCCMVCC はマルチバージョン同時実行制御の略で、デュアルバージョン番号を使用してデータ分離の問題を解決します。 (「作成」にはバージョン番号があり、「削除」にもバージョン番号があり、変更操作は「削除」と「作成」に分かれています) 各トランザクションは、各テーブルの追加、削除、変更、およびクエリを開始するときにバージョン番号を生成します。各トランザクションは、このバージョン番号より小さい「作成」番号と、このバージョン番号より大きい「削除」番号を持つデータのみをクエリできます。この方法では、追加、削除、チェックの操作を同時に実行でき、変更操作のみをキューに入れる必要があります。この方法では、共有ロックがなくても、他のトランザクションがデータを変更した後、データのバージョン番号が自分のものより大きくなり、読み取らなくなるため、繰り返し不可能な読み取りの問題が解決されます。 RR 分離レベルでの MVCC 同時実行MVCC の導入後、すべてが順調に進んでいるようです。しかし、2 つのトランザクションがデータを次々に更新し、そのデータを再度読み取るときに、何を読み取るかについて考えたことがありますか?ハハ、これは起こり得ないことです。変更操作はシリアルであり、別のトランザクションがこのトランザクションをコミットしてからでないと変更できません。では、質問を変えましょう。2 つのトランザクションが、データに対して +1 操作を連続して実行します。他のトランザクションがコミットされた後、このトランザクションは再度 +1 を実行し、データを再度読み取ります。このトランザクションは +1 または +2 のどちらの結果を読み取りますか? +2 が読み取られると、分離が破壊され、他のトランザクションによって送信されたデータが読み取られるのではないでしょうか。 しかし、これは確かにその通りです。他のトランザクションも送信されており、このトランザクションもデータを変更しています。もちろん、その後に+2を読む必要があります。元々0だったのに、今回の取引で1しか増えなかったのに、読んでみたら2になってしまい、ちょっと違和感があります。実際、標準の RR 分離レベルでは、すべての操作がシリアルであるため、このトランザクションがデータ行を読み取った後、他のトランザクションはこのデータを変更できません。このデータは常にこのトランザクションによってのみ操作されるため、分離は厳密に満たされます。ただし、MySQL の RR は読み取りと書き込みの同時実行性を強化します。2 つのトランザクションが同時にデータの一部を変更する場合にのみ、それらをシリアル化する必要があります。その他のすべての操作は並列で実行できます。つまり、この結果が引き起こされるのは、繰り返し不可能な読み取りが発生したためと思われます。しかし、この繰り返し不可能な読み取りは、実は私たちの直感と一致しています。このトランザクションでデータが変更された後は、当然ながら最新のデータを読み取る必要があります。 プロセスを分析するには: データ作成バージョン番号は0です トランザクション 1 のバージョン番号は 1、読み取りデータ値 = 0 トランザクション2のバージョン番号は2、変更されたデータ値+1=1、元のデータの削除バージョン番号は2、新しいデータの作成バージョン番号は2に更新され、コミットされます。 トランザクション 1 はデータ値 + 1 = 2 を変更します。(変更は現在の読み取りであるため、バージョン番号が最も大きいデータが常に読み取られ、読み取られる値は 1 になります。) 変更後、削除バージョン番号は 1 になります。 新しいデータ作成バージョン番号は1です このトランザクションはデータ値=2を読み取ります 詳細な分析: 実は、上記の説明にも抜け穴があります。3 番目のトランザクション バージョン番号 3 があったらどうなるでしょうか?バージョン番号が 3 なので、トランザクション 1 と 2 のコミットされていないデータを直接読み取ることができますか?実際、MVCC では、各トランザクションには最小の表示バージョン low_limit_id もあります (トランザクション番号 >= low_limit_id のレコードは現在のトランザクションには表示されません)。これにより、現在実行中だがコミットされていないトランザクションが除外されます。たとえば、トランザクション 3 の場合、バージョン番号は 3 ですが、low_limit_id = 1 であるため、トランザクション 1 と 2 によって行われた変更は 3 には表示されません。 要約する 分離問題を解決するために、データを完全にコピーするなどの愚かな方法は使用されませんでした。従来のデータベースでは、共有ロックと排他ロックを使用して読み取り操作と書き込み操作をシリアル化していました。一方、MySQL では MVCC と排他ロックを使用して、読み取り操作と書き込み操作を並列で実行できます。 Mysql は、RR 未満の分離レベルでは従来の方法と同じように動作します。分離レベル RR では従来の方法とは異なります。これは、トランザクションがデータの一部を更新した後、他のトランザクションによってそのデータの一部にコミットされた変更を読み取ることができるという事実に反映されています。 以下もご興味があるかもしれません:
|
<<: Docker に Kong ゲートウェイをインストールする方法の例
>>: NGINXがウェブサイトのPV、UV、独立IPをカウントする方法の詳細な説明
関数の起源最近、水平スクロール バーを必要とする H5 に取り組んでいました。いくつかのドキュメント...
システム環境: Win10 64ビットMySQL バージョン: mysql-5.7.18-winX6...
故障したストレージ ドライブからデータを救出する場合でも、アーカイブをリモート ストレージにバックア...
目次一般的な圧縮形式: gz .bz2 .xz .zip一般的に使用されるアーカイブは圧縮を必要とす...
この記事の例では、ショッピングカートの計算を実装するためのjsの具体的なコードを参考までに共有してい...
日常の開発タスクでは、データ テーブル内のグループ化フィールドに基づいて統計データを取得するために、...
HTML Police がコードを調べて意味のないタグをすべて見つけ出すので、注意を払う必要がありま...
まず効果図を見てみましょう: 完全なコードは添付されています <テンプレート> <...
目次継承ES5 プロトタイプ継承ES6 クラス継承両者の違いES5プロトタイプ継承の内部実装ES6 ...
具体的なコードは次のとおりです。 <!DOCTYPE html> <html>...
誰についてシステムにログインしているユーザーを表示します。 who コマンドを実行すると、現在システ...
1. CSS3アニメーション☺CSS3 アニメーションは、JavaScript を介して要素のスタイ...
この記事では、マウスがドロップダウンボックスの上を通過するときにドロップダウンボックスを表示するため...
目次VARCHAR 型と CHAR 型結論: VARCHAR 型と CHAR 型VARCHAR と ...
この記事では、DingTalkの勤怠カレンダーを実装するためのVueの具体的なコードを参考までに共有...