MySQLの同時実行制御とトランザクションの原則に関する詳細な説明

今日のインターネットビジネスで最も広く使用されているデータベースは、間違いなくリレーショナルデータベースMySQLです。「または」という単語を使用する理由は、TIDB、OceanBaseなどの国内データベース分野も近年大きな進歩を遂げているためです。分散データベースですが、まだ絶対的なカバレッジを形成していないため、この段階では、作業中に発生したいくつかの問題に対処するためのMySQLデータベースの学習と、インタビュー中のデータベース部分の調査を継続する必要があります。

主要な工場からのドキュメントやより実際のインタビューの質問を整理するためのさまざまなナレッジポイントモジュールもあります。困っている友達は、以下のリンクをクリックして無料で入手できます。

リンク:1103806531パスワード:CSDN

ここに写真の説明を挿入

今日のコンテンツでは、MySQLデータベースの同時実行制御、トランザクション、およびストレージエンジンの主要な問題について説明します。このコンテンツに関連するナレッジグラフを次の図に示します。
ここに写真の説明を挿入

同時実行制御

同時実行制御は大きなトピックです。コンピュータソフトウェアシステムで同時にデータを変更する複数の要求がある限り、Javaのマルチスレッドセキュリティなどの同時実行制御の問題が発生します。MySQLの同時実行制御では、主に、データベースがテーブルデータの同時読み取りと書き込みを制御する方法について説明します。

たとえば、次の構造のテーブルuseraccountがあります。

ここに写真の説明を挿入
このとき、次の2つのSQLステートメントがデータベースへの要求を同時に開始した場合:

SQL-A:

update useraccount t set t.account=t.account+100 where username='wudimanong';

SQL-B:

update useraccount t set t.account=t.account-100 where username='wudimanong'

上記のステートメントを実行すると、正しい結果はaccount = 100になりますが、同時実行の場合、次の状況が発生する可能性があります。

ここに写真の説明を挿入
では、MySQLの同時実行制御はどのようになっていますか?実際、ほとんどの同時実行制御方法と同様に、ロックメカニズムは同時実行制御を実現するためにMySQLでも使用されます。

1.MySQLロックタイプ

MySQLでは、同時実行制御は主に「読み取り/書き込みロック」によって実現されます。

読み取りロック:共有ロックとも呼ばれ、複数の読み取り要求がロックを共有して、ブロックを発生させることなく同時にデータを読み取ることができます。

書き込みロック(書き込みロック):排他ロック(排他ロック)とも呼ばれます。書き込みロックは、ロックを取得する他のすべての要求を除外し、書き込みが完了してロックが解放されるまでブロックします。

読み取り/書き込みロックは、並列の読み取りと読み取りを実現できますが、並列の書き込み、読み取り、および書き込みを実現することはできません。後で説明するトランザクションの分離は、読み取り/書き込みロックに基づいています。

2.MySQLロックの粒度

上記の読み取り/書き込みロックは、MySQLのロックタイプに応じて分類され、読み取り/書き込みロックが課すことができる粒度は、主にデータベース内のテーブルと行に反映されます。これは、テーブルロックと行ロックとも呼ばれます。 )。

テーブルロック(テーブルロック):MySQLの最も基本的なロック戦略です。テーブル全体をロックするため、ロックを維持するためのオーバーヘッドは最小限に抑えられますが、テーブルの読み取りと書き込みの効率が低下します。ユーザーがテーブルロックを介してテーブルへの書き込み操作(挿入、削除、更新)を実装する場合、最初にテーブルをロックする書き込みロックを取得する必要があります。この場合、他のユーザーによるテーブルの読み取りと書き込みはブロックされます。 。通常の状況では、「altertable」などのステートメントはテーブルロックを使用します。

行ロック:行ロックは、最大の範囲で同時読み取りと書き込みをサポートできますが、データベース保守ロックのオーバーヘッドは比較的大きくなります。行ロックは、私たちの日常生活で最も一般的に使用されるロック戦略です。一般に、MySQLの行レベルのロックは、MySQLサーバーレベルではなく、特定のストレージエンジンによって実装されます(テーブルロックはMySQLサーバーレベルで実装されます)。

3.マルチバージョン同時実行制御(MVCC)

MVCC(MultiVersion Concurrency Control)、マルチバージョン同時実行制御。ほとんどのMySQLトランザクションエンジン(InnoDBなど)では、行レベルのロックは単純に実装されていません。そうでない場合、次のような状況が発生します。「データAがユーザー(行レベルの書き込みロックを取得)によって更新されている間、他のユーザーこのデータの読み取り(読み取りロックの取得)はブロックされます。」しかし、現実は明らかにそうではありません。これは、MySQLストレージエンジンが同時実行パフォーマンスの向上を考慮しているためです。MVCCデータマルチバージョン制御により、読み取りと書き込みの分離が実現され、データをロックなしで読み取り、読み取りと書き込みを並列に実行できます。

例として、InnoDBストレージエンジンのMVCC実装を取り上げます。

InnoDBのMVCCは、レコードの各行の後ろに2つの非表示の列を格納することによって実装されます。これらの2つの列のうち、1つは行の作成時間を保持し、もう1つは行の有効期限を保持します。もちろん、それらが保存するのは実際の時間値ではなく、システムのバージョン番号です。新しいトランザクションが開かれるたびに、システムバージョン番号が自動的にインクリメントされます。トランザクションの開始時のシステムバージョン番号は、クエリの各行のバージョン番号と比較するためのトランザクションのバージョン番号として使用されます。

MVCCがMySQLで依存している主な意味は、「ログの取り消しとビューの読み取り」です。

  • 元に戻すログ:元に戻すログは、データ行の複数のバージョンを記録するために使用されます。
  • ビューの読み取り:データの現在のバージョンの可視性を判断するために使用されます

元に戻すログは、トランザクションの後半で導入されます。MVCCの読み取りおよび書き込み原理の概略図は次のとおりです。

ここに写真の説明を挿入
上の図は、MySQL InnoDBストレージエンジンを示しています。REPEATABLEREAD(繰り返し可能読み取り)トランザクション分離レベルでは、MVCCは、ほとんどの読み取り操作を行う2つの追加のシステムバージョン番号(行作成バージョン番号、行削除バージョン番号)を保存することによって実装されます。読み取りロックを追加する必要はありません。この設計により、データの読み取り操作がより簡単になり、パフォーマンスが向上します。

では、MVCCモードでのデータ読み取り操作により、データが正しく読み取られるようにするにはどうすればよいでしょうか。InnoDBを例にとると、レコードの各行は、選択時に次の2つの条件に従ってチェックされます。

  • バージョン番号が現在のトランザクションバージョン以下のデータ行のみを検索します。これにより、トランザクションによって読み取られた行が、トランザクションの開始前に存在していたか、トランザクション自体によって挿入または変更されたことが保証されます。
  • 行の削除バージョン番号が未定義であるか、現在のトランザクションバージョン番号よりも大きいです。これにより、トランザクションによって読み取られた行が、トランザクションの開始前に削除されないことが保証されます。

クエリの結果として返されるのは、上記の2つの条件を満たすレコードのみです。図に示すロジックを例にとると、書き込み要求でアカウントを200に変更するプロセスで、InnoDBは新しいレコード(account = 200)を挿入し、現在のシステムバージョン番号を行作成バージョン番号(createVersion = 2)として使用します。同時に、現在のシステムバージョン番号がバージョン番号を削除するための元の行として使用され(deleteVersion = 2)、次のように、このデータのデータコピーには2つのバージョンがあります。

ここに写真の説明を挿入

書き込み操作が終了しておらず、トランザクションが一時的に他のユーザーに表示されていない場合、選択チェック条件に従って、accout = 100のレコードのみが条件を満たしているため、クエリ結果はaccount = 100のレコードを返します。

上記のプロセスは、MVCCの実装に関するInnoDBストレージエンジンの基本原則ですが、後でMVCCのロジックに注意を払う必要があります。マルチバージョン同時実行制御は、「REPEATABLE READ(繰り返し可能読み取り)」と「READCOMMITED(コミット読み取り)」の2つのトランザクション分離レベルでのみ機能します。 。他の2つの分離レベルは、MVCCと互換性がありません。これは、READ UNCOMMITED(コミットされていない読み取り)が、現在のトランザクションバージョンに準拠するデータ行ではなく、常に最新のデータ行を読み取るためです。SERIALIZABLEは、すべての読み取り行に追加されます。ロックはMVCCの考え方に準拠していません。

総括する

時間の制約により、詳細は記載されていません。MySQLトランザクションの後半とMySQLストレージエンジンは表示されません。フルバージョンが必要な友達は、以下のリンクをクリックして無料で入手できます。

リンク:1103806531パスワード:CSDN

ここに写真の説明を挿入
ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_48655626/article/details/109117233