GPU服务器与GPU云服务器磁盘异常怎么查?从inode、I/O延迟和日志增长定位问题

训练任务突然卡住、检查点保存超时、容器启动失败,或者系统提示 No space left on device,不一定只是磁盘容量耗尽。GPU 服务器上的大量模型权重、数据集、缓存和检查点可能快速占满空间;大量小文件则可能先耗尽 inode;云盘或本地磁盘的 I/O 延迟升高,也会让 GPU 利用率下降,却不一定伴随容量告警。日志持续增长、文件系统进入只读状态,以及“df 显示已满但 du 找不到大文件”,都需要分别判断。
建议按以下顺序排查:先确认影响范围并保留现场,再检查容量和 inode,随后确认挂载点与文件系统状态,再观察 I/O 延迟和进程竞争,最后定位日志、缓存、检查点或已删除但仍被进程占用的文件。修复后还要在实际业务负载下复核,不能只看一次 df -h 就认为问题已经解决。
先确认故障范围,避免误删业务数据
排查前记录故障发生时间、受影响的任务、节点、挂载路径和最近一次正常时间。尽量不要立即重启训练任务、删除日志或清理缓存,先保存一组只读信息:
date
hostname
uptime
df -hT
df -i
findmnt -A
这些结果可以回答三个基础问题:
- 是整个系统根分区异常,还是某个数据盘、容器目录或临时目录异常?
- 是数据块容量不足,还是 inode 数量耗尽?
- 挂载点是否变成只读,或者目标目录实际上没有挂载成功而落到了根分区?
如果只有一个训练任务失败,而其他任务正常,应优先查看该任务的数据目录、检查点目录和容器临时目录。如果多个任务同时出现读写超时,则要提高对共享存储、云盘、本地磁盘或文件系统状态的怀疑。
GPU服务器和GPU云服务器有什么区别?先确定存储边界
GPU 服务器与 GPU 云服务器的排查思路基本一致,但能够观察和修复的层级不同。GPU 服务器通常可以直接查看本地磁盘、RAID 控制器和硬盘健康信息;GPU 云服务器的磁盘可能是系统盘、数据盘、临时本地盘或云平台提供的块存储,具体属性取决于实例和存储配置,不能仅凭设备名称判断。
| 对比项 | GPU服务器 | GPU云服务器 |
|---|---|---|
| 容量与 inode | 直接查看本机文件系统和挂载点 | 仍需在实例内查看,但还要核对云控制台中的磁盘挂载与容量状态 |
| I/O 延迟 | 可结合本地磁盘、RAID 和控制器信息判断 | 需要结合实例内 iostat 与云平台磁盘监控,区分系统层和存储层问题 |
| 硬盘健康 | 在有权限且设备直通时可查看 SMART;经过 RAID 控制器时还需看控制器信息 | 虚拟块设备通常不一定提供可用的 SMART 信息,不应强行据此判断底层硬盘 |
| 文件系统修复 | 可安排停机、卸载分区后离线检查 | 可能需要停止实例、从救援环境处理,或使用云平台快照、克隆和迁移能力 |
| 处理方式 | 可更换磁盘、检查 RAID 或调整本地目录 | 应先核对实例类型、磁盘类型、快照和变更规则,避免误操作导致数据丢失 |
因此,云服务器中看到的 /dev/vda、/dev/sda 或其他设备名只能说明操作系统识别到了块设备,不能直接说明底层介质类型和性能。先执行以下命令确认实际关系:
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS,ROTA,RO
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS
如果是云服务器,还要把实例内的挂载路径、设备大小和故障时间,与云平台控制台中的磁盘状态、监控曲线和操作记录对齐。没有这些信息时,不要直接执行扩容、卸载或重建磁盘操作。
第一步:分别检查容量和 inode
1. 检查数据块容量
df -hT
重点看 Use%、Mounted on 和 Type。容量达到上限时,常见影响包括:
- 新文件无法创建,训练任务无法保存检查点;
- 日志无法继续写入,服务可能因为写日志失败而退出;
- 数据库、缓存或容器运行目录无法创建临时文件;
- 即使还有少量可见空间,普通用户也可能因保留空间或权限问题无法写入。
确认某个挂载点后,再查看一级目录占用。以下命令适用于常见 Linux GNU coreutils 环境,-x 用于避免把其他挂载盘的内容重复算入:
sudo du -xhd1 / 2>/dev/null | sort -h
sudo du -xhd1 /var 2>/dev/null | sort -h
sudo du -xhd1 /data 2>/dev/null | sort -h
将 /data 替换为实际挂载点,不要对不确定的路径直接执行删除命令。继续向占用最大的目录下钻:
sudo du -xhd1 /data/checkpoints 2>/dev/null | sort -h
sudo du -xhd1 /data/cache 2>/dev/null | sort -h
sudo du -xhd1 /var/log 2>/dev/null | sort -h
df 与 du 的结果不一致时,不要立即认为 df 出错,常见原因有:
- 文件已经删除,但进程仍然打开文件描述符;
du没有权限读取某些目录;du -x只统计当前文件系统,而df统计的是整个挂载点;- 目录中存在挂载点,统计边界不同;
- 文件系统元数据或日志出现异常。
2. 检查 inode
df -ih
如果 IUse% 接近或达到 100%,即使 Avail 仍有空间,也可能无法创建新文件。inode 耗尽通常与以下内容有关:
- 数据集切分后产生大量小文件;
- 训练缓存、缩略图、临时片段或中间结果数量过多;
- 每次任务启动都创建新的日志目录;
- 日志轮转产生大量小文件;
- 容器层或构建缓存长期未清理。
可以按目录统计文件数量。以下命令会遍历目录,目录很大时会产生一定读取开销,建议在业务低峰执行:
sudo find /data -xdev -type f -printf '%h\n' 2>/dev/null \
| sort | uniq -c | sort -n | tail -20
也可以查看某个目录下的文件和目录总数:
sudo find /data/cache -xdev -type f 2>/dev/null | wc -l
sudo find /data/cache -xdev -type d 2>/dev/null | wc -l
容量不足与 inode 不足的修复方向不同。前者需要定位大文件、旧检查点或日志;后者需要减少小文件数量、调整缓存组织方式、合并数据分片或清理已经确认不再使用的目录。不要因为 df -h 看起来还有空间,就忽略 df -i 的结果。
第二步:确认挂载点和文件系统状态
容量正常但读写仍然失败时,检查目录是否挂载正确、是否被切换成只读:
findmnt -T /data
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /data
lsblk -f
重点关注:
SOURCE是否是预期设备;FSTYPE是否与实际文件系统一致;OPTIONS中是否出现ro;- 目标目录是否因为挂载失败而落回根文件系统;
- 设备是否显示只读状态。
继续查看内核和系统日志中的文件系统错误:
sudo journalctl -k -b --no-pager \
| grep -Ei 'I/O error|blk_update_request|buffer I/O|EXT4-fs|XFS|read-only|filesystem'
没有 systemd-journald 或 journalctl 的系统,可以使用:
sudo dmesg -T \
| grep -Ei 'I/O error|blk_update_request|buffer I/O|EXT4-fs|XFS|read-only|filesystem'
如果出现 I/O error、文件系统损坏、日志回放失败或自动切换只读,优先保护数据,不要反复执行写入操作。先确认备份、快照或检查点可用,再安排维护窗口。文件系统修复必须在卸载后或救援环境中进行,不能对正在使用的挂载点直接运行修复工具。
以常见文件系统为例:
# 仅示意,必须先确认设备、文件系统类型,并确保目标分区已卸载
sudo fsck -f /dev/DEVICE # 适用于相应的 ext 文件系统
sudo xfs_repair /dev/DEVICE # 适用于 XFS
这类命令可能修改文件系统元数据,执行前应完成备份或快照,并记录原始设备和挂载关系。设备填错、分区仍在挂载或中途断电,都可能扩大损坏范围。修复过程不可简单回滚,恢复方式通常是使用备份、快照或重新挂载原始数据副本。对于云服务器,应优先查看云平台提供的离线检查、快照和救援流程,不要依据设备名称猜测操作步骤。
第三步:从 I/O 延迟判断是不是磁盘忙
容量和文件系统都正常时,问题可能是磁盘没有“满”,但已经无法及时完成读写。先确认是否安装了 sysstat,然后采样设备级指标:
iostat -xz 1 5
常见字段的判断方法如下:
await:请求从提交到完成的平均等待时间,通常以毫秒显示。持续升高说明请求完成变慢,但要结合业务类型和历史基线判断。avgqu-sz:平均等待队列长度。队列持续增加,说明提交速度超过了设备处理速度。%util:设备忙碌比例。持续偏高可以作为繁忙信号,但对并发能力不同的设备不能单独作为“磁盘已饱和”的结论。r/s、w/s、rkB/s、wkB/s:读写请求量和吞吐量,用于判断是读取、写入还是混合负载。
同时观察系统是否存在内存压力、阻塞和 I/O 等待:
vmstat 1 5
如果系统支持 pidstat,可以进一步定位产生磁盘读写的进程:
pidstat -d -p ALL 1 5
结合进程列表确认这些读写是否来自预期的训练任务、数据预处理、日志服务、容器运行时或备份程序:
ps -eo pid,ppid,user,stat,comm,args --sort=-%cpu | head -30
判断 I/O 延迟时,应把采样时间与故障时间对齐。例如:
await和队列长度在训练保存检查点时同步升高,可能是检查点写入、数据预处理或多个任务争用同一设备;- 设备读写量不高,但延迟持续升高,同时内核日志出现 I/O 错误,应优先检查设备或文件系统;
- 只有单个进程读写异常,其他设备指标正常,可能是应用自身阻塞、单个大文件操作或应用线程问题;
- GPU 利用率下降并不等于 GPU 硬件故障。如果数据加载、检查点写入或缓存读取被磁盘拖慢,GPU 也会因等待数据而空闲。
云服务器需要把 iostat 采样结果与云平台监控的磁盘读写、队列、延迟或突发能力指标进行时间对照。实例内指标正常而控制台显示存储侧异常,或者两者都异常时,处理路径不同,不能只凭一个命令判断底层磁盘状态。
第四步:定位日志增长和已删除文件
1. 查找日志目录中的异常增长
先确认日志目录占用:
sudo du -xhd1 /var/log 2>/dev/null | sort -h
sudo find /var/log -xdev -type f -printf '%s %p\n' 2>/dev/null \
| sort -n | tail -20
检查 systemd 日志占用:
sudo journalctl --disk-usage
如果日志在短时间内持续增长,先查看最近的重复报错,而不是直接删除整个日志目录:
sudo journalctl -p warning -b --no-pager -n 200
sudo journalctl -b --no-pager -n 200
同时检查日志轮转配置是否存在、是否能正常解析。logrotate -d 是调试模式,不会执行实际轮转:
sudo logrotate -d /etc/logrotate.conf
sudo ls -l /etc/logrotate.d/
日志暴涨的根因可能是存储错误反复重试、训练任务启动失败、数据权限错误、应用异常循环,或者日志轮转没有生效。只清理日志而不处理源头,空间很快会再次耗尽。
如果已经确认需要释放 systemd 日志空间,应先保留故障时间段所需的日志,并确认业务不依赖被清理的历史记录。下面命令会删除较旧的归档日志,参数只是示例,保留量必须根据磁盘余量、审计要求和故障调查需要确定:
# 执行前备份或导出需要保留的日志;该操作会删除符合条件的旧归档日志
sudo journalctl --vacuum-size=1G
这类清理操作无法恢复被删除的归档日志。若存在合规、审计或故障取证要求,应先导出并校验备份,再执行清理。
2. 处理“文件已删除但空间未释放”
当 df -h 显示空间紧张、du 却找不到对应的大文件时,检查仍被进程打开的已删除文件:
sudo lsof +L1
重点看文件大小、进程名、PID 和所属服务。典型场景是日志文件被删除或轮转后,服务仍保持旧文件描述符,直到服务重新打开日志,空间才会释放。
处理时应先确认服务能否重启,以及训练任务是否已经保存检查点。对于关键任务,优先使用应用自身的日志重载机制;没有重载机制时,在维护窗口重启对应服务,并立即验证服务状态:
sudo systemctl status SERVICE_NAME
sudo systemctl restart SERVICE_NAME
sudo systemctl status SERVICE_NAME
SERVICE_NAME 必须替换为实际服务名。重启前应备份配置、确认依赖关系和回滚方式;对训练进程、数据库或承载关键业务的服务,不要直接套用此命令。若不能重启,可以先记录 PID、文件大小和服务配置,结合应用文档决定是否能够安全关闭文件描述符或进行日志重载,避免直接操作 /proc 造成服务异常。
第五步:排查检查点、缓存和临时文件
GPU 任务通常会同时产生模型权重、检查点、数据预处理结果、编译缓存和临时文件。按目录查看大文件,有助于判断是正常增长还是异常重复生成:
sudo find /data -xdev -type f -size +10G -printf '%s %TY-%Tm-%Td %TH:%TM %p\n' \
2>/dev/null | sort -n | tail -30
10G 只是筛选示例,不代表所有环境都应以该值为阈值。对于空间较小的系统盘,应使用更小的筛选条件。
每个大文件都要确认以下信息:
- 是否属于正在运行的任务;
- 是否是最新且唯一需要保留的检查点;
- 是否存在可恢复的备份或远端副本;
- 是否由应用配置自动重新生成;
- 删除后是否会导致任务无法恢复或重新下载大量数据。
确认不再使用的文件后,再按照业务的保留策略清理。清理前应完成备份或快照,明确影响的挂载点和目录,并保留删除清单。不要使用未经核对的通配符清空整个 /data、/var/log 或容器目录,也不要把“缓存”默认视为可以安全删除的内容。有些缓存包含任务中间状态,删除后会导致任务重新计算并加重 I/O。
常见结果与对应处理方向
| 观察结果 | 更可能的原因 | 下一步 |
|---|---|---|
df -h 接近 100%,df -i 正常 | 大文件、检查点、日志或缓存增长 | 用 du 和 find 定位目录及文件,按保留策略清理或扩容 |
df -h 还有空间,df -i 接近 100% | 大量小文件或日志轮转文件 | 统计文件数量,合并分片、调整缓存和日志组织方式 |
df 很满,du 明显偏小 | 已删除但仍被进程打开的文件,或统计边界不同 | 使用 lsof +L1,确认服务后安全重载或重启 |
挂载选项出现 ro,内核有文件系统错误 | 文件系统保护性只读或设备异常 | 停止写入,备份后安排离线检查或平台侧恢复 |
await、队列长度持续升高 | I/O 竞争、设备处理变慢或存储侧限制 | 用 pidstat 定位进程,并结合本地或云平台监控核对 |
| 日志目录持续快速增长 | 应用报错循环、I/O 重试或轮转失效 | 先保留故障日志,再处理报错源和轮转策略 |
| 只有某个任务失败,其他任务正常 | 任务目录、权限、临时文件或检查点配置异常 | 对照任务路径、用户权限和应用日志,不要先判断为整块磁盘故障 |
修复后的验证方法
修复完成后,不要只检查“空间是否下降”。至少完成以下验证:
- 重新查看容量、inode、挂载状态和文件系统类型:
df -hT
df -i
findmnt -T /data
- 进行一次受控的创建、写入、读取和删除测试。测试目录应位于受影响挂载点,文件大小和写入方式要接近实际任务,但不要在生产数据目录中制造无关文件:
testdir=/data/.disk-check
mkdir -p "$testdir"
dd if=/dev/zero of="$testdir/test.bin" bs=1M count=16 conv=fsync status=progress
sha256sum "$testdir/test.bin"
rm -f "$testdir/test.bin"
rmdir "$testdir"
以上测试会产生实际写入,执行前确认目录路径无误、磁盘有足够余量,并避免在 I/O 已经严重拥塞时运行。
- 在代表性业务负载下重新采样 I/O:
iostat -xz 1 5
vmstat 1 5
将修复后的结果与故障前或历史正常时段比较,不使用脱离设备类型、业务模型和采样时间的固定阈值。
- 让一个可恢复的训练任务完成数据读取和检查点写入,确认 GPU 不再长时间等待数据,应用日志没有新的 I/O、只读文件系统或空间错误。
- 对云服务器,将实例内结果与云平台同一时间段的磁盘监控、挂载状态和操作记录核对;对本地 GPU 服务器,则继续检查本地磁盘或 RAID 控制器是否产生新的告警。
建立复发监控点
磁盘异常处理完成后,应持续关注四类指标,而不是只监控容量:
- 文件系统容量使用率和 inode 使用率;
- 挂载状态、只读事件、文件系统错误和块设备 I/O 错误;
- 设备 I/O 延迟、队列长度、读写吞吐和高 I/O 进程;
- 日志目录、检查点目录、缓存目录的增长速度和文件数量。
同时保留故障发生时间、任务名称、挂载点、采样结果和处理动作。这样下一次出现“GPU 利用率下降、任务卡住或保存失败”时,可以快速区分是容量耗尽、inode 耗尽、日志失控、文件系统保护性只读,还是 I/O 延迟升高,而不是反复进行无目标的清理或重启。