Linux BTRFS - 转换为带有故障驱动器的单个

eee*_*eta 14 linux raid btrfs

少量背景故事:

我有一个小型媒体文件系统,我在上面存储了用于我的 HTPC 设置的各种电影和电视节目。这最初是btrfs在 1TB WD 外置驱动器上使用 设置的。

后来,我决定购买另一个驱动器,赋予这个文件系统 RAID1 镜像功能。该硬盘是 Seagate Barracuda(2TB,BARRACUDA 7200.14 FAMILY)。不幸的是,这不是一个好的驱动器选择。驱动器很快就开始出现大量读取错误,尽管 BTRFS 能够纠正它们。

最近,该驱动器的读取错误数量激增,其状况不断恶化。BTRFS 现在开始崩溃:

kernel: RSP: 0018:ffff88005f0e7cc0  EFLAGS: 00010282
kernel: RIP: 0010:[<ffffffffa0081736>]  [<ffffffffa0081736>] btrfs_check_repairable+0xf6/0x100 [btrfs]
kernel: task: ffff88001b5c4740 ti: ffff88005f0e4000 task.ti: ffff88005f0e4000
kernel: Workqueue: btrfs-endio btrfs_endio_helper [btrfs]
kernel: CPU: 1 PID: 3136 Comm: kworker/u8:3 Tainted: G           O    4.5.3-1-ARCH #1
kernel: invalid opcode: 0000 [#1] PREEMPT SMP 
kernel: kernel BUG at fs/btrfs/extent_io.c:2309!
kernel: ------------[ cut here ]------------
kernel: BTRFS info (device sdc1): csum failed ino 73072 extent 1531717287936 csum 3335082470 wanted 3200325796 mirror 0
kernel: ata3: EH complete
kernel: BTRFS error (device sdc1): bdev /dev/sda3 errs: wr 0, rd 18, flush 0, corrupt 0, gen 0
kernel: blk_update_request: I/O error, dev sda, sector 2991635296
Run Code Online (Sandbox Code Playgroud)

我想从 RAID1 阵列中移除故障驱动器,在单个驱动器上恢复无冗余。不幸的是,似乎缺乏有关如何执行此操作的文档。

我知道可以运行以下命令:

sudo btrfs balance start -dconvert=single /media
Run Code Online (Sandbox Code Playgroud)

将数据配置文件转换为single模式,但我不确定数据将放置在哪里。由于其中一个驱动器出现故障,我希望能够确保 BTRFS 不会尽职尽责地擦除好驱动器上的所有数据,并在坏驱动器上放置一个副本 - 相反,我想简单地表现得好像另一个驱动器从未存在过(例如,转换回我的旧设置)

这不起作用:

$ sudo btrfs device delete /dev/sda3 /media
ERROR: error removing device '/dev/sda3': unable to go below two devices on raid1
Run Code Online (Sandbox Code Playgroud)

我是什么做的?帮助将不胜感激。

TL;DR:从 BTRFS 中的 1 个驱动器开始single,添加了另一个驱动器,成功了RAID1,另一个驱动器现在出错了,我如何返回到一个驱动器(特别是已知好的驱动器)single

eee*_*eta 13

好的,我在这个 Trello 链接的帮助下想通了。如果其他人想这样做,这里是程序。

程序

来自两个磁盘的 RAID1 阵列,一个/dev/sda有故障,另一个/dev/sdc已知良好:

  1. 在 中禁用此阵列的自动挂载/etc/fstab重新启动。基本上,我们希望 btrfs 忘记这个数组的存在,因为有一个错误,如果它被拔掉,它仍然会尝试使用其中一个驱动器。
  2. 现在您的阵列已卸载,请执行:

    echo 1 | sudo tee /sys/block/sda/device/delete

    替换sda为错误的设备名称。这会导致磁盘转速下降(您应该在 dmesg 中验证这一点)并且内核无法访问。

    或者:只需在启动前将驱动器从计算机中取出即可!我选择不选择这种方法,因为上述方法对我来说很好用。

  3. 使用-o degraded模式挂载您的阵列。
  4. 使用 开始重新平衡操作sudo btrfs balance start -f -mconvert=single -dconvert=single /mountpoint。这将重新组织已知良好驱动器上的范围,将它们转换为single(非 RAID)。这将需要将近一天的时间才能完成,具体取决于驱动器的速度和阵列的大小。(我的有 ~700 GiB,并以每分钟 1 1GiB 块的速度重新平衡)幸运的是,此操作可以暂停,并在它发生时保持阵列在线。
  5. 完成此操作后,您可以发出sudo btrfs device remove missing /mountpoint删除“丢失”的故障设备的命令。
  6. 开始第二次重新平衡sudo btrfs balance start -mconvert=dup /mountpoint以恢复元数据冗余。这在我的系统上需要几分钟。
  7. 你完成了!您的阵列现在single处于模式,已删除所有冗余。
  8. 把你有故障的驱动器带到外面,用锤子敲打它。

故障排除

  • 求助,btrfs 试图写入我的故障磁盘,出错了,并强制它只读!
    • 您是否按照步骤 1 操作并在继续之前重新启动?btrfs 可能仍然认为您降速的驱动器存在。重新启动将导致 btrfs 忘记任何错误,并让您继续。

  • 这不起作用。我在 Ubuntu 16.04(内核 4.4)上。dmesg 说“缺少设备(1)超过限制(0),不允许可写安装”。因此,我被困在“mount -o 降级”步骤 (2认同)

小智 11

谢谢你的帖子。我有一个想法,我可以测试 raid,将驱动器从我的热插拔托架中弹出,使用另一个驱动器,然后将 raid 驱动器弹回。回想起来,这是一个坏主意,现在我需要我的热插拔托架。

这是我发现的。作为根:

# sudo btrfs fi show
Label: 'disk'  uuid: 12817aeb-d303-4815-8bba-a3440e36c62c
Total devices 2 FS bytes used 803.10GiB
    devid    1 size 931.51GiB used 805.03GiB path /dev/sda1
    devid    2 size 931.51GiB used 805.03GiB path /dev/sdb1
Run Code Online (Sandbox Code Playgroud)

请注意为每个驱动器列出的设备。brtrfs balance 的男人让我找到了 devid 选项,尝试了几次来弄清楚过滤器是如何工作的(最初尝试 devid=/dev/sdb1)。所以你的第一次尝试看起来像这样。

# btrfs balance start -dconvert=single,devid=2 -mconvert=single,devid=2 /mnt
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误。

ERROR: error during balancing '/media/.media': Invalid argument
There may be more info in syslog - try dmesg | tail    
Run Code Online (Sandbox Code Playgroud)

这是来自 dmesg 的错误:

BTRFS error (device sdb1): balance will reduce metadata integrity, use force if you want this
Run Code Online (Sandbox Code Playgroud)

所以这是最后的工作:

# btrfs balance start -f -dconvert=single,devid=2 -mconvert=single,devid=2 /mnt
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助其他人。