高い CPU 使用率
症状
サーバーの CPU が 90% 以上。システム全体が遅く、ロードアベレージが高い。
1. 実際に DB が CPU を消費しているかを確認する
OS レベルで top/mpstat を使い、CPU を消費しているプロセスが本当に DB かを確認する。隣接プロセスやバックアップ/アンチウイルスが消費元であることもある。iowait が高ければ、問題は CPU ではなくディスクである。
2. CPU を最も使用しているクエリを見つける
CPU 時間順に上位のクエリを抽出する。通常は少数のクエリ (悪い計画、全表スキャン、インデックスの欠如) が CPU を消費している。
Oracle
SELECT sql_id, cpu_time/1e6 cpu_sec, executions, sql_text FROM v$sql ORDER BY cpu_time DESC FETCH FIRST 10 ROWS ONLY;PostgreSQL
SELECT query, calls, total_exec_time, mean_exec_time FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;MySQL
SELECT digest_text, count_star, sum_timer_wait/1e12 sec FROM performance_schema.events_statements_summary_by_digest ORDER BY sum_timer_wait DESC LIMIT 10;SQL Server
SELECT TOP 10 total_worker_time/execution_count avg_cpu, execution_count, SUBSTRING(t.text,1,200) FROM sys.dm_exec_query_stats q CROSS APPLY sys.dm_exec_sql_text(q.sql_handle) t ORDER BY total_worker_time DESC;3. 計画/インデックスの問題を確認する
問題のクエリの計画を取得する。全表スキャン、ネステッドループの爆発、ハッシュ結合のスピル、パラメータスニッフィング/古い統計情報による悪い計画が CPU を消費する。インデックスを追加するか、統計情報を収集する。
4. 即座に緩和する
暴走クエリを強制終了し、必要に応じて Resource Manager/Resource Governor で制限する。突然始まった負荷については、直近のデプロイ/パラメータ変更を確認する。
5. 恒久的に修正する
クエリ/インデックスを修正し、計画の安定性を確保し、統計情報収集ジョブをスケジュールする。CPU が常に 100% なら、スケーリング (CPU の追加、読み取りレプリカへの読み取りの分散) が必要になりうる。