높은 CPU
증상
서버 CPU 90% 이상. 시스템 전체가 느리고 load average가 높다.
1. 실제로 DB가 CPU를 소비하는지 확인한다
OS 수준에서 top/mpstat으로 CPU를 소비하는 프로세스가 정말 DB인지 확인한다. 때로는 인접 프로세스나 백업/백신이 소비자다. iowait가 높으면 문제는 CPU가 아니라 디스크다.
2. CPU를 가장 많이 쓰는 쿼리를 찾는다
CPU 시간 기준으로 정렬한 상위 쿼리를 추출한다. 대개 몇몇 쿼리(나쁜 계획, full scan, 누락된 인덱스)가 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. 계획/인덱스 문제를 확인한다
문제 쿼리의 계획을 확인한다. full table scan, nested loop 폭증, hash join spill, 또는 parameter sniffing/오래된 통계로 인한 나쁜 계획이 CPU를 소모한다. 인덱스를 추가하거나 통계를 수집한다.
4. 즉시 완화한다
폭주 쿼리를 종료하고 필요하면 Resource Manager/Resource Governor로 제한한다. 갑자기 시작된 부하라면 최근 배포/파라미터 변경을 검토한다.
5. 영구적으로 해결한다
쿼리/인덱스를 수정하고, 계획 안정성을 확보하며, 통계 수집 작업을 스케줄링한다. CPU가 항상 100%라면 확장(CPU 추가, 읽기를 read replica로 분산)이 필요할 수 있다.