使用 dd 在 XFS 文件系统中截断文件 - 如何恢复
Truncated file in XFS filesystem using dd - how to recover
磁盘布局
我的 HDD raid 阵列快要报废了,我为此买了一些新磁盘。
我曾将旧硬盘用作 kvm/qemu 虚拟机的原始磁盘映像存储。
Raid 阵列是使用 mdadm 构建的。在 md 设备上,我有 LVM 的物理卷。在物理卷上,我有存储原始磁盘映像的 XFS 文件系统。
每个原始磁盘映像都是由 qemu-img 制作的,并包含 LVM 的物理卷。一个 PV = 一个 LV = 一个原始磁盘映像中的 VG。
动作
当我尝试使用 cp 进行数据移动时,我在我的 raid 阵列中遇到了坏块和 i/o 问题,所以我从 cp 切换到 dd with noerror,sync flags
我写了dd if=/mnt/old/file.img of=/mnt/**old**/file.img bs=4k conv=noerror,sync
问题
现在文件 /mnt/old/file.img 在 XFS 文件系统中的大小为零。
有没有简单的解决方案来恢复它?
我的感觉是您的 RAID 阵列出现故障。您可以通过...查看 RAID 状态...
cat /proc/mdstat
由于您看到 i/o 个错误,这很可能是您问题的根源。前进的最佳途径是制作每个 RAID 成员的扇区级副本(或至少是抛出 i/o 错误的成员)。参见 Linux ddrescue。它旨在复制故障硬盘。然后从副本执行恢复工作。
终于找到解决办法了,但是不是很简单
Xfs_undelete 没有匹配我的问题,因为它不支持非常大的文件的 B+Tree 扩展存储格式 (V3)。
成功 semi-manual 解决我的问题的过程包括以下主要步骤:
- 立即卸载文件系统并使用 dd 对文件进行完整分区备份
- 调查有关截断文件的 XFS 日志条目
- 在专家模式下使用 xfs_db 手动还原 inode 核心 header
MB。恢复 inode 核心不会取消标记为 non-free,并且当您尝试以通常方式从具有已恢复 inode header 的文件中复制一些数据时,您将收到 i/o 错误。
这是开发 python 脚本的原因。
- 使用脚本从 B+Tree 树中提取 extents 数据作为 inode 并将它们写入磁盘
我已根据 LGPL 许可在 GitHub
发布了恢复脚本
P.S。由于损坏的 inode b+tree extent 记录,一些数据丢失了,但它们对我来说没有意义。
磁盘布局 我的 HDD raid 阵列快要报废了,我为此买了一些新磁盘。 我曾将旧硬盘用作 kvm/qemu 虚拟机的原始磁盘映像存储。 Raid 阵列是使用 mdadm 构建的。在 md 设备上,我有 LVM 的物理卷。在物理卷上,我有存储原始磁盘映像的 XFS 文件系统。 每个原始磁盘映像都是由 qemu-img 制作的,并包含 LVM 的物理卷。一个 PV = 一个 LV = 一个原始磁盘映像中的 VG。
动作
当我尝试使用 cp 进行数据移动时,我在我的 raid 阵列中遇到了坏块和 i/o 问题,所以我从 cp 切换到 dd with noerror,sync flags
我写了dd if=/mnt/old/file.img of=/mnt/**old**/file.img bs=4k conv=noerror,sync
问题 现在文件 /mnt/old/file.img 在 XFS 文件系统中的大小为零。 有没有简单的解决方案来恢复它?
我的感觉是您的 RAID 阵列出现故障。您可以通过...查看 RAID 状态...
cat /proc/mdstat
由于您看到 i/o 个错误,这很可能是您问题的根源。前进的最佳途径是制作每个 RAID 成员的扇区级副本(或至少是抛出 i/o 错误的成员)。参见 Linux ddrescue。它旨在复制故障硬盘。然后从副本执行恢复工作。
终于找到解决办法了,但是不是很简单
Xfs_undelete 没有匹配我的问题,因为它不支持非常大的文件的 B+Tree 扩展存储格式 (V3)。
成功 semi-manual 解决我的问题的过程包括以下主要步骤:
- 立即卸载文件系统并使用 dd 对文件进行完整分区备份
- 调查有关截断文件的 XFS 日志条目
- 在专家模式下使用 xfs_db 手动还原 inode 核心 header MB。恢复 inode 核心不会取消标记为 non-free,并且当您尝试以通常方式从具有已恢复 inode header 的文件中复制一些数据时,您将收到 i/o 错误。 这是开发 python 脚本的原因。
- 使用脚本从 B+Tree 树中提取 extents 数据作为 inode 并将它们写入磁盘
我已根据 LGPL 许可在 GitHub
发布了恢复脚本P.S。由于损坏的 inode b+tree extent 记录,一些数据丢失了,但它们对我来说没有意义。