このトピックでは、データベース障害を特定してトラブルシューティングする方法について説明します。
データベースでシステムボトルネックの問題が発生していないか確認する
- PROCESSLISTの使用次のステートメントを実行して、PolarDB-Xインスタンスで実行されているすべてのSQLステートメントを表示します。
SHOW PROCESSLIST WHERE INFO IS NOT NULL
ほとんどの場合、ステートメントのスタッキングは、データベースが低速で応答するときに発生します。 返された結果に実行時間が0を超える多数のステートメントが含まれていない場合、問題はデータベースに存在しません。 そうしないと、データベースでボトルネックの問題が発生する可能性があります。
- スタック情報の使用アプリケーションは、TCPを介してデータベースと対話する。 データベースでボトルネックの問題が発生した場合、アプリケーションがソケットを使用してデータベースに要求を送信した後、データベースは結果を返しません。 この場合、ソケットを使用して送信された要求は、read() メソッドを使用して処理することはできません。 アプリケーションに関するスタック情報を使用して、データベースでブロッキングが発生したかどうかを判断できます。 次のセクションでは、例を示します。 この例では、Javaアプリケーションが使用されます。
- jstackコマンドを実行してスタック情報をダンプします。
- ダンプされたスタック情報で、MySQLドライバがリクエストに対する応答を待っているスタックを検索します。 次のコンテンツは、dunpedスタック情報の例を示しています。
a t java.net.SocketInputStream.socketRead0 (ネイティブメソッド) a t java.net.SocketInputStream.socketRead(SocketInputStream.java:116) a t java.net.SocketInputStream.read(SocketInputStream.java:171) a t java.net.SocketInputStream.read(SocketInputStream.java:141) at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:101) at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:144) at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:174) -locked <0x00000002eb8f2d98> (com.mysql.jdbc.util.ReadAheadInputStream) at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3183) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3659) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3649) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4090) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:972) at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:2497) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2870) at com.mysql.jdbc.ConnectionImpl.exe cSQL(ConnectionImpl.java:2806)
前の例に示すように、多数のスレッドのスタックが存在する場合、多数のスレッドがブロックされ、データベースからの応答を待機しています。 これは、データベースでボトルネックの問題が発生したことを示します。 それ以外の場合は、アプリケーションにボトルネックの問題が存在するかどうかを確認してください。
データベースの問題を解決する
上記の方法を使用してデータベースでボトルネックの問題が発生していることを確認した後、次のいずれかの方法を使用してボトルネックの問題を解決することを推奨します。
方法1: すべてのステートメントを殺すPROCESSLISTステートメントの返された結果に、多数のSQLステートメントがスタックされていることが示されている場合は、実行中のすべてのステートメントを直ちに強制終了することをお勧めします。 PolarDB-Xは、実行中のすべてのステートメントを強制終了できるように、次のステートメントを提供します。
キル "すべて"
ステートメントを使用して、計算ノードとデータノード間のすべての接続を強制終了し、すべてのステートメントが強制終了されるようにします。
方法2: アプリケーションを再起動メソッド1を使用した後でもステートメントがスタックされ、特定の期間待機する場合は、アプリケーションを再起動することをお勧めします。 これにより、アプリケーションの状態が正しくないためにコストがかかるSQL文をアプリケーションが繰り返し実行しようとするのを防ぎます。
方法3: 一定期間内に実行できるSQL文の数を絞る方法2を使用しても問題が解決しない場合は、PolarDB-Xが提供するCCL_RULESスロットリング機能を使用することを推奨します。
SHOW FULL PROCESSLIST
ステートメントを実行して、大部分のリソースを消費するSQLステートメントのテンプレートIDを見つけます。---- -------------- ----------------- ------------- ------------------------------- ----------------------------------- ----------------------- + ----------------- + | ID | ユーザー | ホスト | DB | コマンド | 時間 | ステート | 情報 | SQL_TEMPLATE_ID | ---- -------------- ----------------- ------------ ------------------------------- ------------------------------------------------------------- ----------------- + | 2 | polardbx_root | ***.*.*.*:62787 | polardbx | クエリ | 0 | | 完全なプロセスリストを表示 | NULL | | 1 | polardbx_root | ***.*.*.*:62775 | polardbx | クエリ (Waiting-selectrleleral) | 12 | | select 1 | 9037e5e2 | ---- -------------- ----------------- ------------ ------------------------------- ------------------------------------------------------------- ----------------- + セットの2列 (0.08秒)
- テンプレートIDを使用して、次の例に示すように、一定期間内に実行できるこのタイプのSQL文の数を調整します。
CREATE CCL_RULE IF NOT EXISTS 'test' ON *.* to 'ccltest' @ '%' 選択のため テンプレートによるフィルター ('9037e5e2') MAX_CONCURRENCY=10;
上記の方法が無効な場合は、データベースを再起動します。