我有一台服务器,我删除了一个大文件。我们姑且称之为~/tempfile.txt
。不知何故,删除操作没有正常进行,磁盘损坏了——也就是说,du -hs *
没有显示该文件存在。但df -h
显示根分区已满。
事实证明这是一个已知问题,可能是由于正在运行的进程访问了“已删除”的文件而发生的。stackoverflow 上的一个答案建议运行lsof +L1
以获取此类文件的列表。好吧,运行它会产生以下条目:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
none 2241 root txt REG 0,5 8560 0 52453 / (deleted)
有几件奇怪的事情:
- “名称”应该是“~/tempfile.txt”,但事实并非如此。
- inode 编号 - 52453 指向其他文件:
/usr/src/linux-azure-headers-5.0.0-1025/include/uapi/video/sisfb.h
。 - PID 为 2241 的进程不存在。
标准程序是终止访问该文件的 PID,但是,没有这样的过程。
我尝试重新启动,但并没有恢复可用空间(如果有进程正在访问该文件,则应该恢复可用空间)。相反,lsof +L1
再次运行会显示一个条目,但这次 inode 编号和 pid 不同,但“名称”字段相同(/
)。
我现在想运行 fsck。首先直接在试运行模式下运行fsck.ext4 -nvf /dev/sda1
,输出显示存在一些问题:“空闲块计数错误、空闲 inode 计数错误、块位图差异”等。因此,我想让我重新启动系统并以只读模式挂载根分区,然后对其运行 fsck。
好吧,fsck.ext4 -nvf /dev/sda1
显示没有任何问题!所以我尝试运行lsof +L1
,结果出乎意料。没有幽灵文件!现在磁盘空间释放了吗?df -h
——磁盘使用率仍为 100%。
我尝试使用根分区的 rw-mount 重新启动,但fsck
再次lsof +L1
出现错误。
这种情况肯定会持续发生 - 只读模式没有显示错误,而读写挂载显示磁盘错误。
我不知道发生了什么。有人能合理猜测一下问题出在哪里吗?
我已经备份了数据,所以我可以用数据启动另一台服务器,但这非常奇怪,我想了解发生了什么。
答案1
对磁盘进行映像处理以获得可供使用的副本。
浏览树顶部的磁盘使用情况,以确认大部分存储空间的使用情况。(如果问题文件无法通过 dentry 枚举,则不会。)ncdu
是一个可视化树的空间利用率的程序。
在读写和卸载时对块设备进行 fsck(并保存输出)。这听起来像是一个 rootfs,在这种情况下,请考虑将磁盘连接到不同的实例并在那里进行 fsck。否则,将早期启动环境配置为始终进行 fsck,然后重新启动。如何执行此操作取决于发行版,例如 systemd 对早期 fsck 的执行方式与以前的 init 脚本不同。无论哪种方式,请检查可能在 中获得引用的孤立 inode 之类的东西lost+found
。
lsof
如果文件当时未打开,则用途有限。您可能看到不相关的打开的未链接文件。
有了备份,恢复或新建实例即可快速恢复。您想调查到什么程度取决于您的好奇心,以及这是否是可能再次发生的问题。