MySQLベースのグローバルロック、テーブルロック、行ロック


序文

ロックは、同時実行の問題を処理するためにデータベースによって使用されるデータ構造です。

この記事では、MySQLのグローバルロック、テーブルロック、および行ロックを紹介します。


ヒント:以下はこの記事の内容です。以下のケースは参照用です。

1つ、グローバルロック

やったとき論理バックアップデータベース全体を、私たちは世界的なロックを使用する必要があり、コマンドがあるコマンドFlush tables with read lockFTWRL

グローバルロックをバックアップに使用すると、ビジネスのシャットダウン、マスタースレーブの遅延などの問題が発生する可能性がありますが、グローバルロックを使用しないと、より深刻な結果が発生します。

  1. アカウントの残高が最初にバックアップされた場合、ユーザーは次に購入操作を行い、次に配送テーブルをバックアップします。この時点では、ユーザーの残高は変更されていませんが、製品は出荷されています。
  2. 上記の操作が送信された場合、ユーザーはお金を差し引いたが、出荷を受け取らなかった

もちろん、DMLの追加削除、変更だけでなく、データベーステーブルフィールドの更新もグローバルロックによって制限されます。

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

テーブルレベルのロックは、テーブルロックとメタデータロック(MDL)の2つのタイプに分けられます。

1.テーブルロック

 lock tablesread/write

ただし、テーブルロックを使用しないことをお勧めします。テーブル全体をロックすることによる影響が大きすぎ、innoDBは行ロックをサポートしているため同時実行を処理するためにテーブルロックを使用しないでください。

2.メタデータロック(MDL)

MDLロックは、デフォルトでテーブルにアクセスするときにシステムによって追加され、表示する必要はありません。機能は、読み取りと書き込みの正確さを保証することです。

  1. テーブルが追加、削除、変更、およびチェックされると、読み取りロックが自動的に追加されます
  2. テーブルの構造が変更されると、書き込みロックが自動的に追加されます

読み取りロック間に相互排除はなく、書き込みロックと読み取り/書き込みロックの間で相互排除が発生します。その理由は、テーブル構造を変更する操作が(1つずつ)キューに入れられるためです。

特定のテーブルの構造を変更すると、データベースがダウンします。その
理由は、テーブルの構造を変更する過程で、データベースアクセスするクエリ操作頻繁に発生し、クライアントに再試行メカニズムがあるためです。スレッドがいっぱいです。

これは、テーブル構造を安全に変更する方法についての質問につながりますか?問題は長いトランザクションの処理にあります。トランザクションがコミットされていない場合、スレッド常に占有され、読み取りロックはロック解除されません。
したがって、次のことを試みることができます最初に長いトランザクションを強制終了し、次に右にテーブル構造を変更します

3、列ロック

トランザクションAがデータベーステーブルの行を更新しているとき、このとき、トランザクションBはデータベースの行も更新します。このとき、トランザクションBは、トランザクションAがコミットされるまで待機してから、行データを変更する必要があります。これは、行ロック呼ばれます。

1.ツーフェーズロックプロトコル

行ロックは必要に応じて追加され、不要になったときにすぐに解放されることはありませんが、トランザクションの終了後に解放されます。

したがって、トランザクションの最後に、競合を引き起こし、同時実行性に影響を与える可能性最も高いロックを設定する必要があります

:ユーザーが製品を購入するときに行うこと

  1. ユーザーアカウントの残高を差し引く
  2. マーチャントアカウントの残高を増やす
  3. ログ

このことから、マーチャントのアカウント残高操作は最も競合しやすいと結論付けることができます。マーチャントと顧客は1対多の関係にあるため、マーチャントの残高更新操作に対して同時に複数のトランザクションが発生する可能性があります。

トランザクションのこの時点で、操作2を最後に配置する必要があります

2.デッドロックとその検出

システム内の各スレッドが他のスレッドがリソースを解放するのを待っているとき、それはデッドロック現象と呼ばれるものです。

解決策は次のとおりです。

  1. スレッドを操作せず、タイムアウトを 待っinnodb_lock_wait_timeoutてタイムアウト時間設定します
  2. デッドロック検出を開始すると、システムはデッドロックされたトランザクションをアクティブにロールバックしinnodb_deadlock_detectますデフォルトはオン(オープン)です

通常はデッドロック検出を使用しますが、デッドロック検出はCPUリソースの大量消費の問題も引き起こします

現時点では、さらに2つの解決策があります

  1. デッドロック検出トランザクションは発生せず、デッドロック検出を直接オフにできると結論付けることができます。
  2. データベースサーバーの同時実行性を制御します(ソースコード、ミドルウェアなどを変更します)

チームの技術的能力が十分でない場合は、上記の例を例にとると、マーチャントバランスのフィールドを10のフィールドに分割できます。これにより、CPU消費量も削減できます。

おすすめ

転載: blog.csdn.net/qq_45596525/article/details/114693055