DBAtlas · 数据库运维图谱

CPU 过高

症状

服务器 CPU 达到 90% 以上;整个系统变慢,load average 很高。

1. 确认 CPU 确实是被数据库消耗的

在操作系统层面用 top/mpstat 确认消耗 CPU 的进程确实是数据库。有时消耗者是相邻进程或备份/杀毒软件。若 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. 检查计划/索引问题

获取问题查询的执行计划。全表扫描、nested loop 爆炸、hash join 溢出,或参数嗅探/过时统计信息导致的糟糕计划都会消耗 CPU。添加索引或收集统计信息。

4. 立即缓解

终止失控查询,必要时用 Resource Manager/Resource Governor 对其加以限制。对于突然出现的负载,检查最近的部署/参数变更。

5. 永久修复

修复查询/索引,确保计划稳定,并安排统计信息收集作业。若 CPU 持续处于 100%,可能需要扩容(增加 CPU、将读取分散到只读副本)。

在 DBAtlas 中打开 →