【ロック機構】MySQLのロック機構

1. グローバルロック

グローバル ロックはデータベース インスタンス全体をロックするもので、グローバル ロックが追加されるとデータベース全体が読み取り専用状態になります。グローバル ロックの使用シナリオは、データベースをバックアップすることです。

2. テーブルレベルのロック

テーブルレベルのロックには、テーブル ロックとメタデータ ロック (メタ データ ロック、MDL) の 2 種類があります。

2.1 テーブルロック

テーブルロックの構文はlock tables … read/writeです。たとえば、次のステートメントを実行します。

lock tables t1 read,t2 write;

読み取りロックがテーブル t1 に追加され、書き込みロックがテーブル t2 に追加されることを示します。現時点では、他のスレッドは t1 の読み取りのみが可能で、 t1 の書き込みはできず、 t2 の読み取りと書き込みもできません同時に、現在のスレッドは t1 の読み取り、t2 の読み取りと書き込みのみが可能で、他のテーブルにはアクセスできません。

2.2 メタデータのロック

メタデータ ロック (MDL とも呼ばれます) は、テーブルにアクセスするときに自動的に追加されます。テーブルの追加、削除、変更、クエリを実行する場合は、MDL 読み取りロックを追加し、テーブルの構造を変更する場合は、MDL 書き込みロックを追加します。

注: MDL 読み取りロックは相互に排他的ではありません。読み取りロックと書き込みロック、および書き込みロックと書き込みロックは相互に排他的です

したがって、複数のスレッドが同時にテーブルの追加、削除、変更、クエリを行うことができますが、スレッド A がテーブルにフィールドを挿入するとき、他のスレッドはテーブルに対して他の操作を実行する前に、スレッド A の挿入が完了するのを待つ必要があります。

3. 行ロック

行ロックは、名前が示すとおり、テーブル内の行をロックすることです。たとえば、トランザクション A が行を更新します。このとき、トランザクション B も同じ行を更新する必要があるため、トランザクション A がその行を解放するまで待つ必要があります。更新するにはロックしてください。

3.1 2フェーズロックプロトコル

行ロックは必要なときに (行の更新時など) 追加されますが、すぐには解放されません。ただし、ロックを保持しているトランザクションがコミットされるまで行ロックは解放されません。

3.2 デッドロック

栗を例に挙げます。まず、栗を 4 つの期間に分けます。

(1) トランザクション A が開かれ、ステートメントが実行されます。update t set k=k+1 where id=1;

(2) トランザクション B が開かれ、ステートメントが実行されます。update t set k=k+1 where id=2;

(3) トランザクション A は次のステートメントを実行します。update t set k=k+1 where id=2;

(4) トランザクション B は次のステートメントを実行します。update t set k=k+1 where id=1;

最初の 2 つの期間ではステートメントの実行は正常です。3 番目の期間では、トランザクション A は id=2 の行のデータを変更したいと考えていますが、現時点では、トランザクション A はトランザクション B が行を解放するまで待つことしかできません。 id=2 の行のロックは後でのみ変更できます (トランザクション B は 2 番目の期間に保持されますが、行ロックはトランザクションの終了時にのみ解放できます)。

次の 4 番目の期間では、トランザクション B は id=1 の行のデータを変更したいと考えていますが、現時点では、トランザクション B はトランザクション A が id=1 の行の行ロックを解放して変更するのを待つことしかできません (最初の期間ではトランザクション A が実行されますが、ロックはトランザクションの終了時にのみ解放できます)。

このとき、2 つのトランザクションはお互いに行ロックを解除するのを待ちます。これはデッドロックです。

3.3 デッドロックの検出

デッドロック検出はデッドロックを解決する効果的な方法です。MySQL がデッドロック検出を開始してデッドロックを検出すると、トランザクションの 1 つがロールバックされ、他のトランザクションが通常どおり続行できるようになります。

おすすめ

転載: blog.csdn.net/m0_52373742/article/details/122799573