我遇到了一个问题:在安装了一些软件包后,我的 openSUSE Tumbleweed 机器上的更新失败,并声称 /var 是只读文件系统。
我已恢复到早期的快照,测试 /var 不是只读的,重新运行更新,在出现一些错误消息后,它又恢复为只读。
这问题让我检查了启动消息,难道你不知道 BTRFS 有问题吗:
[ 231.762975] BTRFS info (device sda2): scrub: started on devid 1
[ 287.021834] BTRFS error (device sda2): parent transid verify failed on 31572885504 wanted 278272 found 278280
[ 287.060064] BTRFS info (device sda2): scrub: not finished on devid 1 with status: -5
[ 643.134491] BTRFS info (device sda2): qgroup scan completed (inconsistency flag cleared)
[ 971.347644] BTRFS info (device sda2): scrub: started on devid 1
[ 1026.335159] BTRFS error (device sda2): parent transid verify failed on 31572885504 wanted 278272 found 278280
[ 1026.374518] BTRFS info (device sda2): scrub: not finished on devid 1 with status: -5
最后 3 行再次重复。切换到较早的快照似乎不会产生任何影响,因此这可能不是文件系统内容最近发生的某些更改,可能已被中途中断。它要么已经存在了一段时间,要么是不同的东西。
我尝试清理,但这会中止进程一分钟(大约 14 GiB),并出现 I/O 错误:
> sudo btrfs scrub start -B /dev/sda2
ERROR: scrubbing /dev/sda2 failed for device id 1: ret=-1, errno=5 (Input/output error)
scrub canceled for 8b283f24-277b-4cf8-8d87-6107bca1ef57
Scrub started: Wed Jul 15 14:20:22 2020
Status: aborted
Duration: 0:00:55
Total to scrub: 60.00GiB
Rate: 183.09MiB/s
Error summary: no errors found
那么,没有发现错误,但由于 I/O 错误而中止?看起来好像有曾是毕竟是一个错误。
我确实测试了驱动器的 SMART 状态,据我所知,它似乎完全没问题。该驱动器的使用寿命约为 2700 小时,因此我预计它也不会出现太多磨损。
我又搜索了一些并发现这建议从备份中替换磁盘的内容。由于这是我的主系统分区,因此我根本不希望将整个分区安装完毕。我确实有最近的部分克隆备份,但也有错误(可能已经存在了一段时间)。另外:我的系统工作正常,除非我尝试更新某些内容,所以也许可以通过某种方式挽救它?
仅检查 csum 错误:
> sudo btrfs check --check-data-csum /dev/sda2
Opening filesystem to check...
WARNING: filesystem mounted, continuing because of --force
Checking filesystem on /dev/sda2
UUID: 8b283f24-277b-4cf8-8d87-6107bca1ef57
[1/7] checking root items
[2/7] checking extents
parent transid verify failed on 31572885504 wanted 278272 found 278280
parent transid verify failed on 31572885504 wanted 278272 found 278280
Ignoring transid failure
[3/7] checking free space cache
[4/7] checking fs roots
parent transid verify failed on 31572885504 wanted 278272 found 278280
Ignoring transid failure
parent transid verify failed on 31572885504 wanted 278272 found 278280
Ignoring transid failure
parent transid verify failed on 31572885504 wanted 278272 found 278280
Ignoring transid failure
root 259 inode 4735696 errors 800, odd csum item
root 259 inode 4746779 errors 800, odd csum item
root 259 inode 4747724 errors 800, odd csum item
parent transid verify failed on 31572885504 wanted 278272 found 278280
Ignoring transid failure
[... lots of repetitions of the previous two lines ...]
Ignoring transid failure
ERROR: errors found in fs roots
found 49867616256 bytes used, error(s) found
total csum bytes: 38229736
total tree bytes: 1010974720
total fs tree bytes: 895434752
total extent tree bytes: 57819136
btree space waste bytes: 215524051
file data blocks allocated: 869778038784
referenced 68509286400
Soo ...这是否意味着只有一个块受到校验和问题的影响?这是否意味着它只是一个文件?或者“fs root 中发现错误”行是否表明文件系统存在更多问题?
我见过这建议使用零日志,但该命令似乎既不存在于我的系统上,也不存在于我用来在卸载时检查磁盘的 Manjaro Live 系统上,su 我认为不再需要/支持?无论如何,维基百科说只要文件系统能挂载,零日志就没啥用,我的也能挂载。然而,它也说不使用 btrfs 检查除非一切都失败,否则进行维修。
对我来说,似乎所有其他方法确实都失败了,但是我不确定我是否忽略了处理该问题的其他方法,甚至可能找出最初出了什么问题。
那么,是否值得尝试通过btrfs check --init-csum-tree
(或btrfs check --repair
?)来修复此问题,或者是否有更智能的方法来修复此问题而无需重新安装系统?也许可以查明哪些文件受到影响并检查它们是否可以修复或重新生成?
答案1
我确实运行了我能找到的任何其他分析方法来尝试找出哪些文件受到 transid 故障的影响,但并没有真正走得太远。因此,我使用btrfs restore
、 和从实时启动的系统运行btrfs check --repair
和,对仍然可读的所有内容进行了备份。btrfs check --init-csum-tree
这消除了错误报告,但留下了很少的空间指示为空闲。因此,我跟进了brfs balance
良好的措施(必须运行几次,第一次仅限于几乎空的块(usage=10
),因为可用空间很少。经过几次擦洗和平衡后,驱动器似乎再次正常工作,但有些文件已损坏/丢失。我卸载/重新安装了一些不再起作用的受影响的软件包,运行了完整的系统更新,一切又恢复正常了。
为了减少此类错误再次发生(并且不被注意到)的可能性,我现在在 openSUSE 中设置了一项服务来定期清理和平衡磁盘。从那时起运行良好。我真的希望这种卫生措施是 BTRFS 的一部分:擦洗每 X 次写入,在重新分配 Y% 的块后进行平衡……如果出现问题,则提出标志。或者至少默认提供 BTRFS 的发行版应该预先配置一些类似的内容,因为任何使用 BTRFS 的人都需要进行清理和平衡。