MySQLのロック機構に関する最も包括的な説明

MySQLのロック機構に関する最も包括的な説明

序文

ロックの粒度に応じて区別する

  • グローバルロック
  • テーブルロック
  • 行ロック
    • レコードロック
    • ギャップロック
    • プロキーロック

ロックのシナリオによると

  • 楽観的ロック
  • 悲観的ロック

グローバルロック

ロック対象は、データベースインスタンス全体です。

読み取りロック付きテーブルフラッシュ (FTWRL) - データベース全体を読み取り専用にする

使用シナリオ: データベース全体の論理バックアップを作成する

完全なデータベース論理バックアップ

データをバックアップするためにグローバル ロックが必要なのはなぜですか?

たとえば、売上の場合、出荷を記録するテーブルと控除を記録するテーブルが 1 つあります。その結果、出荷記録テーブルをバックアップしました。このとき、誰かが何かを購入したのに、代金のみが控除され、出荷記録はありませんでした。これは明らかに受け入れられません。

公式の論理バックアップ ツールは mysqldump です。 mysqldump がパラメータ –single-transaction を使用する場合、一貫したビューを確保するために、データをインポートする前にトランザクションが開始されます。 MVCC のサポートのおかげで、このプロセス中にデータを正常に更新できます。ただし、これはトランザクションに基づいており、MyISAM データ エンジンでは使用できません。この場合、一部のテーブルが InnoDB データ エンジンに基づいていない可能性があります。

もちろん、すべてが InnoDB データ エンジン テーブルである場合は、デフォルトの mysqldump を使用して、パラメーター –single-transaction を追加し、グローバル論理バックアップを実行することをお勧めします。

FTWRL と set global readonly=true の違い

  1. Readonly は他のロジックで使用されます (システムによって異なる)
  2. ftwrlは、クライアント接続が切断されたときに自動的にロックを解除し、デッドロックの問題を防ぐことができます。

テーブルロック

コマンド: テーブル {tableName} を読み取り/書き込みでロックする (書き込みは読み取りよりも強力です。書き込みができる場合は読み取りもできます)、テーブルのロックを解除する

ロックされたリソースでは、現在のスレッドのみが対応する操作を実行できます。また、現在のスレッドは、ロックされたテーブルに対してのみ対応する操作を実行できます。

たとえば、テーブル t1 を読み取りロックすると、現在のスレッドは読み取りのみ可能で書き込みはできず、他のスレッドは読み取りも書き込みもできません。

MDLロック

明示的な使用は必要ありません。テーブルにアクセスするときに自動的に追加されます (テーブル構造の変更によって発生する問題を防ぐため)

テーブルを追加、削除、変更、またはチェックするときに MDL 読み取りロックを適用し、テーブルの構造を変更するときに MDL 書き込みロックを適用します。

  • MDL読み取りロック(共有ロック)では、ロックは相互に排他的ではありません。そのため、複数のスレッドが同時に追加、削除、変更、クエリを実行できます。
  • MDL書き込みロック(排他ロック)は、他の読み取り/書き込みロックと相互に排他的です。つまり、現在のデータ変更、クエリ、または構造変更は、実行前に他のMDL書き込みロックが解除されるのを待つ必要があります。

行ロック

行ロックは各エンジンによってエンジンレベルで実装されます (MyISAM は行ロックをサポートしていないため、エンジンは一度に 1 つのスレッドでのみ更新操作を実行できます)

トランザクションの場合: 1 行または複数行のデータが必要なときに行ロックが追加されますが、トランザクションがコミットされるまですべての行ロックは解除されません。つまり、他のスレッドが行データにアクセスする必要がある場合、そのスレッドのトランザクションがコミットされるまで待ってからアクセスする必要があります。

例:

スレッドAは次のことを行います
始める;
t1 を更新し、id=1 の場合に a=1 を設定します。

t2を更新し、id=2の場合にb=2を設定します。

専念

このとき、スレッド A は t1 の id=1 と t2 の id=2 をそれぞれロックします。このとき、スレッド B が t1 の id=1 にアクセスしても、アクセスできません。最初のステートメントが実行されたとしても、スレッド B はスレッド A がコミット操作を実行した後にのみデータを取得できます。

したがって、注意すべき点は、トランザクション操作を実行するときに、更新が連続していない場合は、アクセスが最も多いステートメントを最後に実行することです(ロックは連続していますが、ロックの解放は一緒に解放されるため)。

特徴テーブルロック行ロック
ロックレベルMySQL サーバー層データエンジン層
エンジンMyISAM、innoDB翻訳
特徴デッドロックなし、低オーバーヘッド、高速ロック、大きなロック粒度デッドロックしやすい、オーバーヘッドが高い、ロックが遅い、ロックの粒度が小さい

デッドロック

デッドロックは多くの状況で発生しますが、そのほとんどはデータベース操作の問題によって発生します。例えば

スレッドAとスレッドBは両方ともid=1とid=2を変更し、トランザクションを開始します。

スレッドAは最初にid=1を変更し、id=1がスレッドAによってロックされる。

スレッドBがid=2を変更し、id=2が郡Bによってロックされる

このとき、スレッド A は id=2 がロックを解除するまで待機してから id=2 に対する操作を実行する必要があり、スレッド B は id=1 がロックを解除するまで待機してから id=1 に対する操作を実行する必要があります。

その結果、循環的なデッドロック状態が発生します。

この問題に対処するには 2 つの戦略があります。

  1. タイムアウトまで待機状態に直接移行します。このタイムアウトは、パラメータ innodb_lock_wait_timeout (デフォルトは 50 秒) によって設定できます。これをあまり短く設定することはできません。デッドロックではない場合はどうなるでしょうか?
  2. デッドロック検出を開始します。デッドロックが見つかった場合は、デッドロック チェーン内のトランザクションを積極的にロールバックして、他のトランザクションの実行を継続できるようにします。パラメータ innodb_deadlock_detect をオンに設定すると (デフォルトはオン)、このロジックがオンになります。

レコードロック

列ロックのケース

トランザクションによってロックされた特定のレコード情報をロック後に対象とする

トリガー条件: クエリ条件が正確に一致し、一致条件フィールドが一意である

例: update t1 set name="张三" where id=12138

機能: レコードが現在のトランザクションによって管理されている場合、ロックされた後は他のトランザクションによって取得されず、「繰り返し読み取り」や「データ ダーティ リード」の問題が発生します。

ギャップロック

列ロックのケース

ギャップとは、その間にあるデータを意味します

主キーインデックス id に複数の未入力データがあります。このとき、スレッド A と B の 2 つがあり、A が 0 ~ 10 の間のデータを照会し、B が id=3 にデータを挿入すると、データのダーティ リード問題が発生します。

そのため、between などの範囲でトランザクションを実行する場合は、制約のためにギャップロックが追加されます。

プロキーロック

一時キー ロックは、クエリされたレコードをロックし、範囲クエリ内のすべてのギャップ スペースもロックし、次に次の隣接する間隔もロックします。

(リンは隣接を意味します)

楽観的ロックと悲観的ロック

コンセプト楽観的ロック悲観的ロック
コンセプト同時実行の競合がないと仮定する
提出時にデータに問題があるかどうかのみを判断する
同時実行の競合が発生すると想定する
ロック
実装レベルビジネスコードレベル、自分で実装する
(特定のビジネスロジックと組み合わせる必要がある)
MySQLデータベース自体
同時実行性同時実行性同時小規模
実装データベースにバージョン番号フィールドを追加します。
送信時に、操作前のバージョン番号が現在のバージョン番号と一致しているかどうかを確認します。
共有ロック: ロック xxxxxx を選択
排他ロック: 更新用に xxxx を選択
他のMySQL の同期ロックは、実際には排他ロックです。
共有ロック: チェックする他のスレッドを実行しても、追加、削除、変更は許可されません
排他ロック: 追加も削除も許可されません

要約する

MySQL のロック機構に関するこの記事はこれで終わりです。MySQL のロック機構についてさらに詳しく知りたい方は、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL 悲観的ロックと楽観的ロックの実装
  • MySQLの関連ロックについての簡単な理解
  • MySQLのさまざまなロックに関する詳細な理解

<<:  docker リモート API のワンクリック TLS 暗号化の実装

>>:  CSSスプライト技術は複数の背景を1つのPNG画像に統合しますCSSポジショニング

推薦する

Jenkins を通じて None のイメージを定期的にクリーンアップする方法

序文継続的なコード配信のプロセスで、Jenkins を利用して Docker イメージを作成すると、...

フロントエンドHTMLスキン変更機能の実装コード

透明を含む5つの肌の色を変更するには50行のコードが必要です最初にコードをお渡ししますので、ご自身で...

Linux ディスクのシーケンシャル書き込みとランダム書き込みの方法

1. はじめに● ランダム書き込みではヘッドがトラックを頻繁に変更するため、効率が大幅に低下します。...

Vue で CSS カスタム変数を使用する方法

目次CSS カスタム変数機能は古くから存在していますが、実際の開発ではあまり使用されていません。その...

UbuntuでMySQLデータベースファイルディレクトリを変更する方法

序文同社の Ubuntu サーバーは、さまざまなシステムのディレクトリを異なる論理パーティションに配...

Linuxでブーストライブラリをインストールするための完全な手順

序文Boost ライブラリは、標準ライブラリのバックアップとして機能し、C++ 標準化プロセスの開発...

webpackを使用してTypeScriptコードをパッケージ化およびコンパイルする方法を教えます

TypeScript バンドルwebpack 統合通常、実際の開発では、ビルド ツールを使用してコー...

MySQLをインストールして設定し、ルートパスワードを変更する方法

1. インストールapt-get install mysql-server にはアカウントとパスワー...

2018 年にリリースされる Apache Spark 2.4 の新機能は何ですか?

この記事は、2018 年 9 月 19 日に Adob​​e Systems Inc で開催された ...

RoughViz を使用して Vue.js でスケッチされたチャートを視覚化する方法

導入チャートは、データ セットを読みやすくし、その各部分を区別しやすくするために使用されるデータのグ...

W3C チュートリアル (2): W3C プログラム

W3C 標準化プロセスは 7 つの異なるステップに分かれています。 W3C 標準化プロセスは 7 つ...

マウスを動かしたときに画像のズーム効果とゆっくりとした遷移​​効果を実現するCSSのサンプルコード

transform:scale()比例したズームインまたはズームアウトを実現できます。 transi...

vscodeカスタムvueテンプレートの実装

vscode エディタを使用して vue テンプレートを作成すると、新しい vue ファイルを作成す...

Linux コマンドラインターミナルで画面を分割するための 2 つのツール

ターミナル分割画面ツールは2つあります: screen と tmux 1. 画面分割を使用する(上下...

mysql mycat ミドルウェアの簡単な紹介

1. mycatとはエンタープライズアプリケーション開発のための完全にオープンソースの大規模データベ...