BA は InnoDB についてよく知っている必要があります: セマフォの待機が 600 秒以上続いています。サーバーがハングしているように見えるため、意図的にサーバーをクラッシュさせました。MySQL バックグラウンド スレッド srv_error_monitor_thread 600 秒以上ブロックされているラッチ ロックがあることが検出された場合、ロックが 10 回連続して検出されても解放されない場合、サービスがハングし続けるのを防ぐためにパニックがトリガーされます。
何が起こったのか
バージョン番号: MySQL 5.5.40
ログには、待機中のスレッドが出力され続けます。データ ディクショナリ ロック、場所は dict0dict.c 行 305、待機時間が 900 秒を超えています。
ロックを保持しているスレッドは 139998697924352 で、その 16 進値は 7f53fca8a700 です。
--スレッド 139998393616128 は、dict0dict.c 行 305 で 934.00 秒間待機しました。セマフォ: RW ラッチの X ロック (0x105a1b8 でファイル dict0dict.c 行 748a ライターで作成されました) (スレッド ID 139998697924352)排他モードで予約しました リーダー数 0、ウェイター フラグ 1、lock_word: 0 ファイル dict0dict.c 行 302 で最後に読み取りがロックされました。 ファイル /pb2/build/sb_0-13157587-1410170252.03/rpm/BUILD/mysql-5.5 で最後に書き込みがロックされました。 .40/mysql-5.5.40/storage/innobase/dict/dict0dict.c line 305
スレッド 139998697924352 のトランザクション情報をロックし、データ ディクショナリ テーブルの操作をクエリします。
--- トランザクション 0、テーブル統計の更新が開始されていません: MySQL スレッド ID 14075、OS スレッド ハンドル 0x7F53FCA8A700、クエリ ID 110414021 21.14.5.139 JZJK USRSELECT ROUND (SUM (Data_length Index_length Data_free)/1024/ 1024 /1024) AS MY_DB_TOTAL_SIZE FROM information_schema.TABLES
ロック保持スレッド 139998697924352 をチェックして、待機している他のロックがあるかどうかを確認します。
スレッド 139998697924352、btr0sea.c 行 1134 でセルフロックが見つかりました。このロック構造は AHI に関連しています。
--スレッド 139998697924352 は、btr0sea.c 行 1134 で 934.00 秒間待機しました。ファイル btr0sea.c 行 178a ライターで作成された 0x1eb06448 の RW ラッチ上のセマフォ:X-lock (wait_ex) (スレッドid 139998697924352) は、待機専用モードで予約しましたリーダー数 1、ウェイター フラグ 1、lock_word: fffffffffffffffff前回の読み取りはファイル btr0sea.c 行 1057 でロックされました前回の書き込みはファイル /pb2/build/sb_0-13157587-1410170252.03/rpm/BUILD でロックされました/mysql-5.5.40/mysql-5.5.40/storage/innobase/btr/btr0sea.c 行 1134
次に、2 つのロック構造がどの関数に含まれているかを確認します。 #dict0dict.c dict_table_stats_lock 関数の 305 行目
btr0sea.c btr_search_drop_page_hash_index 関数の 1134 行目
これらの関数はどのような状況で呼び出されますか?innodb_table_monitor を有効にし、dict_table_stats_lock を呼び出して、ログ出力時に X ロックを適用します。このケースは有効になっていません。
innodb_stats_on_metadata が有効な場合、データ ディクショナリ テーブルのクエリを実行すると、統計情報の更新操作がトリガーされ、dict_table_stats_lock の X ロックが呼び出されます。これは、ロックを保持しているスレッドのトランザクション情報と一致します。
アダプティブ ハッシュ インデックス (AHI) は、インデックス ページの検索を高速化するために InnoDB によって使用されるハッシュ テーブル構造です。ページの訪問数が特定の条件を満たした場合、B ツリー クエリのコストを削減するために、このページのアドレスがハッシュ テーブルに保存されます。
MySQL バージョン 5.5 AHI は、グローバル ロック btr_search_latch を使用して、ハッシュ テーブル変更の一貫性を維持します。
InnoDB バッファ プールのステータスは、空きバッファが基本的に 0 アイドルのままであることを示しています。 InnoDB バッファ プールがデータ ページを削除するとき、btr_search_drop_page_hash_index 関数を呼び出して、AHI からデータ ページをクリアします。
----------------------------バッファプールとメモリ----- --- ---------------------割り当てられた合計メモリ 17582522368;追加プールに割り当てられた 0
辞書メモリ割り当て 4289681##バッファ プール サイズ 1048576
空きバッファ数 0
データベース ページ1040831
古いデータベース ページ 384193
変更されたデータベース ページ 0
概要
AHI のグローバル ロック btr_search_latch は、競合のホット スポットになることが多く、パフォーマンスに影響を与えますが、バージョン 5.7 以降は改善され、InnoDB バッファーと同様に複数のインスタンスに分割されています。この場合、Innodb_stats_on_metadata パラメーターがオンになっていると、メタデータ情報のクエリ時に統計情報が更新され、データ ディクショナリがロックされ、多数のビジネス操作がブロックされます。また、バッファ プールのスペースが不十分なため、テーブルが削除されます。古いページが削除され、AHI の btr_search_latch ロック競合がトリガーされ、最終的にはセマフォがタイムアウトしてクラッシュします。
>> イースターエッグ <<
セマフォのクラッシュを数メガバイトのログで分析し、ロック間の関係を見つけるのはかなりの作業です。スレッドとトランザクション。 sed、awk、grep の 3 つの魔法の武器の助けにより、効率は向上しましたが、まだ十分ではありません。
怠け者になるために、DBA がこれらの関係を迅速に整理できるようにするための小さなプログラムを作成しました。 その使用法は次のようになります:hongbin@MBP ~> mysqldba Doctor -f /Users/hongbin/workbench/mysqld_safe.log
ターゲット バージョン。コードをチェックするときに対応するバージョンを探します:
MySQL Server バージョン: '5.7.16-log'
セマフォ クラッシュの数ログに表示される mysql の起動数。起動数がクラッシュ数よりも大きい場合は、通常の起動またはその他のクラッシュが原因である可能性があります:
##****** **** MySQL サービスの開始数 ******* ***
MySQL セマフォのクラッシュ -> 3 回 ["2018-08-13 23:12:18 " "2018-08-14 12:13:43" "2018 -08-16 13:42:36"]
MySQL サービス開始 -> 3 回 ["2018- 08-13 23:12:59" "2018-08-14 12:15:20" "2018-08-16 13:46:37"]
どの RW ラッチがスレッドであるか主に待機していますか? 内容には、ロック位置、発生回数、スレッド ID (発生回数)、より頻繁に出現するものに焦点を当てます:********** ** ロックを待機したスレッド **********row0purge.cc:861 - > 58 140477266503424:(57) 140617703745280:(1)gi.cc:14791 -> 1 140477035656960:(1)trx0undo .ic:171 -> 1 1406176827655 68:(1)ha_innodb.cc:14791 -> 620 140617389913856:(58) 140202719565568:(58) 140202716903168:(57) 140 477029533440:(56) 140617407219456:(55) 140477035656960: (5 2) 140477035124480:(29) 140477108467456:(29) 140477025539840:(26) 140477031130880:(25) 140477027669760:(22) 1406176349447 68:(21) 140617634146048:(21) 140477019948800:(21) 140477026604800:(20) 140477022078720 :(1 8) 140477018883840:(16) 140477038585600:(15) 140477028734720:(10) 140477022877440:(9) 140477034325760:(1) 1404770316633 60:(1)srv0srv.cc:1968 -> 208 140477276993280:(185) 140617714235136 :(23)ha_innodb.cc:5510 -> ; 601 140617398167296:(57) 140617409615616:(55) 140617392043776: (53) 140477110597376:(52) 14061739577 1136:(50) 140617636275968:(45) 140617632548608:(40) 140617634146048: (33) 14061763967564 8:(32) 140617397102336:(28) 140617639409408:(23) 140617635743488:(21) 140617637811968: (18) 1406176386106 88:(16) 140617399232256:(12) 140617638344448:(10) 140617638078208:(10) 140477033793280 :(10) 14047702926720 0:(10) 140617397368576:(9) 140617635211008:(6) 140617393641216:(5) 140617637545728: (3) 140617402693376 :(2) 140477037254400:(1)dict0dict.cc:1239 -> 136 140477122623232 :(50) 140617392842496:(35) 140202726487808:(2 6) 140477123688192:(12) 140477038851840:(5) 140477030065920:( 4) 140617634412 288:(4)row0trunc.cc:1835 -> 1 140477109798656:(1)
どの書き込みスレッドが上記のロックの X ロックを保持しているか、より頻繁に出現するスレッドに注目してください:************ ***********
##140616681907968 -> 1 trx0undo.ic:171:(1)140477173069568 -> 243 srv0srv.cc:1968 でブロックするライター スレッド:(185) row0purge.cc:861:(57) row0trunc.cc:1835:(1)140617682765568 -> 29 srv0sr v.cc: 1968:(23) ha_innodb.cc:5510:(5) row0purge.cc: 861:(1)スレッドに対応するトランザクション情報を書き込みます。トランザクション情報が出力されないログ レコードも存在する可能性があります:
***** ***** これらのライター スレッドの trx 状態 **********MySQL スレッド ID 83874、OS スレッド ハンドル 140477173069568、クエリ ID 13139674 10.0.1.146 aml 参照テーブルから削除中書き込みスレッドによって保持されている S ロックの統計:
****これらの書き込みスレッドは最後に読み取りロックされました ****140477173069568 -> 243 row0purge.cc:861:(243)140617682765568 -> 24 row0purge.cc:861:(24)140616681907968 -> 1 trx0undo.ic: 190:(1 )
X の統計書き込みスレッドによって保持されているロック:
****これらの書き込みスレッドは、前回書き込み時にロックされました ****140477173069568 -> 243 dict0stats。 cc:2366:(243)140617682765568 -> 24 dict0stats.cc:2366:(24)140616681907968 -> 1 buf0flu.cc:1 198:(1)
イベント後のログ経由解析の結果、スレッドのトランザクション情報がログに出力されない可能性があり、トランザクションによって実行された具体的な操作を知ることができません。この状況に対応して、ミニ プログラムにはトランザクション中にトランザクション情報を収集する機能が追加されました。
使用方法は次のとおりです:
hongbin@MBP ~> mysqldba -uxxx -pxxx Doctor -wこれは、次のエラーを監視します。対象の mysql ログに「ライター (スレッド ID 140616681907968) がモードで予約しました」というキーワードが表示されたら、ps 内のトランザクション情報をクエリして保存します。
上記はミニ プログラムの単なる使用法ですが、DBA に役立つミニ プログラムとして、他にも発見を待っている機能があります。ぜひあなたの考えを私と共有してください。
SQL に関連する技術的な記事については、
SQL チュートリアル以上がMySQL セマフォのクラッシュの分析を思い出してください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。