Amazon RDS for MySQL インスタンスで CPU 使用率が高い場合のトラブルシューティングと解決方法を教えてください。

最終更新日: 2022 年 2 月 11 日

Amazon Relational Database Service (Amazon RDS) for MySQL DB インスタンスで CPU 使用率が高くなっています。高い CPU 使用率をトラブルシューティングして解決するにはどうすればよいですか?

簡単な説明

CPU 使用率の増加は、ユーザーが開始する負荷の高いワークロード、複数の同時クエリ、または長時間実行されるトランザクションなど、いくつかの要因によって引き起こされる可能性があります。

Amazon RDS for MySQL インスタンスの CPU 使用率上昇の原因を特定するには、次のアプローチを確認します。

  • 拡張モニタリング
  • Performance Insights
  • ワークロードでの CPU 使用率上昇の原因を検出するクエリ
  • 有効なモニタリングによるログ

送信元を特定したら、ワークロードを分析および最適化して、CPU 使用率を削減できます。

解決方法

拡張モニタリングの使用

拡張モニタリングの [operating system (OS) process list] (オペレーティングシステム (OS) プロセスリスト) セクションで、OS プロセスRDS プロセスを確認します。mysqld または Aurora プロセスの CPU 使用率の割合を確認します。これらのメトリクスは、CPU 使用率の増加が OS または RDS でのプロセスに起因するかどうかを確認するのに役立ちます。または、これらのメトリクスを使用して、mysqld または Aurora によって発生した CPU 使用率の増加を監視できます。cpuUtilization のメトリクスを確認することで、CPU 使用率の分割も調べることができます。詳細については、「Monitoring OS metrics with Enhanced Monitoring」(拡張モニタリングを使用した OS メトリクスのモニタリング) を参照してください。

注: パフォーマンススキーマをアクティブにすると、OS スレッド ID をデータベースのプロセス ID にマッピングできます。詳細については、「十分なメモリがあるのに Amazon RDS DB インスタンスがスワップメモリを使用するのはなぜですか?」を参照してください。

Performance Insights の使用

Performance Insights を使用すれば、CPU 使用率が高い原因となっているインスタンス上で実行中のクエリを正しく識別できます。まず、Performance Insights for MySQL をアクティブにします。そうすると、Performance Insights を使用してワークロードを最適化できます。必ずデータベース管理者 (DBA) にご相談ください。

Performance Insights で使用できるデータベースエンジンを確認するには、「Amazon RDS での Performance Insights を使用した DB ロードのモニタリング」を参照してください。

クエリを使用して、ワークロードでの CPU 使用率上昇の原因を検出する

ワークロードを最適化する前に、問題のあるクエリを特定する必要があります。CPU 使用率が高くなる問題が発生しているとき、次のクエリを実行すると、CPU 使用率の根本的な原因を特定できます。次に、ワークロードを最適化して、CPU 使用率を低減します。

SHOW PROCESSLIST コマンドは、MySQL インスタンスで現在実行中のスレッドを表示します。場合によっては、同じステートメントのセットが完了せずに実行され続けることがあります。この場合、後続のステートメントは、最初のステートメントセットが終了するまで待機する必要があります。これは、InnoDB の行レベルのロックが同じ行を更新している可能性があるためです。詳細については、MySQL ウェブサイトの「SHOW PROCESSLIST 構文」を参照してください。

SHOW FULL PROCESSLIST;

注: SHOW PROCESSLIST クエリをマスターユーザーとして実行します。マスターユーザーでない場合、MySQL インスタンスで実行中のすべてのスレッドを表示するには、MySQL PROCESS サーバー管理権限が必要です。管理権限がない場合、SHOW PROCESSLIST は、お使いの MySQL アカウントに関連付けられているスレッドのみを表示します。

INNODB_TRX テーブルは、読み取り専用トランザクションではない、現在実行中のすべての InnoDB トランザクションに関する情報を提供します。

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

INNODB_LOCKS テーブルは、InnoDB トランザクションがリクエストしたが受信していないロックについての情報を提供します。

MySQL 5.7 以前の場合:

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

MySQL 8.0 の場合:

SELECT * FROM performance_schema.data_lock;

INNODB_LOCK_WAITS テーブルは、ブロックされた InnoDB トランザクションごとに 1 つまたは複数の行を提供します。

MySQL 5.7 以前の場合:

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

MySQL 8.0 の場合:

SELECT * FROM performance_schema.data_lock_waits;

次のようなクエリを実行して、待機中のトランザクション、および待機中のトランザクションをブロックしているトランザクションを確認できます。詳細については、MySQL ウェブサイトの「InnoDB トランザクションの使用および情報のロック」を参照してください。

MySQL 5.7 以前の場合:

SELECT
  r.trx_id waiting_trx_id,
  r.trx_mysql_thread_id waiting_thread,
  r.trx_query waiting_query,
  b.trx_id blocking_trx_id,
  b.trx_mysql_thread_id blocking_thread,
  b.trx_query blocking_query
FROM       information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_trx_id;

MySQL 8.0 の場合:

SELECT
  r.trx_id waiting_trx_id,
  r.trx_mysql_thread_id waiting_thread,
  r.trx_query waiting_query,
  b.trx_id blocking_trx_id,
  b.trx_mysql_thread_id blocking_thread,
  b.trx_query blocking_query
FROM       performance_schema.data_lock_waits w
INNER JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_engine_transaction_id
INNER JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_engine_transaction_id;

SHOW ENGINE INNODB STATUS クエリは、InnoDB 標準モニターから InnoDB ストレージエンジンの状態に関する情報を提供します。詳細については、MySQL ウェブサイトの「SHOW ENGINE 構文」を参照してください。

SHOW ENGINE INNODB STATUS;

SHOW [GLOBAL | SESSION] STATUS は、サーバーのステータスに関する情報を提供します。詳細については、MySQL ウェブサイトの「SHOW STATUS 構文」を参照してください。

SHOW GLOBAL STATUS;

注: これらのクエリは Aurora 2.x (MySQL 5.7); Aurora 1. x (MySQL 5.6); MariaDB 10.x でテストされました。また、INFORMATION_SCHEMA.INNODB_LOCKS テーブルは MySQL 5.7.14 以降サポートされなくなり、MySQL 8.0 で削除されました。performance_schema.data_locks テーブルは、INFORMATION_SCHEMA.INNODB_LOCKS テーブルを置き換えます。詳細については、MySQL ウェブサイトの「data_locks テーブル」を参照してください。

ログの分析とモニタリングの有効化

ログを分析する場合、または Amazon RDS for MySQL でモニタリングをアクティブにしたい場合は、次のアプローチを検討してください。

  • MySQL General Query Log を分析して、mysqld が特定の時間に何を行っているかを確認します。クライアントがいつ接続または切断したかに関する情報を含む、特定の時間にインスタンスで実行されているクエリも表示できます。詳細については、MySQL ウェブサイトの「The General Query Log」(一般クエリーログ) を参照してください。
    注: General Query Log を長期間アクティブにすると、ログがストレージを消費し、パフォーマンスのオーバーヘッドを増加させる可能性があります。
  • MySQL Slow Query Logs を分析して、long_query_time で設定した秒数よりも実行時間が長いクエリを見つけます。ワークロードを確認し、クエリを分析して、パフォーマンスとメモリ消費を改善することも可能です。詳細については、MySQL ウェブサイトの「スロークエリログ」を参照してください。ヒント: スロークエリーログまたは一般クエリログを使用するとき、パラメータ log_outputFILE に設定します。
  • MariaDB 監査プラグインを使用して、データベースアクティビティを監査します。例えば、データベースにログオンしているユーザーや、データベースに対して実行されるクエリを追跡できます。詳細については、「MariaDB 監査プラグインのサポート」を参照してください。
  • Aurora for MySQL を使用する場合、Advanced Auditing も使用できます。監査により、ログに記録するクエリのタイプをより細かく制御できます。そうすることで、ロギングのオーバーヘッドが軽減されます。
  • innodb_print_all_deadlocks パラメータを使用して、デッドロックおよびリソースのロックを確認します。このパラメータを使用して、InnoDB ユーザートランザクションのデッドロックに関する情報を、MySQL エラーログに記録できます。詳細については、MySQL ウェブサイトの「 innodb_print_all_deadlocks」を参照してください。

高い CPU 使用率のワークロードの分析と最適化

CPU 使用率を増加させているクエリを特定したら、ワークロードを最適化して、CPU の消費量を減らします。

ワークロードに不要なクエリが表示された場合、次のコマンドを使用して接続を終了できます。

CALL mysql.rds_kill(processID);

クエリの processID を検索するには、SHOW FULL PROCESSLIST コマンドを実行します。

クエリを終了しない場合は、EXPLAIN を使用してクエリを最適化します。EXPLAIN コマンドは、クエリの実行に関連した個々のステップを示しています。詳細については、MySQL ウェブサイトの「EXPLAIN によるクエリの最適化」を参照してください。

プロファイルの詳細を確認するには、PROFILING をアクティブにします。PROFILING コマンドは、現在のセッション中に実行されているステートメントのリソース使用率を示すことができます。詳細については、MySQL ウェブサイトの「SHOW PROFILE 構文」を参照してください。

テーブルの統計を更新するには、ANALYZE TABLE を使用します。ANALYZE TABLE コマンドは、オプティマイザーがクエリを実行するための適切な計画を選択するのに役立ちます。詳細については、MySQL ウェブサイトの「ANALYZE TABLE 構文」を参照してください。