你是不是也这样?每天看top、iostat、vmstat,看到CPU高就加CPU,看到I/O慢就换SSD,结果问题依旧?其实,90%的DBA搞错了诊断顺序——先看系统,再看数据库。顺序反了,所有努力都白费。

先说个重点。数据库性能问题,根源只有三个:CPU、I/O、内存。但很多人一上来就查v$sql,查了半天发现SQL没问题,最后发现是磁盘满了。正确的做法,永远是先看操作系统。操作系统是地基,数据库是房子,地基不稳,折腾房子没用。

怎么诊断CPU?别只盯着top里的%us。你打开vmstat,看第一列r(运行队列)和第二列wa(I/O等待)。如果r长期大于CPU核心数,说明进程在排队,CPU确实不够用了。如果wa很高但us不高,那问题不在CPU,在磁盘。你加CPU反而会加重等待。真不是吓你,很多DBA在这里栽过跟头。

再来看内存。很多人用free -m,看到used很高就慌了,以为内存不够。其实Linux把空闲内存拿去做cache了,真正该看的是available那一列。如果available还有不少,但swap的used在涨,那才是真问题。swap持续增长,说明物理内存已经不够,数据库在跟磁盘换内存,性能一落千丈。这时候加内存比什么都管用。

接下来说I/O。iostat -x里有个指标叫await,它比%util重要得多。%util接近100%只说明磁盘在忙,但await是每次I/O请求的等待时间,直接反映用户体验。OLTP业务下,SSD的await应该小于10毫秒,SAS盘小于20毫秒。如果await很长,即使%util不高,也说明磁盘慢,或者控制器有问题。别只看%util就下结论。

操作系统看完了,再进数据库。CPU高的时候,查v$sql按cpu_time排序,看看哪个SQL在吃CPU。I/O高的时候,查disk_reads,找全表扫描的SQL。内存瓶颈,看共享池命中率,低于95%说明硬解析太多,得用绑定变量。记住,这时候你已经有方向了,不是瞎猜。

给你两个实战场景。场景一:vmstat显示wa很低,但us很高,iostat的%util也不高,那CPU是瓶颈。查v$sql,找到逻辑读高的SQL,加索引或者优化排序。场景二:wa很高,us很低,iostat的await很长,那磁盘是瓶颈。查v$sql,找物理读高的SQL,考虑把表放到更快存储上,或者加大db_cache_size减少物理读。

最后说一句,每一次巡检都是一次预防。别等报警了才去查,平时养成记录基线的习惯。CPU、I/O、内存的正常值是多少,你心里要有数。哪天偏离了,你就能第一时间发现问题。

你平时巡检经常踩哪个坑?评论区聊聊,咱们一起避雷。