服务器入坑指北:云盘变慢或报 I/O 错误时你能做什么
盘突然变慢,业务跟着一起卡;过一阵又自己好了,周而复始。或者内核日志里冒出 I/O 错误,可盘看起来还能读写,你完全看不出严重程度。想判断是"盘的问题"还是"这台机器的问题",手边却没有任何硬件读数——虚拟盘上本来也拿不到那些东西。
这里的难点不在某个命令,而在顺序与分流:一上来就去调文件系统参数,或者把"等 I/O 的时间"当成"宿主没给 CPU",方向反了后面全是白做;更严重的错误是在还没把数据保下来时就开始"研究",把现场和可用副本一起弄没。
这篇先把"变慢"与"报错"分成两条路径,给出分水岭(窃取时间)与报错链的判读顺序,再给一条顺序不能反的动作闭环:先保数据,再研究。全文只给形态与判据,不给可以照抄的数值阈值。
先分流:是变慢,还是报错
两条路径的动作完全不同,分流错了后面全白做:
- 变慢:延迟抬升、抖动,但内核日志里没有 I/O 错误;
- 报错:内核日志里出现 I/O 错误,可能伴随文件系统被重挂为只读。
前者的动作在"错峰、限流、升配、换节点"之间选;后者的动作是"先保数据、再看能不能继续用、然后(在虚拟盘上)把问题交给提供商"。所以第一件事不是敲命令,而是先看日志里到底有没有错误。
分水岭:窃取时间说明瓶颈是不是你能解决的
这是全文最关键的判断依据。窃取时间指的是:客户机需要、但宿主机没有提供给它的 CPU 时间——宿主把资源给了别处。它有三个特点要记住:统计在 /proc/stat 里给出、常见工具以百分比或独立列显示、无法关闭。
判据很直接:
- 变慢的同时,窃取时间也在升高 → 瓶颈在宿主或共享资源侧。这时候你在客户机里调任何参数都没用,因为问题不在你这台机器上;动作是错峰、升配、换节点,或者找提供商。
- 窃取时间不高,但设备侧指标难看 → 瓶颈更可能在存储路径本身(后面一节讲怎么判读)。
必须区分开的是另一个指标:等 I/O 的时间。它表示"CPU 空闲着、但有未完成的 I/O 请求在等"——那是你在等别人(盘、控制器、后端);而窃取时间是"你想要 CPU、宿主不给"。一个指向存储路径,一个指向宿主争抢,混为一谈就会去优化错的方向。
还有一个读数细节:部分内核版本下,某些工具不会显示窃取项。这时候换一个工具,或者直接读/proc/stat——统计本身一直在,只是显示与否的问题。
变慢侧:设备级与 CPU 侧同屏看
iostat -x <间隔> <次数> # 设备级:平均队列长度、平均等待、利用率、平均请求大小
vmstat <间隔> <次数> # CPU 侧:窃取时间与等 I/O 时间(列名按工具版本)
cat /proc/stat # 直读:包含窃取项(工具不显示时用它)
uptime # 粗看负载趋势,与上面同屏对比
没装这些工具时也有替代:直接读 /proc/diskstats 与 vmstat,能得到同类信息,判读方式仍然是看形态——队列是否长期偏高、等待是否持续抬升。
判读要按"形态"来,而不是记一个数字:
- 平均队列长度长期偏高 → 设备跟不上到达的请求;
- 平均等待时间由"在队列里等的时间 + 被服务的时间"构成,长期偏高并伴随高利用率 → 存储路径跟不上;
- 利用率长期贴顶,同时请求大小或形态明显异常 → 既可能是负载形态问题,也可能是后端在限速;
- 窃取时间与上述指标同时升高 → 更倾向宿主侧争抢;
- 等 I/O 很高,但设备指标并不难看 → 瓶颈可能在设备之下或之外(控制器、网络存储后端),先去查那条路径。
一句话判据:先分清是"设备跟不上",还是"根本轮不到你"。前者在存储路径上找,后者在宿主与共享资源上找。
报错侧:只读是保护性反应,不是原因
内核检测到 I/O 错误或元数据错误之后,会主动冻结对文件系统的写入——你会看到挂载变成只读。这是保护性反应,目的是避免在已知不可靠的介质上继续扩大损坏;它不是问题的原因,所以"把只读改回可写就好了"是错误的理解。
日志里会看到两类信息,形态如下(不同内核版本的措辞有差异,看形态即可):
- 块层:I/O 错误、请求更新失败、缓冲区 I/O 错误一类;
- 文件系统层:ext 家族的错误与日志中止;XFS 的元数据损坏、因日志错误而关闭文件系统一类。
判读顺序不能乱:
- 确认挂载状态:找出哪些挂载点已经变成只读;
- 从内核日志里取首因:看最早那条相关错误,而不是最后刷屏的那条——最后那条往往是首因的后果;
- 尝试重新挂回可写:这是区分"瞬时抖动"与"持续故障"的动作——能成功通常说明是瞬时问题;如果很快又变回只读,或者根本挂不回去,说明问题在文件系统层之下,需要按报错路径处理。
还有一条方向性判断:当日志里块层信息占主导时,优先怀疑介质、控制器与存储后端,而不是先对文件系统猛敲工具。在只读状态下继续对文件系统做各种尝试,只会把现场搞得更乱。
虚拟盘上你能做的只有这几件事
这一节是前提,不是补充:虚拟盘上没有"读自监测读数、修坏道、换盘"这条路——物理介质不属于你,属于提供商。所有围绕"我要修好这块盘"的动作,在这里都不成立。
真正能做的动作只有这几个:取证、快照、克隆或副本、迁移、重建,以及把问题报给提供商。最后这条是正经的处置动作,不是推卸——你手上没有介质层的工具,把准确的错误信息与时间点交上去,才是让问题被处理的路径。
顺带排除一类"伪装成介质故障"的情况:精简置备的卷写满之后,写入也会以 I/O 错误的形式出现。这是存储侧的容量问题,不是介质坏了——先确认容量,再谈介质。
动作闭环:先保数据,再研究(顺序不能反)
- 取证(趁还能读):把上面两组只读观测的结果与内核日志里的首因留下来。这一步是在"还能读"的时候做的。
- 快照 / 克隆 / 副本:先拿到一份可用副本。这是后面所有动作的前提。
- 判定:
- 能自愈:延迟出现周期性抖动、与快照/备份窗口重合、且没有错误 → 用错峰与限流缓解;
- 必须迁移:延迟长期抬升、窃取时间高、还伴随 I/O 错误 → 在客户机里做什么都没用,动作是升配、换节点或找提供商。
- 迁移或重建:从副本恢复服务。
- 报提供商 / 换节点:虚拟盘上的介质层问题只能这样处理。
- 复核:按下一节的清单验证。
为什么顺序不能反?因为"研究"往往包括挂载、检查、修复这类动作,它们会直接改变现场;而如果你还没拿到副本,一次失败的修复就可能把唯一的可用数据也弄没。先保数据,再研究——这一条比任何指标都重要。
回滚考虑也放在这一步:迁移前保留副本;重建之前先确认副本可读可用;任何"动原盘"的动作都排在副本之后。
现象到动作的判定表
| 你看到的现象 | 走哪条路径 | 看什么证据 | 结论 | 动作 |
|---|---|---|---|---|
| 延迟抬升、无错误,且与快照/备份窗口重合 | 变慢 | 设备指标 + 窗口时间 | 自愈型抖动 | 错峰、限流 |
| 延迟长期抬升,窃取时间同时偏高 | 变慢 | 窃取时间 + 设备指标 | 宿主侧争抢 | 升配/换节点、报提供商 |
| 延迟抬升,但设备指标不难看,等 I/O 偏高 | 变慢 | 等 I/O + 下游链路 | 瓶颈可能在控制器或网络存储 | 查那条路径,别改文件系统 |
| 日志出现块层 I/O 错误,挂载变只读 | 报错 | 首因日志 + 挂载状态 | 保护性反应 | 先保数据;能挂回可写则继续观察 |
| 挂回可写后很快又变只读 | 报错 | 时间间隔 + 错误是否重复 | 持续故障 | 迁移/重建 + 报提供商 |
| 偶发一次错误,之后不再复现 | 报错 | 能否复现、是否同一区域 | 瞬时可观察 | 留证据观察,不要过度反应 |
| 写入报 I/O 错误,但设备指标正常 | 报错 | 存储侧容量与配额 | 容量问题伪装成介质故障 | 先确认容量,再谈介质 |
迁移或恢复后怎么验证:每项一条判据
- 延迟趋势回到基线:在同一业务时段与迁移前对比趋势,而不是看某一瞬间。
- 内核日志不再出现同类错误:观察窗口跨越一次完整的业务高峰。
- 挂载状态正常且可写:不是"能挂上"就算,要确认可写并且没有再次变只读。
- 业务侧指标恢复:用改动前同一套观测口径复核。
- 留档完整:副本、迁移记录与内核日志首因都已留存,便于对提供商复述。
- 验证方式固定成一句话:在原来的业务时段,用原来的操作复现一次,延迟与错误都不再出现,才算通过。
这篇不解决什么
- 不解决空间问题:《磁盘还有空间却写不进去》那篇处理的是空间与 inode 耗尽,判定入口是"空间类报错"。
- 不做文件系统层判断:《一致性检查什么时候不该跑》那篇讲的是文件系统层"要不要检查、能不能检查";本篇不做任何检查动作,只处理"变慢/报错"的分支。
- 不涉及换出层:《zswap 的配置取舍》那篇在换出路径上。
本篇的位置是块设备与虚拟盘 I/O 层,只做"变慢"与"报错"这两条分支的动作选择。
踩坑清单
- 把"等 I/O 的时间"当成"窃取时间"(或反过来):一个是等别人,一个是轮不到你,方向会完全错。
- 在宿主侧瓶颈上做客户机内调参:窃取时间高说明问题不在你这台机器里。
- 只看到一次错误就当没事,或者反过来过度反应:判据是能否复现、是否集中在同一区域、是否伴随只读重挂。
- 先"研究"后保数据:顺序反了,一次失败的修复可能把唯一的可用数据也弄没。
- 在只读挂载的状态下继续写、继续对着文件系统敲工具:只会扩大损坏。
- 把虚拟盘当物理盘,去找"读自监测读数、修坏道、换盘"这类动作:这条路在虚拟盘上不存在。
- 忽略快照或备份窗口造成的周期性抖动:先看延迟有没有周期性,再看它跟谁重合。
- 迁移前没留副本:迁移失败就没有退路了。
- 只看应用日志、不看内核日志:首因在内核日志里,应用日志通常只是"结果"。
- 认为"盘还能读写"就等于没问题:只读重挂是保护性反应,能读写不代表介质可靠。
- 把精简置备卷写满当成介质故障:先确认存储侧容量。
- 把文件系统重挂只读当成故障本身去"修":它是保护性反应,首因通常在更下面一层。
- 点赞
- 收藏
- 关注作者
评论(0)