この記事の目的は、これらの概念とその機能の関係を明らかにすることです。 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をカウントする方法の詳細な説明
序文スロークエリとは何か、またスロークエリを最適化するにはどうすればよいか。以下では、これら 2 つ...
目次序文:ステップ1: 無料の天気予報インターフェースを見つけるステップ2: 天気予報インターフェー...
目次1. 現象2. 解決策3. 要約: 1. 現象1. 要件: 特定の表示ページをキャプチャしてアル...
この記事では、画像の一時停止を実現するためのjQueryプラグインの具体的なコードを参考までに共有し...
この質問をされたとき、私は無知で頭が真っ白になりました。もちろん、正しく答えられませんでした。私はず...
1. 約束の説明Promise は、非同期操作の最終状態 (失敗または正常完了) とその結果の値を...
テーブルを画面全体(残りの空白領域)に表示するために、幅属性は 100% と定義されることが多く、セ...
簡単に言うと、distinct は重複を削除するために使用され、group by は統計を集計するよ...
目次1. CSS のみを使用して作成したアニメーションのクリスマスツリー2. CSS のみを使用して...
1. Pythonのインストール1. フォルダーを作成します。 mkdir python フォルダ...
需要背景ビジネス テーブル tb_image のデータの一部は次のとおりです。id は一意ですが、i...
良いアイデアを見つけたので記録しました。私は以前、スクロール効果を実現するためにjQueryを使用し...
序文効率的なSQL文の書き方は、Explain実行計画の分析と切り離せません。実行計画とは何か、効率...
序文Bash には、ls、cd、mv などの重要な組み込みコマンドが多数あるほか、grep、awk、...
デフォルトでは、CentOS 7 上の PHP は apache または nobody として実行さ...