初心者がソースコードからMySQLのデッドロック問題を理解する

初心者がソースコードからMySQLのデッドロック問題を理解する

夜遅くまで何度も困難なシングルステップデバッグを行った後、ようやく理想的なブレークポイントを見つけました。ロック取得プロセスコードの大部分は、 lock0lock.cstatic enum db_err lock_rec_lock()関数にあることがわかります。この関数は、ロック取得のプロセスと、ロック取得が成功したかどうかを表示します。

シナリオ 1: 主キーによる削除

テーブル構造

テーブル `t1` を作成します (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(10) NOT NULL デフォルト ''
 主キー (`id`)
)ENGINE=InnoDB;

id = 10 の t1 から削除します。

ご覧のとおり、インデックス PRIMARY はロックされており、モードは 1027 です。1027 はどういう意味でしょうか? 1027 = LOCK_REC_NOT_GAP + LOCK_X (非ギャップレコードロックとXロック)

プロセスは以下のとおりです

結論:主キー ID に基づいて他のインデックスを使用せずにデータを削除するには、この SQL ステートメントで、ID = 10 のレコードの主キー インデックスに X ロックを追加するだけで済みます。

シナリオ 2: 一意のインデックスによる削除

テーブル構造が若干調整され、名前の一意のインデックスが追加されました。

データを構築する CREATE TABLE `t2` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(10) NOT NULL デフォルト ''
 主キー (`id`)、
 ユニークキー `uk_name` (`name`)
) ;
`t2` (`id`, `name`) 値に挿入 
 (1,'M')、
 (2、'Y')、
 (3、'S')、
 (4,'Q')、
 (5、'L');
 
テスト SQL ステートメント delete from t2 where name = "Y"

実際のソースコードのデバッグ結果を見てみましょう

最初のステップ:

ステップ2:

結論:このプロセスでは、まずユニークキーuk_nameにXロックを追加し、次にクラスター化インデックス(主キーインデックス)にXロックを追加します。

プロセスは以下のとおりです

シナリオ3: 通常のインデックスによる削除

データを構築する CREATE TABLE `t3` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(10) NOT NULL デフォルト ''
 主キー (`id`)、
 キー `idx_name` (`name`) 
);
`t3` (`id`, `name`) 値に挿入 
 (1,'N')、
 (2、'G')、
 (3、「私」)、
 (4,'N')、
 (5、'X');
 
テストステートメント:
name = "N" の場合、t3 から削除します。

デバッグのプロセスを図に示します。

結論:共通インデックスを介して更新する場合、条件を満たすすべての共通インデックスに X ロックが追加され、関連する主キー インデックスに X ロックが追加されます。

プロセスは以下のとおりです

シナリオ4: インデックスを使用せずに削除する

テーブル `t4` を作成します (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(10) NOT NULL デフォルト ''
 主キー (`id`)
)

`t4` (`id`, `name`) 値に挿入 
 (1,'M')、
 (2、'Y')、
 (3、'S')、
 (4,'Q')、
 (5、'L');
 
name = "S" の場合、t4 から削除します。

Xロックは全部で5つあり、残りの3つは1つずつリストされていません。

結論:インデックスを使用せずに更新する場合、SQL はクラスター化インデックス (主キー インデックス) を使用してテーブル全体をスキャンするため、条件を満たしているかどうかに関係なく、各レコードがロックされます。まだ終わってないよ…

ただし、効率化のため、MySQL では最適化が行われています。条件を満たさないレコードについては、判断後にロックが解除されます。最終的に保持されるロックは条件を満たしたレコードに対するものですが、条件を満たさないレコードに対するロック/解除アクションは省略されません。

プロセスは以下のとおりです

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

以下もご興味があるかもしれません:
  • MySQL デッドロック問題の分析と解決例
  • Mysql は、デッドロック問題を解決するために kill コマンドを使用します (実行中の特定の SQL ステートメントを強制終了します)。
  • MySQL の redo デッドロック問題のトラブルシューティングと解決プロセス分析
  • MySQL データベースのパージデッドロック問題の分析
  • MySQLデッドロック問題の詳細な分析

<<:  JavaScript 配列の Reduce() メソッドの構文と例の分析

>>:  JavaScript を使用して文字列内の最も繰り返しの多い文字を取得する方法

推薦する

mysql5.7.20 での最初のログイン失敗に対する簡単な解決策

まず、 (1)MySQL 5.7にはデフォルトのパスワードがあるデフォルトのパスワードを見つける g...

ubuntu14.04 に jdk1.8 をインストールするチュートリアル

1. jdkダウンロードアドレスをダウンロードする我下載的是jdk-8u221-linux-x64....

Linux でハイパースレッディング技術を動的に有効/無効にする方法の詳細な説明

序文Intel のハイパースレッディング テクノロジーにより、1 つの物理コア上で 2 つのスレッド...

Linux の高並列性とパフォーマンス最適化の落とし穴の紹介

目次序文Linux アプリケーション実行中に開いているファイルが多すぎる問題の分析と解決Linux ...

docker コマンド例外「権限が拒否されました」の解決方法

Linuxシステムでは、dockerを新しくインストールし、次のようなコマンドを入力します。dock...

MySQL ユーザー権限管理の実装

1. MySQL の権限の概要MySQL には、権限を制御する 4 つのテーブルがあります。user...

MySQL 5.6 の「暗黙的な変換」によりインデックスが失敗し、データが不正確になる

背景SQL クエリを実行するときに、where 条件の vachar 型フィールドの単一引用符を削除...

MySQL全文インデックスを使用して検索エンジンのサンプルコードの簡易版を実現する

序文全文インデックスを使用できるのは Innodb と MyISAM ストレージ エンジンのみです ...

MySQL のフィールドにデフォルトの時間を追加する方法

日付型の違いと用途MySQL には、日付、時刻、年、日付時刻、タイムスタンプの 5 つの日付タイプが...

MySQLにおける分散ロックの考え方をDBの助けを借りて詳しく説明します

序文スタンドアロン ロックであっても分散ロックであっても、共有データに基づいて現在の操作の動作を判断...

Linux 名前空間ユーザーの詳細な説明

ユーザー名前空間は Linux 3.8 で追加された新しい名前空間で、ユーザー ID やグループ I...

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

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

JavaScript のデシェイクとスロットリングの例

目次安定スロットル: 手ぶれ防止: 一定時間内に最後のタスクのみを実行します。スロットル: 一定期間...

JavaScript ベースの Web 計算機の実装

この記事では、ウェブ計算機のマインスイーパゲームを実装するためのJavaScriptの具体的なコード...

Zabbix は DingTalk のアラーム機能を画像付きで設定します

実装のアイデア:まず、アラーム情報にはitemidが必要です。これは前提条件です。情報に渡されるパラ...