答: 我不断地重新发现,文件系统规划是 Unix 配置中最困难的任务之一。为了回答你的问题,我可以描述我们所做的事情。我们计划了以下设置
- 两块 EIDE 磁盘,每块 2.1GB。
disk partition mount pt. size device 1 1 / 300M /dev/hda1 1 2 swap 64M /dev/hda2 1 3 /home 800M /dev/hda3 1 4 /var 900M /dev/hda4 2 1 /root 300M /dev/hdc1 2 2 swap 64M /dev/hdc2 2 3 /home 800M /dev/hdc3 2 4 /var 900M /dev/hdc4- 每块磁盘都在一个单独的控制器(和扁平电缆)上。理论是,控制器故障和/或扁平电缆故障不会禁用两块磁盘。此外,我们可能会从两个控制器/电缆上的并行操作中获得性能提升。
- 将 Linux 内核安装在根 (
/
) 分区/dev/hda1
上。将此分区标记为可引导。/dev/hdc1
将包含/dev/hda1
的“冷”拷贝。这 *不是* raid 拷贝,只是一个普通的拷贝-拷贝。它在那里只是为了防止第一块磁盘发生故障;我们可以使用救援盘,将/dev/hdc1
标记为可引导,并使用它来继续运行,而无需重新安装系统。你甚至可能想将/dev/hdc1
的内核副本放入 LILO 中,以简化在发生故障时的启动。这里的理论是,在发生严重故障时,我仍然可以启动系统,而无需担心 raid 超级块损坏或其他我不理解的 raid 故障模式和陷阱。/dev/hda3
和/dev/hdc3
将是镜像/dev/md0
。/dev/hda4
和/dev/hdc4
将是镜像/dev/md1
。- 我们选择
/var
和/home
进行镜像,并使用单独的分区,使用以下逻辑使用多个不同分区的想法是,如果,由于某些奇怪的原因,无论是人为错误、电源故障还是操作系统崩溃,损坏都仅限于一个分区。在一个典型案例中,系统正在写入磁盘时电源丢失。这几乎肯定会导致文件系统损坏,这将在下次启动期间由
/
(根分区)将包含相对静态、不变化的数据:在所有实际用途中,它将是只读的,而无需实际标记和挂载为只读。/home
将包含“缓慢”变化的数据。/var
将包含快速变化的数据,包括邮件队列、数据库内容和 Web 服务器日志。fsck
修复。尽管fsck
尽力在进行修复时不会造成额外损坏,但知道任何此类损坏都已限制在一个分区内,这令人感到欣慰。在另一个典型案例中,系统管理员在救援操作期间犯了一个错误,导致数据被擦除或销毁。分区可以帮助限制操作员错误的影响。- 分区的其他合理选择可能是
/usr
或/opt
。实际上,如果我们有更多磁盘,/opt
和/home
是 RAID-5 分区的绝佳选择。警告:不要将/usr
放在 RAID-5 分区中。如果发生严重故障,你可能会发现你无法挂载/usr
,并且你需要它上面的一些工具(例如,网络工具或编译器)。使用 RAID-1,如果发生故障,并且你无法使 RAID 工作,你至少可以挂载两个镜像之一。你无法使用任何其他 RAID 级别(RAID-5、条带化或线性附加)执行此操作。所以,为了完成对这个问题的回答
- 将操作系统安装在磁盘 1,分区 1 上。不要挂载任何其他分区。
- 按照说明安装 RAID。
- 配置
md0
和md1
。- 说服自己,你知道在磁盘故障时该怎么做!现在发现系统管理员的错误,而不是在实际危机期间。进行实验!(我们关闭了磁盘活动期间的电源——这被证明是糟糕但具有启发性的)。
- 执行一些糟糕的挂载/复制/卸载/重命名/重启方案,将
/var
移动到/dev/md1
上。小心地完成,这并不危险。- 享受吧!
mdadd
、mdrun
、等等 命令,和 raidadd
、raidrun
命令之间有什么区别?答: 这些工具的名称在 raidtools 包的 0.5 版本中已更改。md
命名约定在 0.43 和更早版本中使用,而raid
在 0.5 和更新版本中使用。
答: 这确实是一个棘手的问题,因为最新的 raid tools 包需要安装 RAID-1,4,5 内核补丁才能编译。我目前不知道有任何预编译的二进制版本的 raid tools 可用。但是,实验表明,针对内核 2.1.100 编译的 raid-tools 二进制文件,在 2.0.34 下创建 RAID-0/linear 分区时似乎工作正常。一位勇敢的人已经要求了这些,我临时将二进制文件 mdadd、mdcreate 等放在了 http://linas.org/linux/Software-RAID/。你必须从通常的 raid-tools 包中获取 man 页面等。
/
) 吗?为什么我不能直接从 md
磁盘启动 Linux?答: LILO 和 Loadlin 都需要一个非条带化/镜像的分区来从中读取内核镜像。如果你想条带化/镜像根分区 (/
),那么你将需要创建一个非条带化/镜像的分区来保存内核。通常,此分区名为/boot
。然后你可以使用 initial ramdisk 支持 (initrd),或者 Harald Hoyer < HarryH@Royal.Net> 的补丁,这些补丁允许将条带化分区用作根设备。(这些补丁现在是最近 2.1.x 内核的标准部分)可以使用几种方法。Bootable RAID mini-HOWTO 中详细记录了一种方法:ftp://ftp.bizsystems.com/pub/raid/bootable-raid。
或者,使用
mkinitrd
构建 ramdisk 镜像,请参见下文。
Edward Welbon < welbon@bga.com> 写道
- ... 所需要的只是一个脚本来管理启动设置。要将
md
文件系统挂载为根,主要的事情是构建一个初始文件系统镜像,其中包含启动md
所需的模块和 md 工具。我有一个简单的脚本可以做到这一点。
- 对于启动介质,我有一个小的廉价 SCSI 磁盘(170MB,我以 20 美元的价格二手买到)。此磁盘在 AHA1452 上运行,但它也可以是本地 IDE 上的廉价 IDE 磁盘。磁盘不需要很快,因为它主要用于启动。
- 此磁盘有一个小文件系统,其中包含内核和
initrd
的文件系统镜像。初始文件系统镜像只包含足够的材料,让我加载 raid SCSI 设备驱动程序模块并启动将成为根的 raid 分区。然后我执行一个(
echo 0x900 > /proc/sys/kernel/real-root-dev0x900
用于/dev/md0
) 并退出linuxrc
。启动从那里正常进行。
- 我已将大多数支持构建为模块,除了引入
initrd
文件系统的 AHA1452 驱动程序。所以我有一个相当小的内核。该方法非常可靠,自从 2.1.26 之前我就一直在这样做,并且从未遇到过我无法轻易恢复的问题。即使在几次 2.1.4[45] 硬崩溃后,文件系统也幸存下来,没有真正的问题。
- 曾经有一段时间,我分区了 raid 磁盘,以便第一个 raid 磁盘的初始柱面保存内核,第二个 raid 磁盘的初始柱面保存初始文件系统镜像,相反,我将 raid 磁盘的初始柱面作为交换空间,因为它们是最快的柱面(为什么要浪费它们来启动?)。
- 拥有一个专用于启动的廉价设备的好处是它易于启动,并且在必要时也可以用作救援盘。如果你有兴趣,你可以看看构建我的初始 ram 磁盘镜像然后运行
LILO
的脚本。它足够新,可以显示图片。它不是特别漂亮,并且肯定可以为初始 ram 磁盘构建一个更小的文件系统镜像。很容易使其更有效率。但它按原样使用http://www.realtime.net/~welbon/initrd.md.tar.gz
LILO
。如果你有任何改进,请转发一份副本给我。 8-)
答: 是的,但反之则不然。也就是说,你可以将条带放在多个磁盘上,然后在之上构建镜像。但是,条带化不能放在镜像之上。一个简短的技术解释是,线性化和条带化个性使用
ll_rw_blk
例程进行访问。ll_rw_blk
例程映射磁盘设备和扇区,而不是块。块设备可以逐层堆叠;但是,执行原始、低级磁盘访问的设备(例如ll_rw_blk
)不能。
目前(1997 年 11 月),RAID 无法在环回设备上运行,尽管这应该很快就会修复。
答: 目前(1997 年 11 月),对于 RAID-5 阵列,不行。目前,只能对连接驱动器之上的 RAID-1 执行此操作。
答: 存储容量没有差异。磁盘也不能添加到任一阵列以增加容量(有关详细信息,请参见下面的问题)。RAID-1 在读取方面具有性能优势:RAID-1 驱动程序使用分布式读取技术同时从两个扇区读取数据,一个来自每个驱动器,从而使读取性能加倍。
RAID-5 驱动程序虽然包含许多优化,但目前(1997 年 9 月)并未意识到奇偶校验盘实际上是数据盘的镜像副本。因此,它串行化数据读取。
答: 一些 RAID 算法确实可以防止多磁盘故障,但这些算法目前尚未为 Linux 实现。但是,Linux Software RAID 可以通过在一个阵列之上分层一个阵列来防止多磁盘故障。例如,可以使用九个磁盘创建三个 raid-5 阵列。然后,这些三个阵列可以反过来连接在一起,形成一个顶层的 RAID-5 阵列。实际上,这种配置将防止三磁盘故障。请注意,大量的磁盘空间“浪费”在冗余信息上。一般来说,MxN 阵列将使用 M+N-1 个磁盘用于奇偶校验。当 M=N 时,“浪费”的空间量最少。
For an NxN raid-5 array, N=3, 5 out of 9 disks are used for parity (=55%) N=4, 7 out of 16 disks N=5, 9 out of 25 disks ... N=9, 17 out of 81 disks (=~20%)另一种选择是创建一个包含三个磁盘的 RAID-1 阵列。请注意,由于所有三个磁盘都包含相同的数据,因此 2/3 的空间被“浪费”了。
fsck
的东西:如果分区未干净卸载,fsck
会运行并在 90% 以上的时间内自行修复文件系统。既然机器能够使用 ckraid --fix
自行修复它,为什么不使其自动化?答: 可以通过将以下行添加到/etc/rc.d/rc.sysinit
来完成此操作mdadd /dev/md0 /dev/hda1 /dev/hdc1 || { ckraid --fix /etc/raid.usr.conf mdadd /dev/md0 /dev/hda1 /dev/hdc1 }或者mdrun -p1 /dev/md0 if [ $? -gt 0 ] ; then ckraid --fix /etc/raid1.conf mdrun -p1 /dev/md0 fi在介绍更完整和可靠的脚本之前,让我们回顾一下操作理论。Gadi Oxman 写道:在不干净的关机中,Linux 可能处于以下状态之一假设我们正在使用 RAID-1 阵列。在 (2a) 中,可能会发生这种情况:在崩溃之前,少量数据块仅成功写入到某些镜像,因此在下次重启时,镜像将不再包含相同的数据。如果我们忽略镜像差异,raidtools-0.36.3 读取平衡代码可能会选择从任何镜像读取上述数据块,这将导致不一致的行为(例如,
- 当不干净的关机发生时,内存磁盘缓存与 RAID 集同步;没有数据丢失。
- 当崩溃发生时,内存磁盘缓存比 RAID 集内容更新;这会导致文件系统损坏,并可能导致数据丢失。此状态可以进一步分为以下两种状态
- 当不干净的关机发生时,Linux 正在写入数据。
- 当崩溃发生时,Linux 没有写入数据。
e2fsck -n /dev/md0
的输出在每次运行时可能会有所不同)。由于 RAID 不能防止不干净的关机,因此通常没有任何“明显正确”的方法来修复镜像差异和文件系统损坏。
例如,默认情况下,
ckraid --fix
将选择第一个可操作的镜像,并使用其内容更新其他镜像。但是,根据崩溃时的确切时间,另一个镜像上的数据可能更新,我们可能希望使用它作为源镜像,或者可能使用另一种恢复方法。以下脚本提供了一种更健壮的启动序列。特别是,它可以防止在存在不合作的磁盘、控制器或控制器设备驱动程序时长时间重复的
ckraid
。修改它以反映你的配置,并将其复制到rc.raid.init
。然后在根分区已 fsck 并以 rw 方式挂载之后,但在其余分区被 fsck 之前,调用rc.raid.init
。确保当前目录在搜索路径中。mdadd /dev/md0 /dev/hda1 /dev/hdc1 || { rm -f /fastboot # force an fsck to occur ckraid --fix /etc/raid.usr.conf mdadd /dev/md0 /dev/hda1 /dev/hdc1 } # if a crash occurs later in the boot process, # we at least want to leave this md in a clean state. /sbin/mdstop /dev/md0 mdadd /dev/md1 /dev/hda2 /dev/hdc2 || { rm -f /fastboot # force an fsck to occur ckraid --fix /etc/raid.home.conf mdadd /dev/md1 /dev/hda2 /dev/hdc2 } # if a crash occurs later in the boot process, # we at least want to leave this md in a clean state. /sbin/mdstop /dev/md1 mdadd /dev/md0 /dev/hda1 /dev/hdc1 mdrun -p1 /dev/md0 if [ $? -gt 0 ] ; then rm -f /fastboot # force an fsck to occur ckraid --fix /etc/raid.usr.conf mdrun -p1 /dev/md0 fi # if a crash occurs later in the boot process, # we at least want to leave this md in a clean state. /sbin/mdstop /dev/md0 mdadd /dev/md1 /dev/hda2 /dev/hdc2 mdrun -p1 /dev/md1 if [ $? -gt 0 ] ; then rm -f /fastboot # force an fsck to occur ckraid --fix /etc/raid.home.conf mdrun -p1 /dev/md1 fi # if a crash occurs later in the boot process, # we at least want to leave this md in a clean state. /sbin/mdstop /dev/md1 # OK, just blast through the md commands now. If there were # errors, the above checks should have fixed things up. /sbin/mdadd /dev/md0 /dev/hda1 /dev/hdc1 /sbin/mdrun -p1 /dev/md0 /sbin/mdadd /dev/md12 /dev/hda2 /dev/hdc2 /sbin/mdrun -p1 /dev/md1除了上述内容之外,你还需要创建一个rc.raid.halt
,它应该如下所示/sbin/mdstop /dev/md0 /sbin/mdstop /dev/md1务必修改rc.sysinit
和init.d/halt
,以在文件系统在 halt/reboot 之前被卸载的所有位置包含此内容。(请注意,如果fsck
返回错误,rc.sysinit
会卸载并重启。)
答: 使用当前的工具,不行,不容易。特别是,你不能只是将一块磁盘的内容复制到另一块磁盘上,然后将它们配对。这是因为 RAID 驱动程序使用分区末尾的一大块空间来存储超级块。这略微减少了文件系统可用的空间;如果你只是天真地尝试将 RAID-1 安排强加到具有现有文件系统的分区上,raid 超级块将覆盖文件系统的一部分并损坏数据。由于 ext2fs 文件系统将文件随机分散在整个分区中(为了避免碎片),因此很有可能在磁盘满之前,某些文件会落在分区末尾。如果你很聪明,我想你可以计算出 RAID 超级块需要多少空间,并将你的文件系统稍微缩小一点,为稍后添加它留下空间。但是,如果你如此聪明,你也应该能够修改工具来为你自动执行此操作。(这些工具不是很复杂)。
注意:一位细心的读者指出,以下技巧可能有效;我尚未尝试或验证这一点:使用
/dev/null
作为其中一个设备执行mkraid
。然后仅使用单个真实磁盘执行mdadd -r
(不要 mdadd/dev/null
)。mkraid
应该已成功构建 raid 阵列,而 mdadd 步骤只是强制系统在“降级”模式下运行,就像其中一个磁盘发生故障一样。