我有一个磁盘在 RAID1 btrfs 中出现故障,因此写入不确定,但读取大部分工作。如何更换?

der*_*ert 6 linux hard-disk btrfs

我有一个双磁盘 btrfs 文件系统,数据和元数据都在 RAID1 中(通过 btrfs 功能,而不是 mdraid)。磁盘是 USB3 驱动器,顶部带有 dm-crypt。其中一个磁盘出现故障(它有数千个坏扇区,并且写入经常超时)。我已经获得了第三个 U 盘来更换出现故障的 U 盘,我该如何更换它?

der*_*ert 11

事实证明这是皇家皮塔饼。首先,重要的是要注意 btrfs 现在有一个适当的替换命令,这比添加新的、删除失败的要好得多。

首先,首先对新磁盘进行分区并在其上设置 dm-crypt。继续并解锁它。

如果您的磁盘没有写入超时(显然每个需要 360 秒!),您可以执行一个简单的操作:

btrfs replace start -r /dev/mapper/luks-BAD-disk-uuid              \
                       /dev/mapper/luks-NEW-disk-uuid /mount/path
Run Code Online (Sandbox Code Playgroud)

然而,这将导致对坏磁盘进行一些例行写入,如果这些会导致超时——您将看到大约 30 秒的快速复制,然后是 6-12 分钟的空闲等待超时。

为了避免写入,可以使用 device-mapper 设置快照。读取将转到底层坏设备(读取基本没问题);写入将进入写时复制 (COW) 存储。首先,您需要一个适当大的块设备用于 COW 存储。我为它创建了一个新的逻辑卷 ( Watt-sdj1_dmsnap)。任何块设备都应该可以工作——即使是循环设备也应该没问题。我个人建议使用持久的,以防万一出现问题,但如果您生活在危险之中并且有足够的 RAM,RAM 磁盘就可以工作。

我的需要大约 1.7GB 的 COW 空间(从 3TB 驱动器上移出 2.24 TiB)。我建议对 COW 空间慷慨;用完可能是一件坏事,一旦完成,您就可以将其全部释放。

接下来,您需要卸载 btrfs 文件系统(如果它已挂载),并锁定(停止)dm-crypt 设备。我将快照放在加密下方,因为我不想将未加密的数据写入磁盘。

就我而言,分区是/dev/sdj1. 首先,为避免任何错误,请将其设置为只读:

blockdev --setro /dev/sdj1
blockdev --setro /dev/sdj
Run Code Online (Sandbox Code Playgroud)

(您可以稍后使用 将其重新设置--setrw)。现在,实际设置快照:

dmsetup create sdj_divert --table "0 $(blockdev --getsz /dev/sdj1) snapshot /dev/sdj1 /dev/mapper/Watt-sdj1_dmsnap PO 8"
Run Code Online (Sandbox Code Playgroud)

为了快速解释这意味着什么,设备映射表具有以下格式:start-sector number-of-sectors target-type target-arguments。起始扇区为0;扇区数与sdj1的大小相同(毕竟我们要完成整个事情);目标类型是快照。快照目标有几个参数:source-dev cow-dev mode chunk-size。我们提供了一个源设备/dev/sdj1;COW 设备是我创建的逻辑卷;模式PO手段p ersistent(元数据写入到磁盘上,所以它可以在重新启动后进行设置备份)和överflow(如果我们向快照写入大量内容,则可以恢复)。块大小是快照的粒度;如果我们写入一个字节,则该字节周围的整个块都将被复制(并消耗快照中的空间)。8 是 4K,所以不会有对齐问题。

现在,最后,再次解锁设备——但不是解锁/dev/sdj1,而是解锁/dev/mapper/sdj_divert。然后继续并再次挂载 btrfs 文件系统。

您可以使用以下命令检查快照使用情况dmsetup status sdj_divert;这应该给出类似的东西(但斜线前的数字要低得多):

0 5860524928 snapshot 914216/545259520 3568
Run Code Online (Sandbox Code Playgroud)

前三项是起始扇区、扇区数和目标类型。下一个数字是使用的扇区数(斜线之前),然后是扇区总数(斜线之后)。所以这是所用空间的一小部分。最后一个数字是用于元数据的扇区数,它已经包含在使用的数字中。

现在,您终于可以使用btrfs replace start答案顶部的那个简单命令了。那将立即返回;通过运行查看状态btrfs replace status /mount/path

替换完成后,确认坏设备已从文件系统中删除(例如,btrfs fi show /mount/path),然后您可以锁定/关闭故障驱动器,然后删除快照(dmsetup remove sdj_divert)。然后你可以释放 COW 空间(如果你是偏执狂,擦掉它之后)。

最后还有一个技术上可选的步骤:我的替换设备更大,但 btrfs 尚未使用额外的空间。为了使其可用于 btrfs,请在btrfs fi show输出中查找 devid ,然后运行

btrfs fi resize DEVID:max /mount/path
Run Code Online (Sandbox Code Playgroud)

这应该几乎是即时的。