磁盘诊断操作手册

7 分钟
本页目录

从“哪一层异常”开始:空间、inode、设备健康和 I/O 延迟是四个不同问题。本篇负责定位;分区、LVM、文件系统变更集中在 存储手册,避免两套互相矛盾的操作步骤。设备名、路径均需按本机替换。

当前任务入口
磁盘满了df 与 du 不一致
写入慢、卡顿延迟与负载
I/O error、只读设备健康与证据

先把目录映射到真实设备

# 定位包含目标目录的实际挂载
findmnt -T /var/lib

-T 接受目录/文件路径;看 SOURCE、FSTYPE、TARGET,再选下一步工具。路径落在根文件系统也会明确显示,不要因目录名像数据目录就认定它独立挂载。

# 把挂载源向下对应到块设备层级
lsblk -o NAME,TYPE,SIZE,FSTYPE,FSVER,LABEL,UUID,MOUNTPOINTS,MODEL

看 part、lvm、crypt、raid 等 TYPE;SIZE 是该层容量,不是文件系统可用空间。

# 核对稳定设备名指向哪个当前设备
ls -l /dev/disk/by-id/

维护设备时同时核对型号、序列号、容量与槽位,不只凭 sdX。

# 读取该文件系统的数据块使用率和类型
df -hT /var/lib

Use% 接近 100% 进入空间排查;-h 是可读单位,-T 显示类型。

# 单独检查 inode 是否耗尽
df -i /var/lib

IUse% 高可能是大量小文件;文件系统不同,inode 的分配与统计含义也不同。

先看 TYPE 与父子关系:目录可能在 LVM、加密映射、容器 overlay 或网络文件系统上。/dev/sdb 会随枚举变化;维护前把 by-id、型号、容量、挂载点一起核对。df 看文件系统,不是整块盘的剩余容量。

同一路径、同一挂载范围,再比较容量

沿同一挂载范围找占用

# 按一级子目录统计,避免跨文件系统
sudo du -x -h --max-depth=1 /var/lib

选占用最大的业务目录继续下钻;-x 保持同一文件系统。权限错误会造成少算,需要读 stderr,扫描本身也会带来 I/O。

# 查找已删除但仍被进程打开的文件
sudo lsof +L1

关注 COMMAND、PID、SIZE/OFF、NAME;对照设备确认属于目标文件系统。按所属应用支持的日志轮转或优雅重启释放句柄,不直接截断未知 fd。

# 在该路径是挂载点时查看其嵌套挂载
findmnt -R /var/lib

普通目录先用 findmnt -T 取得 TARGET,再对那个挂载点 -R。嵌套挂载会遮住底层文件,使 du/df 的比较范围不同。

# 只针对 journal 判断日志占用
journalctl --disk-usage

日志清理应按 systemd 手册 的归档与保留策略执行;不要根据目录总大小删除活跃日志文件。

这是 GNU du 写法;以目录本身为参数会包含隐藏项,du ... /var/lib/* 会漏掉它们。-x 不跨文件系统。lsof +L1 查已取消链接但仍打开的文件,先确认所属服务和日志轮转方式,正常关闭句柄后空间才释放;不要直接截断未知 /proc/PID/fd。

观察解释与下一步
df: blocks 100%, inodes available查大目录、已删除但仍打开的文件、快照保留与文件系统保留空间
df -i: IUse% 100%小文件数量耗尽 inode;按目录定位数量,清理必须遵守应用保留策略
df >> du先排除权限、挂载范围、隐藏文件,再看打开句柄和快照;两者计量也不完全相同
删了文件却没变小仍打开、快照引用、回收站或写入同时增长;先查原因再继续删

交互式浏览可用 ncdu;搜索文件可用 find/fd。fd 默认遵守忽略规则且忽略隐藏项,需要时明确使用 fd -HI,不要把空结果当作目录没有文件。Docker 卷、日志与镜像清理见 Docker,不能凭目录大就直接删除其数据目录。

把设备延迟与进程负载对齐

# 连续观察设备级吞吐、队列和延迟
iostat -y -xz 1

来自 sysstat;-y 跳过开机累计首份,-x 扩展字段,-z 隐藏无活动设备,1 是秒间隔。用 await、aqu-sz、吞吐对齐业务时段,Ctrl-C 停止。

# 按进程观察累计 I/O,聚焦有 I/O 的对象
sudo iotop -oPa

-o 只看活动,-P 按进程,-a 累计;累计大不等于此刻速率高,内核 accounting/权限不足要先读提示。

# 按秒查看进程读写与 I/O 等待线索
pidstat -d 1

与同一时间的 iostat 对照;进程写入可能先进入页缓存,不能要求每秒与设备写入逐字节相等。

# 读取任务因 I/O 阻塞的压力统计
cat /proc/pressure/io

some/full 的 avg10/60/300 是对应时间窗比例,total 是累计微秒。它补充“任务是否被拖慢”,不能单独指出哪块盘损坏。

iostat 来自 sysstat;-y 跳过自启动以来的首份平均值。结合读写速率、await、队列和应用延迟看连续区间:%util 高不等于所有 NVMe/RAID 都已达到吞吐上限,低吞吐高延迟也可能是同步小写入、队列等待或设备错误。iotop 的权限与内核 accounting 支持需满足;没有条目不证明没有 I/O。

先保全证据,再考虑修复

按设备类型选择健康查询

# 读取已核对 SATA/SAS 设备的详细健康记录
sudo smartctl -x /dev/sdX

设备占位符必须替换;USB 桥的协议可先查 smartctl --scan-open,再按支持的 -d 类型查询,不盲目写固件或发起长自检。

# 对 NVMe 控制器读取健康日志
sudo nvme smart-log /dev/nvme0

这是 NVMe 的选择项;关注 critical_warning、media_errors、temperature 和寿命使用量的变化,不把历史总数单独当成新增故障。

# 按时间关联设备重置、I/O 错误与只读切换
journalctl -k -b --no-pager

保留故障前后记录;硬件读错优先保全可恢复副本,不在原盘上反复强制修复。

确认 TRIM 支持与调度

# 查看设备栈报告的 discard 能力
lsblk -D

DISC-MAX 等为能力线索,不证明当前文件系统已运行 TRIM。

# 查看是否安排周期 TRIM
systemctl status fstrim.timer --no-pager

实际执行结果读 journalctl -u fstrim.service;先检查已有计划,不再叠加重复调度或无条件开启持续 discard。

以上是不同设备的选择项,不是全部照抄执行。USB 桥可能需 smartctl -d 指定协议,先看设备支持。SMART PASSED 不能排除线缆、电源、控制器或即将发生的故障;关注错误计数的变化、温度、介质错误及内核重置。自检会产生负载,时长由设备估计,不固定“几分钟”。

出现 I/O error 或文件系统转只读时,先停止非必要写入、确认备份与恢复入口,再判断硬件还是文件系统损坏;不要先 remount,rw 或 fsck -y。离线检查与层级扩容见 存储。TRIM 需要整条设备栈支持;先查看 fstrim.timer 的计划,不为所有 SSD 强行同时启用持续 discard。

GNU du · sysstat · smartmontools