Linux服务器出现网站卡顿、数据库查询变慢、文件上传耗时增加等情况时,除了检查CPU和内存,还需要关注磁盘I/O。
磁盘I/O表示磁盘读写活动,与磁盘空间使用率是两个不同的概念。磁盘还有大量剩余空间,也可能因为读写请求过多、响应延迟增加而影响业务。
本文以常见Linux系统为例,介绍从磁盘、进程、内存和应用几个方向排查的方法。命令中的进程编号、容器名称和业务目录,需要替换为服务器的实际值。
1. 先确认是否存在磁盘读写问题
出现以下现象时,可以重点检查磁盘I/O:
-
网站和数据库同时变慢,但CPU计算占用不高。
-
备份、文件同步或数据导出期间,业务响应明显变差。
-
日志写入、文件上传和数据库提交经常等待。
-
系统负载升高,同时出现较多等待I/O的任务。
可以先运行:
top
观察CPU统计中的wa,即I/O等待相关指标。
wa升高可以作为排查线索,但不能直接说明某块磁盘已经达到性能上限;wa较低也不能排除磁盘延迟问题。还需要结合磁盘和进程统计进一步判断。
后续使用的iostat与pidstat通常由sysstat软件包提供。系统没有这些命令时,按发行版安装。
Ubuntu、Debian:
sudo apt update
sudo apt install sysstat
Rocky Linux、AlmaLinux等使用DNF的系统:
sudo dnf install sysstat
2. 使用iostat查看磁盘延迟和队列

执行:
iostat -xz -y 1 3
该命令每隔1秒输出一次统计,共输出3次。其中,-x显示扩展指标,-z隐藏当前没有活动的设备,-y跳过开机以来的累计平均报告。
重点关注以下字段:
| 字段 | 含义 | 排查重点 |
|---|---|---|
r/s、w/s |
每秒完成的读、写请求数 | 请求量是否明显增加 |
rkB/s、wkB/s |
每秒读、写数据量 | 是否出现大规模数据传输 |
r_await、w_await |
平均读、写请求耗时,单位毫秒 | 是否明显高于正常时段 |
aqu-sz |
平均未完成I/O请求数量 | 是否持续积压 |
%util |
设备存在I/O活动的时间占比 | 结合延迟和业务表现判断 |
await类指标包含排队和实际处理时间。不同版本的列名与排列可能有所区别。
不要仅凭%util接近100%就判断磁盘性能已经耗尽。 对能够并行处理请求的SSD、NVMe或RAID设备,这个数值不能直接代表性能上限。
更值得关注的是:业务变慢时,相关设备的延迟与队列是否同时升高,并且持续多个采样周期。
初步查看后,可以延长观察:
iostat -xz -y 1 30
3. 使用pidstat定位读写较多的进程

确认磁盘读写异常后,执行:
sudo pidstat -d -p ALL 1 3
重点查看:
-
PID:进程编号。 -
kB_rd/s:进程每秒引起的磁盘读取量。 -
kB_wr/s:进程每秒引起或将引起的磁盘写入量。 -
Command:进程名称。
其中,数据量字段使用KiB计量,1 KiB为1024字节。
找到读写较多的进程后,再核对完整命令。例如,查看PID为2841的进程:
ps -p 2841 -o pid,ppid,user,etime,args
确认它属于数据库、业务程序、备份任务,还是临时脚本,再决定处理方式。
进程写入统计与磁盘同一秒实际完成的写入量,不一定完全一致。 页缓存、延迟回写等机制会影响统计时间,因此需要结合连续采样判断。
如果进程很快退出,短时间采样可能无法捕获。可以增加采样次数,并核对故障时间附近的定时任务和应用日志。
4. 确认业务目录对应哪块磁盘
服务器可能同时存在系统盘、数据盘、逻辑卷和多个挂载点。需要确认发生问题的业务数据实际位于哪个设备。
以数据库目录/var/lib/mysql为例:
findmnt -T /var/lib/mysql
df -hT /var/lib/mysql
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT
这几条命令可以帮助确认:
-
目录所在的文件系统和挂载点。
-
文件系统的空间使用情况。
-
分区、逻辑卷与底层磁盘的关系。
如果实际数据库目录不同,应替换为真实路径。
使用LVM或其他设备映射时,iostat可能同时显示逻辑设备和底层设备。同一次读写可能出现在不同层级的统计中,不要简单相加。
将文件从同一块磁盘的一个目录移动到另一个目录,通常不会增加磁盘读写能力。是否能够分散负载,需要结合底层存储关系判断。
5. 检查内存不足和Swap是否增加磁盘压力

磁盘读写频繁,有时是内存紧张引起的。
执行:
free -h
vmstat 1 6
观察:
-
free中的available:可供新应用使用的内存估计值。 -
vmstat中的si、so:Swap换入和换出活动。 -
vmstat中的b:等待I/O完成的进程数量。
vmstat首行的速率类数据通常反映开机以来的平均情况,排查当前问题时,应重点查看后续采样。
如果业务卡顿期间持续发生Swap换入、换出,应同时检查内存占用与应用并发。仅增加磁盘空间,通常无法解决这种问题。
支持PSI的系统,还可以查看资源压力:
cat /proc/pressure/io
cat /proc/pressure/memory
其中:
-
some表示至少有部分任务因对应资源而阻塞的时间占比。 -
full表示所有非空闲任务同时因对应资源而阻塞的时间占比。 -
avg10、avg60、avg300分别对应最近10秒、60秒和300秒的平均值,单位为百分比。
如果I/O压力持续升高,并且与磁盘延迟和业务卡顿同时发生,就需要进一步处理读写来源。
相关文件不存在,可能是内核未提供或未启用该功能,不能据此判断没有资源压力。
6. Docker环境如何检查磁盘读写?
使用Docker部署业务时,可以先查看容器统计:
docker stats --no-stream \
--format 'table {{.Name}}\t{{.BlockIO}}'
BLOCK I/O显示容器累计的块设备读取量和写入量,不是每秒读写速度。
判断当前是否仍在大量读写,应间隔一段时间再次查看,比较同一容器的计数变化;不要跨容器重建或统计重置直接比较。
找到可疑容器后,可以查看挂载情况:
docker inspect --format '{{json .Mounts}}' web
将web替换为实际容器名称,重点核对数据库、上传文件和业务日志位于哪个挂载目录或数据卷。
容器内部写入、宿主机日志驱动写入和缓存回写,统计归属可能不同。如果容器统计无法解释磁盘负载,应继续在宿主机使用pidstat定位相关进程。
7. 检查磁盘空间、inode和内核错误
I/O问题也可能伴随文件系统异常或空间不足。
执行:
df -hT
df -i
分别检查文件系统容量和inode使用情况。容量耗尽、inode耗尽,都可能导致写入失败,需要与单纯的读写性能问题区分。
查看最近两小时的内核日志:
sudo journalctl -k -b --since "-2h" --no-pager
重点查找:
-
I/O error、Buffer I/O error。 -
设备超时或重置相关记录。
-
EXT4、XFS等文件系统错误。
-
文件系统被重新挂载为只读的记录。
发现持续读写错误或文件系统异常时,应保留完整日志,减少不必要的写入,并联系莱卡云技术支持核查。
不要直接对正在挂载使用的文件系统运行修复操作,也不要通过反复重启或强制改为可写来掩盖错误。
8. 常见原因和对应处理方向
| 常见原因 | 典型表现 | 处理方向 |
|---|---|---|
| 备份、同步任务集中执行 | 固定时间段读写明显增加 | 错峰执行,减少并发,使用任务自身的限速功能 |
| 数据库查询或批量写入增加 | 数据库进程持续产生大量读写 | 检查慢查询、索引和批处理规模 |
| 应用反复记录错误日志 | 日志相关写入持续增长 | 修复错误来源,调整日志级别与轮转策略 |
| 内存不足导致频繁换页 | Swap活动与卡顿同时出现 | 降低内存占用,评估增加内存 |
| 数据导入、解压或文件生成 | 对应任务启动后磁盘压力增加 | 拆分任务,限制并发,安排在低峰执行 |
| 存储性能不足或受到限速 | 延迟持续增加,吞吐量或请求量达到稳定平台 | 核对实际磁盘与实例的性能规格 |
读写量大并不一定代表异常。正常备份和数据处理也会产生较高I/O,关键是它们是否影响业务,以及是否超出预期。
9. 业务已经卡顿时怎么处理?
建议按照以下顺序操作:
-
保留现场。 记录异常时间、磁盘统计、进程编号和相关日志。
-
减少非必要读写。 对已经确认的备份、同步或批处理任务,使用程序支持的暂停、限速或正常停止方式。
-
控制业务并发。 根据应用能力减少同时执行的导出、上传、查询或后台任务。
-
处理根本原因。 修复重复报错、低效查询、任务重叠或内存不足等问题。
-
评估存储调整。 确认是持续性能需求后,再考虑升级存储、调整实例或迁移部分业务。
不要因为数据库进程读写较多就直接强制结束进程。异常终止可能引发业务中断和额外恢复负载。
排查期间,也不宜立即执行全盘扫描、批量压缩或磁盘压力测试,这些操作会继续增加读写。
磁盘扩容是否提升性能,取决于具体存储类型和产品规格。 下单或调整前,应确认需要提升的是容量、每秒请求数、吞吐量还是延迟表现。
10. 处理完成后如何验证?
处理后,重新执行:
iostat -xz -y 1 30
sudo pidstat -d -p ALL 1 10
结合业务实际情况,确认:
-
网站、接口和数据库响应恢复正常。
-
磁盘读写延迟回到正常范围。
-
请求队列不再持续积压。
-
原来的高读写任务已经受控。
-
Swap活动和资源压力没有继续恶化。
-
内核日志中没有新增读写错误。
如果问题只在每天某个时间段出现,应在下一次相同业务周期继续观察。
需要联系莱卡云技术支持时,建议提供服务器标识、异常发生时间及所在时区、受影响业务、磁盘与进程统计、相关错误日志,以及近期执行过的配置或任务调整,便于进一步定位。