大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!
上周讲了参数调优——哪些参数值得调、怎么调。但有一个前置问题没解决:你怎么知道该调哪个参数?
系统慢了,CPU飙了,磁盘I/O满了,内存快爆了——面对一堆异常指标,先查哪个?
很多DBA的直觉是“CPU最高就先看CPU”。但CPU高往往是表象,真正的根因可能在磁盘、在网络、在内存。
今天不讲具体参数,先讲一套诊断优先级——遇到性能问题,按什么顺序排查,才不会走弯路。
一、先系统后数据库:不要一上来就查SQL
接到“系统慢了”的反馈,很多DBA的第一反应是翻慢查询日志。这个直觉可以理解,但往往是低效的。
正确的排查顺序是:先看系统层,再看数据库层。
系统层是“体检”——CPU、内存、IO、网络四大资源,哪个亮了红灯?数据库层是“问诊”——系统层没有瓶颈时,才深入数据库内部排查;系统层已亮红灯时,优先解决资源问题。
慢查询日志只记录了“已经慢了的SQL”,不记录“为什么慢”。如果系统层资源已经打满了,翻慢查询日志是浪费时间——先把资源问题解决了,慢查询自然就少了。
二、四大资源的诊断优先级
遇到性能问题,建议按以下顺序排查:
第一步:查磁盘I/O(优先级最高)
为什么I/O排第一?因为I/O问题是数据库性能问题最常见的根源。而且I/O问题的特征很明确,容易被误判为CPU问题。
怎么看?
# 实时查看磁盘I/O iostat -x 1
关键指标:
| 指标 | 含义 | 危险信号 |
|---|---|---|
%util | 磁盘繁忙程度 | >80% 说明磁盘快打满了 |
await | I/O请求平均等待时间 | 远超svctm说明在排队 |
r/s/w/s | 每秒读写次数 | 接近磁盘IOPS上限 |
wa(top中) | CPU等待I/O的时间 | >10%说明I/O是瓶颈,CPU在空等磁盘 |
常见场景:top里看到CPU使用率很高,但wa(iowait)也很高——CPU其实在等磁盘,不是在算数据。这时候加CPU没用,得解决磁盘问题。
怎么解决?
检查是否有全表扫描(会在第三步确认)
检查是否有大量排序操作或临时表写磁盘
调整
innodb_io_capacity等I/O相关参数考虑升级磁盘(HDD→SSD→NVMe)
第二步:查内存(优先级第二)
内存不足会导致频繁的磁盘交换(Swap),而Swap一发生,性能会直接崩盘。内存问题往往表现为“磁盘I/O高”或“CPU高”——因为内存不够,系统在频繁换页,CPU忙着处理换页中断。
怎么看?
# 查看内存使用 free -h # 查看是否有Swap活动 vmstat 1
关键指标:
| 指标 | 含义 | 危险信号 |
|---|---|---|
available/free | 可用内存 | 接近0说明内存不足 |
si/so(vmstat) | Swap换入/换出 | 非0说明内存在换页 |
| InnoDB缓冲池命中率 | 数据页在内存中的命中比例 | <95%说明缓冲池不够大 |
常见场景:free -h显示内存快用完了,vmstat的si和so列出现非0值。这时候查SQL没用——加内存才是正解。
怎么解决?
调整
innodb_buffer_pool_size(通常设为物理内存的50%-70%)检查是否有内存泄露(连接未释放、大查询占用大量临时内存)
考虑增加物理内存
第三步:查CPU(优先级第三)
CPU高是数据库性能问题最常见的“报警信号”,但它往往是结果,不是原因。所以CPU排在第三位——先排除了I/O和内存的问题,再看CPU。
怎么看?
# 查看CPU使用情况 top
关键指标:
| 指标 | 含义 | 危险信号 |
|---|---|---|
us(用户态) | 应用在跑计算 | 高说明SQL在做大量计算或排序 |
sy(内核态) | 系统在忙 | 高说明连接风暴或锁竞争 |
wa(I/O等待) | CPU在等磁盘 | 高说明磁盘是瓶颈 |
load average | 系统平均负载 | 持续高于CPU核数说明过载 |
us高的场景:us(用户态CPU)高,说明SQL在做大量计算或排序。这时候才轮到查慢查询日志、看执行计划、优化SQL。
sy高的场景:sy(内核态CPU)高,说明系统在频繁切换上下文。通常是连接风暴或大量锁竞争导致的。
怎么解决?
us高 → 优化SQL、加索引、减少排序
sy高 → 检查连接数是否突增、检查锁等待
负载高 → 考虑升级CPU或增加节点
第四步:查网络(优先级第四)
网络问题在集中式数据库中相对少见,但在分布式架构中非常关键。网络瓶颈表现为高延迟和数据包丢失。
怎么看?
# 查看网络流量 sar -n DEV 1
关键指标:
| 指标 | 含义 | 危险信号 |
|---|---|---|
| 网络吞吐量 | 发送/接收速率 | 接近带宽上限 |
| 重传率 | 数据包重传比例 | 过高说明网络不稳定 |
常见场景:应用和数据库在不同机房,跨区域调用延迟高;或者云环境网络带宽被打满。
怎么解决?
将应用和数据库部署在同一可用区
升级网络带宽
优化跨节点查询,减少数据传输量
三、诊断流程图
接到“系统慢了”的反馈 ↓ 第一步:看磁盘I/O(iostat -x 1) ↓ %util>80% 或 wa>10%? ↓ 是 ↓ 否 解决磁盘问题 第二步:看内存(free -h) ↓ ↓ 内存不足 或 Swap活动? ↓ 是 ↓ 否 解决内存问题 第三步:看CPU(top) ↓ us高? sy高? 负载高? ↓ 查慢查询SQL、执行计划 ↓ 第四步:看网络(如有需要)
四、一个真实案例
某电商系统在促销期间突然响应变慢,DBA看到top里CPU使用率85%,第一反应是“CPU瓶颈,要加核”。
但仔细看top的输出:wa(iowait)占了30%。这意味着CPU有30%的时间在“等磁盘”,不是在“算数据”。
用iostat -x 1一看,磁盘%util长期在95%以上,await超过50ms。根因是某张表的统计信息过旧,导致优化器选错了执行计划,频繁触发全表扫描,把磁盘打满了。
解决方案:执行ANALYZE TABLE更新统计信息,查询走了正确的索引,磁盘I/O从95%降到30%,CPU使用率从85%降到40%。系统恢复正常。
复盘:如果只看CPU高就去加核,问题根本解决不了——加再多核,CPU还是在等磁盘。
五、总结
遇到性能问题,不要一上来就翻慢查询日志。先按这个顺序排查:
1. 磁盘I/O—— 最常见、最容易被误判的瓶颈。先看iostat和wa,解决了I/O问题,很多“CPU高”问题自然消失。
2. 内存—— 内存不足导致Swap,性能直接崩盘。先看free -h和vmstat。
3. CPU—— 排除了I/O和内存再看CPU。us高查SQL,sy高查连接和锁,wa高回到第一步。
4. 网络—— 分布式架构中不可忽视,集中式架构中优先级最低。
记住一句话:先系统后数据库,先资源后SQL。系统层亮了红灯,就别在数据库层浪费时间。
小耶在手,SQL 不愁
还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~