MD是用于运行软件RAID阵列的Linux内核驱动程序。Mdadm是您运行以管理MD设备的软件。它们都是同一项目的一部分。
大约从2010年开始,MD就有了坏块日志(BBL)功能。当它无法从底层设备读取时,它将(有时?)。将该数据块标记为坏块,并从不同的设备读取正确的数据,然后永远有更多的重定向读取远离这些坏块。
该功能的一个问题是,除了存储设备的部分永久性故障之外,读取错误可能由于许多原因而发生。例如,可能是背板或控制器故障导致多个设备上出现许多读取错误,或者可以通过某种类型的网络访问这些设备,而临时的网络问题可能会传播错误。
即使设备的特定部分不可读,操作系统也应该尝试在顶部写入正确的数据。此写入将清除问题,或者被驱动器固件重定向到驱动器上的备用扇区。操作系统不应担当此角色,而驱动器应担当此角色,而当驱动器无法执行此任务时,阵列的冗余将会挽救局面。
更糟糕的是,BBL代码中的某个地方显然存在错误,导致在重建阵列或更换设备时将设备的BBL复制到新设备上。显然,一台新设备获取另一台设备的BBL副本是没有意义的,因为它们本质上是针对每个设备的。到目前为止,还没有成功的故意复制这种情况,只有人们在可能最糟糕的时刻不知不觉地击中了它。
如果发现新的坏块,mdadm甚至不会特别努力地警告您。与设备故障不同的是,它不会给你发送电子邮件。MD驱动程序将有关坏块的信息写入系统日志。/proc/mdstat也没有更改。您必须检查sysfs中的一些文件。
有些人希望取消这一功能,认为这是一个在现代毫无意义的坏主意;
有一个RAID维基,它说该功能有优点,但也有必须修复的缺陷;
可能有非常多的mdadm用户没有意见,因为他们对这种情况一无所知。
在过去的10年里,似乎没有人在解决这些问题上取得任何进展。
我现在要说的是,这个故事还没有(还没有?)。有一个令人满意的结局。
我已经意识到“坏区块争议”大约5年了,但我个人从来没有遇到过任何问题,而且它总是排在我要看的清单的底部。Roy最近的帖子促使我决定,将来我创建的MD数组都不会有BBL。
我还利用这个机会部署了Sarah Newman的Ansible角色,该角色检查所有阵列组件是否有空的BBL。BitFolk的数组组件当前在其bbls中没有任何条目-哎呀!
目前,从数组组件中删除BBL的唯一方法是停止该数组,然后使用如下所示的参数对其进行组装:
这样做的一个大问题是,停止阵列显然会导致任何正在使用它的设备停机。如果您的根文件系统在MD阵列上(如果您使用MD,为什么不是这样呢?)。这意味着整个服务器,您必须在某种救援环境中执行此操作。
我已经建议添加一个配置选项来删除程序集上的BBL,这样下次重新启动机器时就会发生这种情况。这似乎没有引起任何兴趣。
如果没有这种帮助,我认为我不会将BBL从我现有的任何阵列中移除-停机时间真的很痛苦,我无法证明花费额外的时间引导到救援环境并手动组装所有阵列是合理的。
所以,如果BBL不能轻易移除,至少可以防止它永远存在,对吗?2016年,当前MD维护者尼尔·布朗(Neil Brown)被问及该功能是否可以默认关闭时,尼尔说,把这一点放到配置文件中就是这样:
问题是,考虑到许多用户对运行mdadm命令的体验:他们不运行mdadm,而是由其他工具为他们运行mdadm,这不如默认禁用它。我甚至可以说,mdadm的大部分使用是由助手脚本和安装程序完成的,而不是由人类完成的。
如果它是一个正在为您运行mdadm的程序,那么在它读取mdadm.conf之前,您必须了解如何设置该mdadm.conf。
以我自己安装Debian的过程为例。我是通过PXE启动Debian安装程序来做到这一点的。我做了一些预置来回答安装程序的许多问题,但实际上我仍然在安装程序的文本界面中执行磁盘分区阶段。
所以我在想,这实际上会很简单,因为Debian安装程序真的很棒,让您可以执行shell并四处查看。当然,我需要做的就是打开一个shell并编辑/etc/mdadm/mdadm.conf,然后返回到mdcfg菜单并继续,对吗?哦,天哪,不是吧。
你可以阅读我的狂野之旅的细节,其中包括我将一个strace的二进制文件上传到d-i中以运行mdadm,以找出发生了什么,但对于那些不愿意这样做的人,本文只提供了相关的发现。
在对为什么我在d-i shell中使用mdadm命令手动创建的数组仍然有BBL感到相当困惑之后,我发现d-i中的mdadm二进制文件被编译为将其配置放在/tmp/mdadm.conf。我不知道为什么,但可能有一个很好的原因。
哦,呵呵,不。每次进入MD配置节(Mdcfg)时,它都会破坏它自己的/tmp/mdadm.conf,如果不返回MD配置节,您就无法进入“执行shell”选项。
如果您使用的是具有多个虚拟控制台的设备(例如,如果您坐在一台传统PC前面),则可以在进入MD配置部分后切换到其中一个,然后修改/tmp/mdadm.conf。我没有那个选项,因为我在串行控制台上。
有一个较早的选项可以加载安装程序组件,使用户可以通过SSH继续安装过程。如果您选择此选项,则可以通过SSH登录到正在运行的安装程序系统,因此,如果您在主控制台中输入MD配置位后执行此操作,那么我猜您可以编辑配置文件并继续。
不过,在这一点上,一切都变得有点复杂了。我试图避免它,但实际上,我建议只从d-i shell手动创建MD阵列。记住它就没那么奇怪了。
如果这是一个简单的例子,其中您刚刚将一个SDA和一个SDB磁盘进行了完全相同的分区,并且您希望在它们上创建一组阵列,那么它可以是一个相当清晰的shell会话,如下所示:
~#mkdir-vp/etc/mdadm&;&;ECHO";为1 2 3 5中的部件创建bbl=no";>;/etc/mdadm/mdadm.conf~#;do\mdadm--create\-v\--config=/etc/mdadm/mdadm.conf\/dev/md${part}\--假定-lean\--level=1\。
~#mkdir-vp/etc/mdadm&;&;echo";create bbl=no";>;/etc/mdadm/mdadm.conf ~#用于%1%2%3%5中的零件;执行\ Mdadm--创建\ -v\ --config=/etc/mdadm/mdadm.conf\ /dev/md${part}\ --假设-干净\ --Level=1\ --RAID-Devices=2\ /dev/sd[ab]${part};\ 干完。
它迭代列表1、2、3、5(我将第4个分区用于其他用途),并从sdaX和sdbX生成名为mdx的数组。强制mdadm二进制文件使用我们的配置文件,该文件禁止创建BBL。
您可以验证任何阵列组件上都不存在BBL,如下所示:
您应该为每个组件获得相同的输出。如果组件确实有BBL,它将输出如下所示:
然后,您可以退出d-i shell并返回到磁盘分区部分。现在您将不需要MD配置部分,但即使您确实进入其中,它也应该会检测到您手动创建的所有阵列。
所有这些都不是很好,但至少暂停Debian安装程序并采取一些手动操作相当容易。我怀疑其他Linux发行版的用户可能没有那么幸运,所以我也认为如果缺省情况下禁用这个有缺陷的特性,或者至少有一种方法可以告诉mdadm删除程序集上的BBL,那将是一个好主意。
事实上,我非常希望能够告诉它删除程序集上的BBL,这样我就可以在所有现有服务器上禁用BBL功能。
实际上,udev在增量汇编模式下从initramfs内部调用mdadm,所以我认为增量汇编代码需要在配置文件中查找此“删除所有bbls”指令,然后在汇编期间执行此操作,就好像在命令行上指定了update=no-bbl一样。