MySQL ロックブロッキングの詳細な分析

MySQL ロックブロッキングの詳細な分析

日常のメンテナンスでは、スレッドがブロックされることが多く、データベースの応答が非常に遅くなります。どのスレッドがブロックの原因になっているかを調べる方法を見てみましょう。

1. 環境の説明

RHEL 6.4 x86_64 + MySQL 5.6.19

トランザクション分離レベル: RR

2. テストプロセス

3. ロックをブロックするスレッド情報を表示する

分析にはいくつかの方法があります。

3.1 show processlistを使用して表示する

MySQL [(なし)]> プロセスリストを表示します。
+----+------+-----------+---------+-------+------+--------------+------------------------------------------+
| ID | ユーザー | ホスト | db | コマンド | 時間 | 状態 | 情報 |
+----+------+-----------+---------+-------+------+--------------+------------------------------------------+
| 2 | root | localhost | NULL | クエリ | 0 | init | プロセスリストを表示 |
| 3 | root | localhost | test | クエリ | 70 | データを送信中 | select count(*) from t3 a,t3 b |
| 4 | root | localhost | test | クエリ | 65 | 更新中 | empno=7788 の emp から削除 |
| 7 | root | localhost | test | クエリ | 68 | 更新中 | update emp set sal=3500 where empno=7788 |
+----+------+-----------+---------+-------+------+--------------+------------------------------------------+
セット内の 4 行 (0.00 秒)

データベース内にスレッドが多数ある場合、この方法では確認するのが確かに困難です。

3.2 show engine innodb statusを使用して直接表示する

------------
取引
------------
Trx ID カウンター 4131
トランザクションの n:o < 4119 のパージが完了しました。n:o < 0 の状態を元に戻します: 実行中ですがアイドル状態です
履歴リストの長さ 126
各セッションのトランザクションのリスト:
---トランザクション0、開始されていません
MySQL スレッド ID 2、OS スレッド ハンドル 0x7f953ffff700、クエリ ID 115 localhost root init
エンジンの InnoDB ステータスを表示
---トランザクション 4130、アクティブ 41 秒開始インデックス読み取り
使用中の MySQL テーブル 1、ロックされているテーブル 1
LOCK WAIT 2 ロック構造体、ヒープ サイズ 360、1 行ロック
MySQL スレッド ID 4、OS スレッド ハンドル 0x7f953ff9d700、クエリ ID 112 ローカルホスト ルート更新中
empno=7788 の emp から削除
------- TRX はこのロックが許可されるまで 41 秒待機しています: ## 41 秒待機しました
レコード ロック スペース ID 16 ページ番号 3 n ビット 88 テーブル `test`.`emp` のインデックス `PRIMARY` trx ID 4130 lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 9 物理レコード: n_fields 10; コンパクト フォーマット; 情報ビット 0 ## スレッド 4 は、test.emp、ページ番号 = 3 の主キーに X ロックを追加するのを待機しています。
 0: 長さ 4; 16 進数 80001e6c; asc l;;
 1: 長さ 6; 16 進数 000000001018; 昇順 ;;
 2: 長さ 7; 16 進数 91000001420084; asc B ;;
 3: 長さ 5; 16 進数 53434f5454; 昇順 SCOTT;;
 4: 長さ 7; 16 進数 414e414c595354; asc ANALYST;;
 5: 長さ 4; 16 進数 80001d8e; asc ;;
 6: 長さ 4; 16 進数 208794f0; 昇順;;
 7: 長さ 4; 16 進数 80000bb8; 昇順 ;;
 8: SQL NULL;
 9: 長さ 4; 16 進数 80000014; 昇順 ;;
 
------------------
---トランザクション 4129、アクティブ 45 秒開始インデックス読み取り
使用中の MySQL テーブル 1、ロックされているテーブル 1
LOCK WAIT 2 ロック構造体、ヒープ サイズ 360、1 行ロック
MySQL スレッド ID 7、OS スレッド ハンドル 0x7f953ff6c700、クエリ ID 111 ローカルホスト ルート更新中
empno=7788 で emp set sal=3500 を更新します
------- TRX はこのロックが許可されるまで 45 秒待機しています: ## 45 秒待機しました
レコード ロック スペース ID 16 ページ番号 3 n ビット 88 テーブル `test`.`emp` のインデックス `PRIMARY` trx ID 4129 lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 9 物理レコード: n_fields 10、コンパクト フォーマット、情報ビット 0 ## スレッド 7 は、test.emp、ページ番号 = 3 の主キーに X ロックを追加するのを待機しています。
 0: 長さ 4; 16 進数 80001e6c; asc l;;
 1: 長さ 6; 16 進数 000000001018; 昇順 ;;
 2: 長さ 7; 16 進数 91000001420084; asc B ;;
 3: 長さ 5; 16 進数 53434f5454; 昇順 SCOTT;;
 4: 長さ 7; 16 進数 414e414c595354; asc ANALYST;;
 5: 長さ 4; 16 進数 80001d8e; asc ;;
 6: 長さ 4; 16 進数 208794f0; 昇順;;
 7: 長さ 4; 16 進数 80000bb8; 昇順 ;;
 8: SQL NULL;
 9: 長さ 4; 16 進数 80000014; 昇順 ;;
 
------------------
---トランザクション 4128、アクティブ 51 秒
2 つのロック構造体、ヒープ サイズ 360、1 つの行ロック
MySQL スレッド ID 3、OS スレッド ハンドル 0x7f953ffce700、クエリ ID 110 ローカルホスト ルートのクリーンアップ中

主な根本原因は依然として thread=3 によって引き起こされていることはわかっていますが、この結果は innodb ステータスからは分析できません。

上記から、スレッド 4 とスレッド 7 の両方が、test.emp、ページ番号 = 3 のプライマリ キーに X ロックを追加するのを待機していることがわかります。ただし、スレッド 7 は 45 秒間待機し、スレッド 4 は 41 秒間待機します。ロックはスレッド 7 よりも後で適用されるため、スレッド 7 がスレッド 4 をブロックしたことがわかります。スレッド 7 が待機している理由については、ここでは根本的な原因を分析できません。

3.3 mysqladmin debugを使用して表示する

# mysqladmin -S /tmp/mysql3306.sock デバッグ

エラー ログには次の内容が表示されます:

スレッド database.table_name ロック/待機中 Lock_type
 
 
3 test.t3 ロック - 読み取り 低優先度読み取りロック
7 test.emp ロック済み - 書き込み 優先度の高い書き込みロック

この方法では、スレッド ID=3 と 7 がブロッカーであることがわかりますが、スレッド 7 もスレッド ID=3 によってブロックされていると判断するにはまだ正確さが足りません。

3.4 innodb_lock_monitorを使用してブロッキングロックスレッドを取得する

MySQL [test]> CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB; ## 任意のデータベースにこのテーブルを作成すると、ロックモニターが有効になります
クエリは正常、影響を受けた行は 0 行、警告は 1 件 (0.07 秒)
 
MySQL [テスト]> 警告を表示\G
************************** 1. 行 ****************************
 レベル: 警告
 コード: 131
メッセージ: テーブル名 innodb_lock_monitor を使用して診断出力を有効にすることは非推奨であり、将来のリリースで削除される可能性があります。INFORMATION_SCHEMA または PERFORMANCE_SCHEMA テーブルを使用するか、SET GLOBAL innodb_status_output=ON を使用してください。
セット内の 1 行 (0.00 秒)

注: これにより 5.6 では警告が発生しますが、使用には影響しません。

次に、show engine innodb status を使用して以下を表示します。

------------
取引
------------
Trx ID カウンター 4667
トランザクションの n:o < 4659 のパージが完了しました。n:o < 0 の状態を元に戻します: 実行中ですがアイドル状態です
履歴リストの長さ 138
各セッションのトランザクションのリスト:
---トランザクション0、開始されていません
MySQL スレッド ID 9、OS スレッド ハンドル 0x7f813c5f7700、クエリ ID 152 localhost root init
エンジンの InnoDB ステータスを表示
---トランザクション 4663、アクティブ 78 秒開始インデックス読み取り
使用中の MySQL テーブル 1、ロックされているテーブル 1
LOCK WAIT 2 ロック構造体、ヒープ サイズ 360、1 行ロック
MySQL スレッド ID 4、OS スレッド ハンドル 0x7f813c628700、クエリ ID 149 ローカルホスト ルート更新中
empno=7788 の emp から削除
------- TRX はこのロックが許可されるまで 78 秒待機しています: ## 78 秒待機しました
レコード ロック スペース ID 16 ページ番号 3 n ビット 88 テーブル `test`.`emp` のインデックス `PRIMARY` trx ID 4663 lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 9 物理レコード: n_fields 10、コンパクト フォーマット、情報ビット 0 ## スレッド 4 は、test.emp、ページ番号 = 3 の主キーに X ロックを追加するのを待機しています。
 0: 長さ 4; 16 進数 80001e6c; asc l;;
 1: 長さ 6; 16 進数 000000001018; 昇順 ;;
 2: 長さ 7; 16 進数 91000001420084; asc B ;;
 3: 長さ 5; 16 進数 53434f5454; 昇順 SCOTT;;
 4: 長さ 7; 16 進数 414e414c595354; asc ANALYST;;
 5: 長さ 4; 16 進数 80001d8e; asc ;;
 6: 長さ 4; 16 進数 208794f0; 昇順;;
 7: 長さ 4; 16 進数 80000bb8; 昇順 ;;
 8: SQL NULL;
 9: 長さ 4; 16 進数 80000014; 昇順 ;;
 
------------------
TABLE LOCK テーブル `test`.`emp` trx id 4663 ロック モード IX ## 主キー行に X ロックを追加する前に、まずテーブルにインテンション ロック IX を追加します。
レコード ロック スペース ID 16 ページ番号 3 n ビット 88 テーブル `test`.`emp` のインデックス `PRIMARY` trx ID 4663 lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 9 物理レコード: n_fields 10、コンパクト フォーマット、情報ビット 0
 0: 長さ 4; 16 進数 80001e6c; asc l;;
 1: 長さ 6; 16 進数 000000001018; 昇順 ;;
 2: 長さ 7; 16 進数 91000001420084; asc B ;;
 3: 長さ 5; 16 進数 53434f5454; 昇順 SCOTT;;
 4: 長さ 7; 16 進数 414e414c595354; asc ANALYST;;
 5: 長さ 4; 16 進数 80001d8e; asc ;;
 6: 長さ 4; 16 進数 208794f0; 昇順;;
 7: 長さ 4; 16 進数 80000bb8; 昇順 ;;
 8: SQL NULL;
 9: 長さ 4; 16 進数 80000014; 昇順 ;;
 
---トランザクション 4662、アクティブ 81 秒開始インデックス読み取り
使用中の MySQL テーブル 1、ロックされているテーブル 1
LOCK WAIT 2 ロック構造体、ヒープ サイズ 360、1 行ロック
MySQL スレッド ID 7、OS スレッド ハンドル 0x7f813c5c6700、クエリ ID 148 ローカルホスト ルート更新中
empno=7788 で emp set sal=3500 を更新します
------- TRX はこのロックが許可されるまで 81 秒待機しています: ## 81 秒待機しました
レコード ロック スペース ID 16 ページ番号 3 n ビット 88 テーブル `test`.`emp` のインデックス `PRIMARY` trx ID 4662 lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 9 物理レコード: n_fields 10、コンパクト フォーマット、情報ビット 0 ## スレッド 7 は、test.emp、ページ番号 = 3 の主キーに X ロックを追加するのを待機しています。
 0: 長さ 4; 16 進数 80001e6c; asc l;;
 1: 長さ 6; 16 進数 000000001018; 昇順 ;;
 2: 長さ 7; 16 進数 91000001420084; asc B ;;
 3: 長さ 5; 16 進数 53434f5454; 昇順 SCOTT;;
 4: 長さ 7; 16 進数 414e414c595354; asc ANALYST;;
 5: 長さ 4; 16 進数 80001d8e; asc ;;
 6: 長さ 4; 16 進数 208794f0; 昇順;;
 7: 長さ 4; 16 進数 80000bb8; 昇順 ;;
 8: SQL NULL;
 9: 長さ 4; 16 進数 80000014; 昇順 ;;
 
------------------
TABLE LOCK テーブル `test`.`emp` trx id 4662 ロック モード IX ## 主キー行に X ロックを追加する前に、まずテーブルにインテンション ロック IX を追加します。
レコード ロック スペース ID 16 ページ番号 3 n ビット 88 インデックス `PRIMARY`、テーブル `test`.`emp` trx ID 4662 lock_mode X はレコードをロックしますが、ギャップ待機はロックしません
レコード ロック、ヒープ番号 9 物理レコード: n_fields 10、コンパクト フォーマット、情報ビット 0
 0: 長さ 4; 16 進数 80001e6c; asc l;;
 1: 長さ 6; 16 進数 000000001018; 昇順 ;;
 2: 長さ 7; 16 進数 91000001420084; asc B ;;
 3: 長さ 5; 16 進数 53434f5454; 昇順 SCOTT;;
 4: 長さ 7; 16 進数 414e414c595354; asc ANALYST;;
 5: 長さ 4; 16 進数 80001d8e; asc ;;
 6: 長さ 4; 16 進数 208794f0; 昇順;;
 7: 長さ 4; 16 進数 80000bb8; 昇順 ;;
 8: SQL NULL;
 9: 長さ 4; 16 進数 80000014; 昇順 ;;
 
---トランザクション 4615、アクティブ 1579 秒、InnoDB 1222 内でスレッドが宣言されました
使用中の MySQL テーブル 2、ロックされている 0
2 つのロック構造体、ヒープ サイズ 360、1 つの行ロック
MySQL スレッド ID 3、OS スレッド ハンドル 0x7f813c659700、クエリ ID 147 localhost root データ送信
select count(*) from t3 a,t3 b ## これはスレッド3で現在実行されているSQLです
Trx 読み取りビューでは、ID >= 4662 の trx は表示されず、< 4659 が表示されます。
テーブル ロック テーブル `test`.`emp` trx id 4615 ロック モード IX ## スレッド 3 は、テーブルに対する意図的な IX ロックと、test.emp テーブル、ページ番号 = 3 の主キーに対する行レベル X ロックを保持しています。
レコード ロック スペース ID 16 ページ番号 3 n ビット 88 テーブル `test`.`emp` のインデックス `PRIMARY` trx ID 4615 lock_mode X はレコードをロックしますが、ギャップはロックしません
レコード ロック、ヒープ番号 9 物理レコード: n_fields 10、コンパクト フォーマット、情報ビット 0
 0: 長さ 4; 16 進数 80001e6c; asc l;;
 1: 長さ 6; 16 進数 000000001018; 昇順 ;;
 2: 長さ 7; 16 進数 91000001420084; asc B ;;
 3: 長さ 5; 16 進数 53434f5454; 昇順 SCOTT;;
 4: 長さ 7; 16 進数 414e414c595354; asc ANALYST;;
 5: 長さ 4; 16 進数 80001d8e; asc ;;
 6: 長さ 4; 16 進数 208794f0; 昇順;;
 7: 長さ 4; 16 進数 80000bb8; 昇順 ;;
 8: SQL NULL;
 9: 長さ 4; 16 進数 80000014; 昇順 ;;

スレッド 3 が現在 select t3 テーブル操作を実行しているのに、test.emp テーブルのページ num=3 をロックしているのはなぜですか?

test.emp テーブル上のスレッド 3 のトランザクションが時間内にコミットされなかった可能性があります。

したがって、スレッド 3 がスレッド 7 をブロックし、スレッド 7 がスレッド 4 をブロックしているため、根本的な原因はスレッド 3 にあると結論付けることができます。できるだけ早くスレッド 3 を送信するか、強制終了してください。

4. 結論

InnoDB でのロック ブロッキングを分析する場合、いくつかの方法を比較します。

(1)show processlistを使用して表示するのは信頼できません。

(2)show engine innodb statusを直接使用して問題の根本原因を確認することは不可能である。

(3) mysqladmin debugを使用してロックを生成するすべてのスレッドを表示すると、それらを確認することはできますが、どれが根本的な原因であるかを判断することはできません。

(4) innodb_lock_monitorを有効にした後、show engine innodb statusを使用してロックブロックの根本原因を見つけます。

オリジナルリンク: https://blog.csdn.net/hw_libo/article/details/39080809

これで、MySQL ロック ブロッキングの詳細な分析に関するこの記事は終了です。MySQL ロック ブロッキングの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL のロック待機とデッドロック問題の分析
  • MySQL ロックの知識ポイントのまとめ
  • MySQL のロックに関する問題

<<:  Docker に Elasticsearch 7.6.2 をインストールするチュートリアル

>>:  Vue のトランジション効果とアニメーショントランジションの使用例の詳細な説明

推薦する

M1 チップに MySQL 8.0 データベースをインストールする方法 (画像とテキスト)

1. ダウンロードまず、MySQLの国内ミラーをお勧めします。特に速いわけではありませんが、それで...

一般的な HTTP ステータス コード 10 個の詳細な説明

HTTP ステータス コードは、Web サーバーの HTTP 応答ステータスを示すために使用される ...

CocosCreatorゲームにおける魚群アルゴリズムの詳細な説明

序文最近CocosCreatorを学びたいと思ったので、エディターをダウンロードして起動しました。誰...

Linux システムで jmeter を実行し、ローカル メモリを最適化する方法の詳細な説明

1. Linuxシステムにクロスシステムファイル転送ツールをインストールするルートユーザーのルートデ...

ウェブページのメモリ使用量とCPU使用量を削減する方法

一部の Web ページは大きく見えなくても開くのに非常に時間がかかる場合があります。一方、他の We...

CSS における px、em、rem、%、vw、vh 単位の違いの詳細な説明

1.ピクセルpx はピクセルの略語で、画面解像度に対する相対的な長さの単位です。 2. えむ参照は親...

docker に nacos をインストールしてデータベースを構成する詳細なチュートリアル

環境の準備 Docker環境 MySQL 5.7 (公式イメージはmysql8をサポートしていません...

Vueにおけるキーの役割と原理の詳細な説明

目次1. 結論から始めましょう2. キーの役割2.1 例2.2 上記の例を修正する2.3 例を再度修...

MySQL サービス 1067 エラーの解決策: mysql 実行可能ファイルのパスを変更する

今日、MySQLサービス1067エラー問題に遭遇しました。システムアカウントを使用するように設定して...

Dockerコンテナにvimコマンドがない問題を解決する方法

問題を見つける今日、Docker コンテナ内のファイルを変更しようとしたところ、コンテナ内に vim...

単一/複数行テキストを含む div を垂直方向に中央揃えする N 通りの方法 (高さ不明/高さ固定)

この問題について話すとき、垂直方向の中央揃えを設定するための vertical-align 属性が ...

jQueryはHTML要素の非表示と表示を実装します

商品を検索するときに、すべてのブランドまたは一部のブランドを表示するTaobaoの機能を真似してみま...

SQL ステートメント実行の詳細な説明 (MySQL アーキテクチャの概要 -> クエリ実行プロセス -> SQL 解析順序)

序文:私はずっと、SQL 文がどのように、どのような順序で実行されるのかを知りたいと思っていました。...

Linux でファイルプレフィックスを一括で追加する方法

フォルダー内のすべての txt ファイルのファイル名の前に「gt_」を追加する必要があります。つまり...

MySQL ディープページング問題の解決の実践記録

目次序文ディープページングを制限すると遅くなるのはなぜですか?サブクエリによる最適化B+ツリー構造の...