MySQLのロックについて理解しておくべきこと

MySQLのロックについて理解しておくべきこと

1. はじめに

MySQL ロックは、その範囲に応じて、グローバル ロック、テーブル ロック、行ロックに分けられます。行ロックはデータベース エンジンによって実装されます。すべてのエンジンが行ロックを提供しているわけではありません。MyISAM は行ロックをサポートしていないため、この記事では InnoDB エンジンを例に行ロックを紹介します。

2. グローバルロック

MySQL は、データベース インスタンス全体をロックするグローバル ロックを提供します。

文法:

読み取りロック付きテーブルのフラッシュ

このステートメントは、通常、バックアップに使用されます。このステートメントを実行すると、データベース内の開いているテーブルがすべて閉じられ、データベース内のすべてのテーブルがグローバル読み取りロックでロックされます。同時に、他のスレッドの更新ステートメント (追加、削除、変更)、データ定義ステートメント (テーブルの作成、テーブル構造の変更)、および更新トランザクションの送信がブロックされます。

MySQL 8.0 以降では、MySQL はバックアップにバックアップ ロックを直接使用できます。

声明:

バックアップのためにインスタンスをロックするインスタンスのロックを解除する

このロックの範囲は広く、 REPAIR TABLE TRUNCATE TABLE, OPTIMIZE TABLE操作やアカウント管理など、ファイルの作成、名前変更、削除を防止します。もちろん、これらの操作はメモリ一時テーブルに対して実行できます。メモリ テーブルにはなぜこれらの制限が適用されないのでしょうか?メモリテーブルはバックアップする必要がないため、これらの条件を満たす必要はありません。

3. テーブルロック

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

メタデータ ロック (MDL) は明示的に使用する必要はなく、テーブルにアクセスすると自動的に取得されます。この機能をサポートするには、MySQL バージョン 5.5 以上が必要です。テーブルを追加、削除、変更、またはチェックすると、テーブルに MDL 読み取りロックが追加されます。テーブル構造が変更されると、MDL 書き込みロックが追加されます。 MDL ロックにはいくつかのルールがあります:

読み取りロックは相互に排他的ではないため、複数のスレッドが同じテーブルを追加、削除、変更、および照会できます。読み取り/書き込みロックと書き込みロックは相互に排他的です。テーブル構造の変更のセキュリティを確保するために、複数のスレッドが同じテーブルにフィールドを追加するなどのテーブル構造操作を実行する必要がある場合は、シリアル化され、ロック待機が必要になります。 MDL の書き込みロック優先度は MDL の読み取りロック優先度よりも高くなりますが、max_write_lock_count システム変数を設定することでこの状況を変更できます。書き込みロック要求がこの変数で設定された数を超えると、MDL 読み取りロック優先度は MDL 書き込みロック優先度よりも高くなります。 (デフォルトではこの数値は大きいため、書き込みロックの優先度が下がることを心配する必要はありません。) MDL ロックは、トランザクションが終了した後にのみ解除する必要があります。

したがって、データベース テーブル構造を操作するときは、長いトランザクションを使用しないように注意する必要があります。これは具体的に何を意味するのでしょうか。例を挙げてみましょう:

上の図は、4 つのセッションによるステートメントの実行を示しています。まず、SessionA はトランザクションを開始しますが、コミットしません。次に、SessionB はクエリを実行します。これらは MDL 読み取りロックを取得するため、互いに影響を及ぼさず、正常に実行できます。SessionC はフィールドを追加します。MDL の書き込みと読み取りは相互に排他的であるため、SessionC はブロックされます。次に、SessionD がクエリ ステートメントの実行を開始します。SessionC がブロックされているため、SessionD もブロックされます。したがって、シミュレートした SessionA のトランザクションは長いトランザクションであり、その後テーブル構造が変更され、テーブルに対する後続のすべての読み取りおよび書き込み操作が実行不可能になります。したがって、実際のシナリオでは、ビジネス リクエストが頻繁に発生する場合、テーブル構造の変更によってライブラリのスレッドがブロックされる可能性があります。

テーブル ロックの構文は次のとおりです。

LOCK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] ... lock_type: { READ [LOCAL] | [LOW_PRIORITY] WRITE} UNLOCK TABLES

テーブル ロックは、読み取りロックと書き込みロックに分けられます。読み取りロックは相互に排他的ではありませんが、読み取りロックを取得した後はデータを書き込むことはできません。読み取りロックを取得していない他のセッションでもテーブルを読み取ることができるため、読み取りロックの目的はテーブルへの書き込みを制限することです。テーブルが読み取りロックによってロックされている場合、挿入ステートメントを実行するとエラーが報告されます。エラーは次のとおりです。

1099 - テーブル 'XXXX' は読み取りロックでロックされており、更新できません

書き込みロックが取得されると、テーブルは読み取りおよび書き込み可能になります。書き込みロックは相互に排他的です。セッションがテーブルの書き込みロックを取得すると、書き込みロックが解除されるまで他のセッションはテーブルにアクセスできません。

テーブルのロックは、 unlock tablesを使用して解除することも、クライアント ポートによって自動的にロック解除することもできます。テーブルのlock tablesテーブルを排他的にロックします。これにより、他のスレッドによるテーブルの読み取りと書き込みが制限されるだけでなく、このスレッドの次の操作オブジェクトも制限されます。

4. 行ロック(InnoDB)

MySQL の行ロックはエンジン レベルで実装されているため、ここでは InnoDB エンジンでの行ロックについて説明します。以下では、InnoDB での一般的な行ロックをいくつか詳しく紹介します。

4.1 共有ロック

共有ロックを使用すると、トランザクションはロックを取得した後に読み取り操作を実行できます。共有ロックは相互に排他的ではありません。1 つのトランザクションが共有ロックを取得した後、別のトランザクションも共有ロックを取得できます。共有ロックを取得した後は書き込み操作は実行できません。

4.2 排他ロック

排他ロックを使用すると、トランザクションはロックを取得した後、行を更新または削除できます。名前が示すように、排他ロックは相互に排他的です。トランザクションが排他ロックを取得した後、ロックが解除されるまで他のトランザクションは排他ロックを取得できません。

4.3 意図ロック

InnoDB は複数の粒度のロックをサポートしており、行ロックとテーブルロックが共存できます。ここで言及したインテンション ロックは実際にはテーブル レベルのロックですが、単独では存在しないため行ロックに入れました。その出現には必ず行ロック (共有ロックまたは排他ロック) が伴います。その主な目的は、テーブル内の行がロックされるか、ロックされていることを示すことです。

インテンション ロックは、行ロックとの組み合わせに応じて次のタイプに分類できます。

  • 意図的な排他ロック: テーブル内の特定の行に対して排他ロックが取得されることを示します。
  • 意図的な共有ロック: テーブル内の特定の行に対して共有ロックが取得されることを示します。

意図ロックの取得は行ロックの取得の前に行う必要があります。つまり、共有ロックの前に共有意図ロックを取得する必要があり、排他ロックについても同様です。

では、この意図ロックは具体的に何をするのでしょうか?

これを説明する前に、インテンション ロックと行ロックの互換性関係を見てみましょう。

--- 排他ロック(X) 意図的な排他ロック(IX) 共有ロック(S) 意図共有ロック (IS)
排他ロック(X) 対立対立対立対立
意図的な排他ロック(IX) 対立互換性がある対立互換性がある
共有ロック(S) 対立対立互換性がある互換性がある
意図共有ロック (IS) 対立互換性がある互換性がある互換性がある

トランザクション A と B の 2 つのトランザクションがあると仮定します。トランザクションは共有ロックを取得し、テーブル内の行をロックします。この行は読み取りのみ可能で、書き込みはできません。ここで、トランザクション B はテーブル全体の書き込みロックを申請します。トランザクション B が正常に適用された場合、テーブル内のすべての行に確実に書き込むことができるため、A によって取得された行ロックと確実に競合します。このような競合を回避するために、データベースは競合検出を実行します。では、どのように検出するのでしょうか?方法は2つあります:

テーブルがテーブル レベルのロックを持つ他のトランザクションによってロックされているかどうかを判断します。テーブル内の各行が行ロックによってロックされているかどうかを判断します。

テーブルの各行を決定するには、すべてのレコードをトラバースする必要があり、非効率的です。そのため、データベースは最初の方法、つまり意図ロックを使用して競合を検出します。

要約する

この記事では、主にMySQLのロックスコープの観点からMySQLのロックを分析します。MySQLは、ロックスコープに応じて、グローバルロック、テーブルロック、行ロックに分けられます。グローバル ロックとテーブル ロックは MySQL 自体によって実装され、行ロックはエンジン レベルで実装されます。 InnoDB の行ロックは、主に共有ロックと排他ロックに分けられます。共有ロックが要求されると、行は読み取り専用になり、共有ロックは相互に排他的ではなくなります。排他ロックが取得されると、行を更新および削除できます。排他ロックは他のロックと相互に排他的です。最後に、行ロックに基づく意図的ロックについて説明しました。意図的ロックは主に、ロック競合検出の効率を向上させるために、行がロックされているか、ロックされようとしていることを意味します。もちろん、InnoDB にはギャップ ロック、レコード ロック、Next-Key ロックなど、他のロックもあります。これらはこの記事の範囲外です。興味があれば、自分で勉強してください。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • MySQL デッドロック シナリオ例の分析
  • MySQL InnoDB のロック機構の詳細な説明
  • 魔法のMySQLデッドロックトラブルシューティング記録
  • MySQL における楽観的ロックと悲観的ロックの例
  • Mysqlは実行中のトランザクションを照会し、ロックを待機する方法

<<:  Linux システムで .sh ファイルを実行する方法

>>:  Vue エクスポート Excel 機能の全プロセス記録

推薦する

JavaScript で Baidu Maps API にアクセスする方法と手順

目次1. Baidu Map API アクセス2. HTML で Baidu Map API を使用...

LeetCode の SQL 実装 (197. 気温上昇)

[LeetCode] 197.気温上昇Weather テーブルが指定されている場合、前の日付 (昨...

Linux RabbitMQ クラスタ構築プロセス図

1. 全体的な手順冒頭で、RabbitMQ サービスをインストールして実行する方法を紹介しましたが、...

MySQL 8.0.13 で日付を 0000-00-00 00:00:00 に設定すると発生する問題を解決する

データベース操作を学び始めたばかりです。今日、データを保存していたところ、エラーが発生していることに...

MySQLセグメンテーション関数substring()の具体的な使用法

MySQL には、主に left()、right()、substring()、substring_i...

Facebook 出会い系サイトデザインのユーザー エクスペリエンス分析

<br />関連記事: Facebookの情報アーキテクチャの分析 元記事: http:...

CSSでnグリッドレイアウトを実装する方法

一般的なアプリケーションシナリオ現在のアプリのインターフェースは基本的に同じであり、グリッドレイアウ...

React 星評価コンポーネントの実装

要件は、製品の評価データを渡すことであり、ページには対応する星の数が表示されます。 1. 異なる評価...

LinuxシステムにおけるMySQLの一般的な操作コマンド

仕える: # chkconfig --list すべてのシステムサービスを一覧表示する# chkco...

MySQLでホワイトリストアクセスを設定する方法

MySQLでホワイトリストアクセスを設定する手順1. ログイン mysql -uroot -pmys...

Vue3のいくつかの利点についての簡単な説明

目次1. ソースコード1.1 モノレポ1.2 タイプスクリプト2. パフォーマンス2.1 ソースコー...

docker-maven-pluginプラグインは対応するjarパッケージを取得できません

docker-maven-plugin プラグインを使用する場合、Maven は対応する jar パ...

非常に便利な CSS 開発ツール 8 つを紹介

CSS3 パターン ギャラリーこの CSS3 パターン ライブラリには、純粋な CSS3 を使用して...

MySQL での and or クエリの優先度分析

これは見落とされがちな問題かもしれません。まず、次の点を明確にする必要があります。 MySQL では...

HTML メタの使用例

使用例コードをコピーコードは次のとおりです。 <!DOCTYPE html> <!...