记录一次强制断电引起的podman后端btrfs数据腐败的修复过程

错误背景

偶然登陆家庭服务器的IPKVM才发现tty被dmesg的BTRFS警报充满了屏幕。大致内容格式如下:

1
2
[  245.480592] BTRFS warning (device sda2): csum failed root xxx ino xxx off xxxxx csum 0x683886ee expected csum 0xdb139986 mirror 1
[  245.480598] BTRFS error (device sda2): bdev /dev/sda2 errs: wr 0, rd 0, flush 0, corrupt 114514, gen 0

而且corrupt(腐败)的数据每秒递增。 回想起之前因为e1000e的网卡驱动炸内核炸了几次让我不得不冷重启整台服务器,这可能导致了一些还在IO的文件导致了错误。

腐败文件定位

btrfs提供了工具可以无需停机进入livecd即可扫描腐败文件 sudo btrfs scrub /dev/sda2

大致输出结果如下 BTRFS warning (device sda2): checksum error at logical 1082287063040 on dev /dev/sda2, physical 237260636160, root 25744, inode 6574, offset 24576, length 4096, links 1 (path: opt/couchdb/lib/stdlib-4.3.1.6/ebin/escript.beam)

通过btrfs scrub扫描出来的腐败文件结果拥有更详细的文件路径以及位置信息,这里我们只需要关注root 25744(subvol的id)与path: opt/couchdb/lib/stdlib-4.3.1.6/ebin/escript.beam()这两个信息。

由于couchdb我并不是通过包管理器安装的而是通过podman部署的,又由于我的podman的存储后端是btrfs subvol,那么我已经大概明白路径在哪里了。

腐败文件清理

我的podman并没有为couchdb创建volumes进行持久化存储,那么应该image的subvol出现了问题。通过sudo btrfs subvol list / | grep 25744验证猜想正确。

那么问题就很好解决了。关闭并且删除当前couchdb容器,通过sudo podman system prune --volumes清理无用image以及无用volumes。

再度运行sudo btrfs subvol list / | grep 25744,检查出错subvol是否已经被删除。

清理结束后,重新运行podman容器,重新拉取image。检查dmesg输出,发现不再弹出腐败报错。问题解决。

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计