一次惊险的群晖阵列数据修复实践
一、缘起
最近天气热起来了,看到柜子里的群晖nas硬盘温度又上来了,一度达到50+度不太健康,于是就折腾把柜子内的设备布局、nas机箱底部垫的消音棉去除掉,提升点散热效果。
结果一通折腾(内部各种设备线、网线较多,调整起来 非常的麻烦),发现对散热效果不大,因为这个nas的机箱底部是没有进风口的设计,进风都是从前置的硬盘托架缝隙进来的;另外由于去除了消音棉,加上氦气盘的噪音,比之前大了很多。
鉴于此就又折腾了一遍把消音棉又加回去了。。。。
结果问题就来了,重新插线开机后,群晖里的存储池子挂了2个,一个raid1的存储池损毁(显示1个硬盘掉了),另一个单盘的basic的存储池硬盘直接掉了不显示了,可能是来回折腾硬盘架松了,也可能是我清灰了2个硬盘出问题了。。
因此就有了这次的惊险的数据恢复过程,这里记录一下备忘(详细命令过程在本地仓库了)。
二、操作过程
修复raid1存储池
在群晖的存储管理里,群晖对raid阵列的要求较高,比如 上面出问题的案例里,硬盘本身没有问题,发现掉了raid1的一个硬盘后,关机重插硬盘,开机后硬盘识别出来了,但是raid里没有自动的把这个磁盘加进去,理论上这时候的数据还没有存在写入等导致的不同步问题,直接把硬盘加进去然后同步一下就行了。
但这里群里存储管理里显示阵列损毁,界面上倒是比较方便,点一个修复阵列,然后把新识别出来的硬盘加入进去,然后存储池同步完成就行了;这个过程很慢,是全盘的同步,其实风险挺高的,如果这时候剩下的1个盘挂了,那就会导致raid1阵列数据丢失或损坏了。。。
好在这个过程比较顺利,经过漫长的等待后阵列正常恢复了。
修复basic不带raid的单盘存储池
另一个单盘的basic的存储池子就没这么幸运可以界面上点击修复了,重插硬盘启动后,硬盘直接显示未初始化,存储池和共享文件夹里都没有正常挂载。
这时候在存储空间管理->概览页面,有提示硬盘没有安装系统,可以点击修复,这里我点击了一下,结果显示完成,但是存储池没有回来
然后就重新启动了机器,这时候存储池出来了,但显示损毁,对应的存储池和共享文件夹都没有出来;由于是单盘,没有修复阵列的选项了,这里就卡住了,引出了下面手动操作mdadm阵列管理的惊险操作。。。
mdamd操作过程
1、参考https://v2ex.com/t/804212里帖子介绍,使用了下面命令,把系统分区加入到群晖系统raid1阵列里。
注意这里损坏的这个阵列对应的硬盘分区一定提前通过命令确认下,比如这里我的是/dev/sdd硬盘,否则会有致命的问题
sudo mdadm -a /dev/md0 /dev/sdd1 sudo mdadm -a /dev/md1 /dev/sdd2
上面2个命令执行后相当于手动的修复了系统分区的问题,阵列应该不会显示未初始化或有问题了,命令执行后madam阵列管理会自动同步raid1的数据。
2、数据分区损毁问题修正
经过上面的过程,系统分区修复完成,重启机器后,发现存储池依然显示损毁,提示尽快备份数据,同时呢数据分区的共享文件夹正常的显示出来了。
也就是到这里如果担心风险,可以先对共享文件夹进行备份,防止后续误操作导致数据彻底丢失。
这里的存储池依然显示损毁,依然是群晖或者madam比较高的要求导致,因为这块硬盘中途出现过掉盘的问题(从系统日志看到硬盘有连接上,掉盘,后来又连接上的日志),系统就标注这个阵列损毁了。
具体的使用cat /proc/mdstat可以看到对应的阵列后有个E标志,类似:
md5 : active raid1 sdd3[0](E) xxx blocks super 1.2 [1/1] [E]
接下来根据https://zhuanlan.zhihu.com/p/672190639介绍的教程修复数据分区问题。
设想的操作:
针对/dev/md5 的软 RAID 阵列异常。这是一个单盘 RAID1 阵列(-n1 -l1),唯一的成员盘是 /dev/sdd3。由于该阵列承载着重要数据,我决定使用 mdadm 对其进行重建修复,并保留了原来的 UUID:c6f31365:5ac5dfcf:55b3171a:01f1990b。
这里原有阵列的uuid可以通过如下命令获取(之所以要获取并在后续创建过程使用,是为了保持和以前一样,这样群晖系统各类共享文件夹、存储池直接就能回来):
sudo mdadm -D /dev/md5
计划很简单:停止旧阵列,然后用 mdadm -Cf 强制创建一个同 UUID 的新阵列,把 /dev/sdd3 重新纳入。然而,就是这个看似简单的操作,因为设备名的一字之差,引发了一场令人后怕的虚惊——我把本该在 /dev/md5 上执行的命令,误敲成了 /dev/md3。
下面是实际操作过程,包含误操作过程,其他人如参考,建议直接参照正确过程,核心就是先获取阵列信息,包括硬盘和uuid,然后停止,然后重新创建。
2.2.1 误操作:差点毁了 md3
整个误操作链条如下:
步骤〇:停止所有的群晖空间
sudo synospace --stop-all-spaces
步骤一:停止现有阵列
我首先执行了:
sudo mdadm -Sf /dev/md3
这行命令强制停止了当时正在运行的 /dev/md3 阵列(其原始成员盘为 /dev/sda1)。
步骤二:错误创建新阵列
紧接着,本该针对 /dev/md5 的命令,被我打成了:
mdadm -Cf /dev/md3 -e1.2 -n1 -l1 /dev/sdd3 -u c6f31365:5ac5dfcf:55b3171a:01f1990b
这一操作在内核中创建了一个全新的 /dev/md3 设备,并将 /dev/sdd3 作为其成员盘,同时写入了带有指定 UUID 的 RAID 超级块(Superblock)。
步骤三:发现错误并补救
命令执行后,我猛然意识到搞错了目标——这本来是给 md5 准备的。于是火速执行:
sudo mdadm -Sf /dev/md3
再次停止了这个错误创建的阵列。此时,系统中有两块盘留下了 RAID 元数据印记:
/dev/sda1:保留着原始md3的超级块(未被触碰)/dev/sdd3:被写入了新超级块,UUID 与原来的md5相同
2.2.2 纠正操作:修复真正的 md5
在清理完误操作后,我使用正确的设备名重新执行了创建命令:
mdadm -Cf /dev/md5 -e1.2 -n1 -l1 /dev/sdd3 -u c6f31365:5ac5dfcf:55b3171a:01f1990b
这一次,设备名正确指向了 /dev/md5,成员盘 /dev/sdd3 上的超级块被再次重写(内容与上一步误操作写入的基本一致),一个新的 /dev/md5 阵列在内核中建立起来。
经过这里的操作,md5看起来在/proc/mdstat中显示正常了,但是md3由于被错误的停止了,就丢失了,因此想办法怎么恢复。
问了大模型使用scan命令后, 居然发现扫描到了老的md3。。
2.2.3 意外发现:md3 竟然还在
为了确认系统状态,我执行了:
sudo mdadm --assemble --scan
扫描结果令人惊讶——/dev/md3 依然存在,而且看状态是正常的。这让我陷入困惑:明明刚才在 md3 上做了创建又停止的操作,为什么它还能被扫描到?会不会已经被破坏了?
2.2.4 重启所有的群辉空间
sudo synospace --start-all-spaces
2.2.5 原理解释:为什么数据完好无损
经过仔细分析,谜团解开,核心原因有两点:
(1)md3 为什么没被破坏?
mdadm --assemble --scan 的工作原理是扫描所有磁盘头部,寻找合法的 RAID 超级块,然后尝试组装。误操作中,mdadm -Cf /dev/md3 ... /dev/sdd3 只是往 /dev/sdd3 写入了新的超级块,并没有触碰 /dev/sda1 上的原始数据。而 /dev/sda1 才是 md3 的真正成员盘,它上面的超级块一直完好无损。当执行 --assemble --scan时,mdadm 扫描到了 /dev/sda1 上的旧超级块,于是顺利地将原始 md3 重新组装了回来。之前所有的误操作,对 md3 来说不过是内核层面的“创建-销毁”,磁盘上的真实数据纹丝未动。
(2)md5 的数据是否安全?
这是一个更关键的问题。通常来说,mdadm -C(Create)是为新建空阵列设计的,如果用在已有数据的磁盘上,在多盘 RAID 场景下可能触发同步,导致数据被覆盖。但这里的幸运之处在于:/dev/md5 是单盘 RAID1(-n1 -l1)。
对于单盘 RAID1,mdadm -C 的行为仅仅是:
在成员盘头部写入新的超级块
不初始化数据区,不触发同步
也就是说,它只是给 /dev/sdd3 戴上了一顶新的“RAID 帽子”,底下的文件系统数据原封不动。再加上强制指定了与原阵列相同的 UUID,系统完全有理由认为这就是原来的那个阵列。后续通过只读挂载验证,文件系统完好,数据全部可见,虚惊一场。
(3)-C 与 -A 的本质区别
这次经历也深刻印证了一个知识点:
| 命令 | 用途 | 对数据的影响 |
|---|---|---|
mdadm -C (Create) | 创建全新阵列 | 初始化超级块,多盘时可能触发同步覆盖数据 |
mdadm -A (Assemble) | 组装已有阵列 | 仅读取超级块并组装,绝不修改数据 |
修复已有阵列时,永远应该使用 --assemble 而非 --create。本次之所以侥幸成功,纯粹是因为单盘 RAID1 的特殊性。
总结
手动修复过程的madam操作由设备名疏忽引发的连环误操作,最终却因单盘 RAID1 的特性和 mdadm 的底层机制而“有惊无险”地过关。
几条深刻的经验教训:
操作前务必三确认设备名。
/dev/md3和/dev/md5一字之差,后果完全不同。在执行危险命令前停顿数秒、逐字核对设备名,是规避灾难的最低成本方式。修复现有阵列请用
--assemble,忘掉--create。-C是新建空阵列的指令,不应作为修复手段。这次因为单盘侥幸逃过,多盘场景下可能酿成数据永久丢失的惨剧。元数据与数据区的分离是最后一道防线。
mdadm的超级块只占据磁盘头部的少量空间,与真正的文件系统数据区分离。只要数据区没有被覆写,数据就有恢复的可能。理解这一底层原理,能在关键时刻做出正确判断。只读验证永远是最好的习惯。 在不确定数据状态时,始终以只读方式挂载检查(
mount -o ro),而不是直接读写挂载。这能避免二次伤害,为补救留出空间。
最终结果:/dev/md3 毫发无伤,/dev/md5 数据完整可用。一次让人后背发凉的误操作,换来的是一个沉甸甸的运维教训——在 Linux 命令行面前,再谨慎都不为过。
总结
1、nas这种设备用来用的,能用别折腾,高温高个几度可能没啥问题,但是来回折腾可能导致掉盘,空间损毁等危害更大,nas是硅基的,50度没问题o( ̄︶ ̄)o
2、在群晖这类成熟nas上,尽量不要手动命令行操作,能界面修复的界面修复,如果不得不命令行修复,一定要确认好设备、确认好命令,如果参照教程,不要直接粘贴命令进去,可能粘贴自带换行导致直接执行了,导致不可挽回的错误
3、上面的手动madam操作,有2次的误操作过程,一个是把其他的阵列错误的停止了;一个是创建新的阵列把错误停止的阵列名称占用了,虽然最终没有清空数据区和raid相关数据,能够恢复,是有点幸运以及madam的优秀设计防呆了,否则后果不堪设想。。。数据必然丢失
这里尤其关键,必须把外部获取到的命令,现在文档中编写并确认,不能直接粘贴过来就运行(有的命令待换行,粘贴过来不回车就执行了),太危险了
参考文档
https://zhuanlan.zhihu.com/p/672190639
发表评论