正常な ApsaraDB RDS for MySQL インスタンスでは、アクティブスレッド数は通常 10 未満です。高スペック、高 QPS のインスタンスでは 20 から 30 になることもあります。この数が 100 や 1,000 を超えると、SQL クエリが蓄積され、応答時間が悪化し、深刻な場合にはインスタンスがクエリの処理を完全に停止します。
このトピックでは、最も一般的な 4 つの根本原因とそれぞれの解決策について説明します。
アクティブスレッド数の確認
ApsaraDB RDS コンソールにログインし、次のいずれかの方法を使用します。
-
[モニタリングとアラート]:左側メニューで、[モニタリングとアラート] をクリックします。[標準モニタリング] タブで、[標準ビュー] をクリックします。
-
DAS:左側メニューで、[自律サービス] > [ダッシュボード] を選択します。[パフォーマンス傾向] タブでスレッド数が多く表示されている場合、一部のセッションがブロックされていることを示します。
低速 SQL クエリ
現象:SHOW PROCESSLIST を実行します。多数のセッションが過度に多くの行をスキャンしている場合、低速クエリがアクティブスレッド数を増加させています。詳細なログを確認するには、[自律サービス] > [スロークエリログ] に移動します。
解決策:SQL スロットリングを有効にするか、問題のあるセッションを終了させて、蓄積を停止します。詳細については、「SQL スロットリング」をご参照ください。
テーブルキャッシュの枯渇
現象:テーブルキャッシュが小さすぎて、現在の 1 秒あたりのクエリ数 (QPS) または開いているテーブルの総数を処理できない場合、セッションは Opening table 状態に切り替わります。
解決策:table_open_cache と table_open_cache_instances の値を増やします。
table_open_cacheの変更は、インスタンスを再起動しなくてもすぐに有効になります。table_open_cache_instancesの変更には再起動が必要です。
メタデータロックの競合
現象:セッションに Waiting for table metadata lock 状態が表示されます。準備フェーズとコミットフェーズでは、DDL ステートメントはテーブルのメタデータロックを取得する必要があります。テーブルが未コミットのトランザクションや低速クエリに関与している場合、DDL ステートメントはブロックされます。これにより、そのテーブルに対する後続のすべてのクエリがブロックされます。
解決策:影響を受けるテーブルで、未コミットのトランザクション、低速クエリ、および進行中の DDL ステートメントをすべて中止します。
行ロックの競合
現象:Innodb_row_lock_waits と Innodb_row_lock_time の値が高い場合は、行ロックの競合を示しています。これらのメトリックを表示するには、[自律サービス] > [ダッシュボード] に移動し、[パフォーマンス傾向] タブをクリックして、[行ロック] セクションを確認します。
診断:SHOW ENGINE INNODB STATUS; を実行し、Lock wait 状態のセッションを探します。このようなセッションが多数存在する場合、深刻な行ロックの競合が確認されます。
解決策:競合を減らすために、次の対策を適用します。
-
ホットデータの更新の最適化:書き込み負荷を同じ行に集中させるのではなく、複数の行に分散させます。
-
トランザクションサイズの削減:大きなトランザクションを小さなトランザクションに分割して、ロックが保持される時間を短縮します。
-
迅速なコミット:トランザクションをできるだけ早くコミットして行ロックを解放し、待機中のセッションのブロックを解除します。