異なるインデックスを更新してMySQLのデッドロックルーチンを解決する

異なるインデックスを更新してMySQLのデッドロックルーチンを解決する 2番目の声明

t3 を更新し、b = '' に設定します (b = "2" の場合)。 

整理するために、次の順序で 3 つの X ロックが追加されました。

前回の記事では、ソース コードを使用してロック関連の情報をデバッグする方法を紹介しました。ここでは、このツールを使用して、実際のオンライン デッドロックのケースを解決します。これは、デッドロックの原因となった最初の 2 つの SQL ステートメントでもあります。オンラインテーブル構造は比較的複雑なので、以下のように簡略化されています。

テーブル `t3` を作成します (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `a` varchar(5)、
 `b` varchar(5)、
 主キー (`id`)、
 ユニークキー `uk_a` (`a`)、
 キー `idx_b` (`b`) 
)
`t3` (`id`, `a`, `b`) 値に挿入 
 (1,'1','2');
# SQL 文は次の通りです。# トランザクション 1: t1
t3 を更新し、b = '' を設定します (a = "1" です)。

# トランザクション2: t2
t3 を更新し、b = '' に設定します (b = "2" の場合)。


2 つのステートメントがデッドロックを引き起こす状況を手動で再現するのは困難です。まずはロックのプロセスを分析してみましょう。

最初のステートメント(一意のインデックスを通じてレコードを更新する)

t3 を更新し、b = '' を設定します (a = "1" です)。 

完了後、次の順序で 3 つの X ロックが追加されました。

シリアルナンバー索引ロックタイプ
1イギリスバツ
2主要なバツ
3 idx_bバツ

シリアルナンバー索引ロックタイプ
1 idx_bバツ
2主要なバツ
3 idx_bバツ

2 つのステートメントは、ロックの順序から見てデッドロックの条件を満たしているようです。

手動でシミュレーションするのは困難です。2つのSQL文を同時に実行するコードを記述すると、すぐにデッドロックが発生します。

------------------------
最近検出されたデッドロック
------------------------
181102 12:45:05
*** (1)取引:
トランザクション 50AF、アクティブ 0 秒開始インデックス読み取り
使用中の MySQL テーブル 1、ロックされているテーブル 1
LOCK WAIT 3 つのロック構造体、ヒープ サイズ 376、2 つの行ロック
MySQL スレッド ID 34、OS スレッド ハンドル 0x70000d842000、クエリ ID 549 localhost 127.0.0.1 root 更新の行を検索しています
t3 を更新し、b = '' を設定します。ここで、b = "2" です。
*** (1) このロックが許可されるのを待機しています:
レコード ロック スペース ID 67 ページ番号 3 n ビット 72 インデックス `PRIMARY`、テーブル `d1`.`t3` trx ID 50AF lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 2 物理レコード: n_fields 5、コンパクト フォーマット、情報ビット 0
 0: 長さ 4; 16 進数 80000001; 昇順 ;;
 1: 長さ 6; 16 進数 0000000050ae; asc P ;;
 2: 長さ 7; 16 進数 03000001341003; 昇順 4;;
 3: 長さ 1; 16 進数 31; 昇順 1;;
 4: 長さ 0; 16進数; 昇順;;

*** (2)取引:
トランザクション 50AE、アクティブ 0 秒更新または削除
使用中の MySQL テーブル 1、ロックされているテーブル 1
4 つのロック構造体、ヒープ サイズ 1248、3 つの行ロック、UNDO ログ エントリ 1
MySQL スレッド ID 35、OS スレッド ハンドル 0x70000d885000、クエリ ID 548 localhost 127.0.0.1 root 更新中
t3 を更新し、b = '' を設定します。ここで、a = "1" です。
*** (2) ロックを保持する:
レコード ロック スペース ID 67 ページ番号 3 n ビット 72 インデックス `PRIMARY` テーブル `d1`.`t3` trx ID 50AE lock_mode X はレコードをロックしますが、ギャップはロックしません
レコード ロック、ヒープ番号 2 物理レコード: n_fields 5、コンパクト フォーマット、情報ビット 0
 0: 長さ 4; 16 進数 80000001; 昇順 ;;
 1: 長さ 6; 16 進数 0000000050ae; asc P ;;
 2: 長さ 7; 16 進数 03000001341003; 昇順 4;;
 3: 長さ 1; 16 進数 31; 昇順 1;;
 4: 長さ 0; 16進数; 昇順;;

*** (2) このロックが許可されるのを待機しています:
レコード ロック スペース ID 67 ページ番号 5 n ビット 72 テーブル `d1`.`t3` のインデックス `idx_b` trx ID 50AE lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 2 物理レコード: n_fields 2; コンパクト フォーマット; 情報ビット 0
 0: 長さ 1; 16 進数 32; 昇順 2;;
 1: 長さ 4; 16 進数 80000001; 昇順 ;;

*** トランザクションをロールバックします (1)

デッドロックログを分析する

*** (1) このロックが許可されるのを待機しています:
レコード ロック スペース ID 67 ページ番号 3 n ビット 72 インデックス PRIMARY テーブル d1.t3 trx ID 50AF lock_mode X はレコードをロックしますが、ギャップ待機はロックしません

トランザクション2: 主キーインデックスのXロックを取得する

*** (2) ロックを保持する:
レコード ロック スペース ID 67 ページ番号 3 n ビット 72 インデックス PRIMARY テーブル d1.t3 trx ID 50AE lock_mode X はレコードをロックしますが、ギャップはロックしません

トランザクション1: 主キーインデックスにXロックを保持する

*** (2) このロックが許可されるのを待機しています:
レコード ロック スペース ID 67 ページ番号 5 n ビット 72 テーブル d1.t3 のインデックス idx_b trx ID 50AE lock_mode X はレコードをロックしますが、ギャップ待機はロックしません

トランザクション1: 共通インデックスidx_bのXロックを取得したい

これは、当社の分析およびオンラインデッドロックログとまったく同じです。

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

以下もご興味があるかもしれません:
  • ユニークインデックスの S ロックと X ロックによる MySQL デッドロック ルーチンの理解
  • MySQL デッドロック シナリオ例の分析
  • MySQL (InnoDB) がデッドロックを処理する方法の詳細な説明
  • MySQL における楽観的ロックと悲観的ロックの例
  • Mysqlは実行中のトランザクションを照会し、ロックを待機する方法
  • MySQLの関連ロックについての簡単な理解

<<:  Nginx でバージョン番号を隠したり偽造したりする方法

>>:  トークンの有効期限が切れたときにページを更新するときに繰り返しプロンプトが表示されないようにする Vue について

推薦する

CnBlogs カスタムブログスタイルの共有

半夜かけてようやくブログのスタイルを大体完成させることができました。ブログ全体が青を基調としていて、...

HTMLは正規表現を使用してテーブルの例をテストします

以下は、HTML で正規表現を使用してテーブルをチェックするサンプル コードです。具体的なコードの内...

Linux で CPU 使用率が高くなる原因をトラブルシューティングするプロセスの詳細な説明

目次序文始めるステップトラブルシューティング序文CPU 使用率が高くなるのは、オンラインでよくある問...

Ubuntu環境でPHPとNginxをコンパイルしてインストールする方法

この記事では、Ubuntu 環境で PHP と Nginx をコンパイルしてインストールする方法につ...

DockerコンテナはホストのMySQL操作にアクセスする

背景:インターフェイスを提供する Flask プロジェクトがあり、これは Docker コンテナを使...

大きなオフセットによる MySQL 制限ページングが遅い理由と最適化ソリューション

MySQL では通常、limit を使用してページ上のページング機能を完了しますが、データ量が大きな...

NavicatでMySQLビッグデータをインポートする際のエラーの解決方法

Navicat がエクスポートしたデータはインポートできません。最後に、MySQLコマンドのインポー...

MYSQL(電話番号、IDカード)データ非感応化の実装

1. データ感度低下の説明日常の開発ニーズでは、データの感度低下が頻繁に発生します。たとえば、ID ...

タブステータスバーの切り替え効果を実現するための js と jQuery

今日は、タブ バーをクリックして切り替えるという目的を実現するために、js と jQuery を使用...

JavaScript はフロントエンド Web ページでカウントダウンを実装します

ネイティブJavaScriptを使用してカウントダウンを簡単に実装します。参考までに、具体的な内容は...

テーブルパーティションとパーティション分割とは何ですか?MySqlデータベースパーティションとテーブルパーティション分割方法

1. テーブルとパーティションを分割する必要があるのはなぜですか?日常の開発では、大きなテーブルに遭...

MySQLメモリストレージエンジンに関する知識

メモリストレージエンジンに関する知識ポイントメモリ ストレージ エンジンは日常業務ではほとんど使用さ...

Linux 負荷分散 LVS の詳細な理解

目次1. LVS 負荷分散2. 負荷分散LVSの基本紹介3. LVSアーキテクチャ3.1 ロードバラ...

VMware15 仮想マシン ブリッジ モードでインターネットにアクセスできない問題の解決方法

説明 ソリューションVMware 15 仮想マシン ブリッジ モードではインターネットにアクセスでき...

Vue プロジェクトでブラウザ キャッシュ設定を無効にする例

プロジェクトをリリースするときに、キャッシュをクリーンアップする必要があるという問題に遭遇することが...