群晖硬件软件背景:

        PVE虚拟机,底层文件系统为zfs,有z1 z2 z3三个zpool

        群晖硬盘分别从三个zpool各拿5T空间,使用zvol创建虚拟空间。

        使用群晖自带存储管理,从5T扩展到5Traid1,再扩展到10T raid5。

        群晖版本7.2 处理器AMD 8G内存 宿主机64G LPDDR4 无纠错

开端:

        半年前第一次接触群晖,从z1先拿了5032G作为存储,玩各种网页套件和docker不亦乐乎。(伏笔32G)

        容量不够了,于是从z2又拿了5033G(注意这个33)组了raid1,完成了迁移。因为raid1特性,此时我就把一些重要数据开始往里存(噩梦开端)。

        把原来z3的一些数据做了整理、迁移、删除后,又腾出了些空间,于是拿了5034G给群晖。

 至于我为什么不用统一的容量大小,因为管理虚拟机多了就知道,虚拟磁盘在虚拟机内都是sda sdb sdc这样,不会有高度有辨识的序列号。所以我用容量来区分不同的硬盘。不过可能都是业余行为,不然也不会有这个文章(

承接:

  zvol功能本来也是PVE的功能,据说对于虚拟机的管理有帮助。随着虚拟机数量变多,我准备把原来直接存放在zpool根目录的虚拟磁盘文件转移为zvol。(每个zvol就相当于一个虚拟磁盘)期待更好的性能和碎片管理。接下来是我的天才操作。

        在组完raid1后,我想把新添加的z2的空间转移到z2/zvol2中,于是我关闭DSM,直接删除了位于z2的虚拟磁盘文件,然后添加5033G的z2/zvol2给群晖。然后开启群晖,选择修复阵列。(后话:删除后重组开机就出现了”Checksum mismatch“的警告,但我没有在意,因为只是警告。)

        t3这里也并一开始就是zvol,添加进群晖并等待了几天做添加磁盘和扩大空间的操作。

        终于完成raid5的扩展,实际可用空间自然是10t左右,然后我发现一个事,io很拉垮,写入文件长期只有8MB/s。检查发现io全部卡在t1。这才发现,t1这里还没有转换成zvol。

        然后又是拿“数”好戏,我把t1的虚拟磁盘删了,重新创建5034G的t1/zvol,并让群晖自己修复。

承接2:

 也确实修复完成了,我本来想做一次数据清洗,但是速度太慢就一直没开始。同时各种软件比如qbittorrent、Phoprism、BiliRec都是夜以继日对整个阵列进行写入操作。

        因为感觉写入比较碎的,于是考虑添加一些写入缓存,然后我又从宿主机的两块不同的ssd分区拿了32G的空间作为读写缓存。

转折:       

        某一天我删除了z3的一个超级旧的快照,为什么说旧,因为创建于两年前,意味着碎片非常多。然后zfs就卡死了,z3对应的硬盘io占用和延迟都拉满,宿主机也因此而卡顿,有几个虚拟机也卡住了。然后发生了几次强制重启,等待3天左右才把那个快照删除掉。

结局:

        终于io什么都正常下来了,接下来几天我重新检查所有虚拟机,检查到群晖,就发现日志出现大量”Checksum mismatch“。

        我准备对这个”Checksum mismatch“的问题仔细研究,我发现报错的都是qbittorent的下载文件,没有涉及重要目录和文件,于是我准备删除qbit目录和快照,并且另外开一个不带校验的共享目录专门给qbit下载。(反正可以重新下((

        最后,在我执行删除qbit目录的操作时,存储池提示堪用,某个硬盘无法访问了。重启过后又恢复了,于是并未在意。

        最后的最后,我执行删除快照操作后,群晖提示正在回收快照的存储空间时,存储池警报大作,存储池变为只读。

目前的情况:

        紧急迁移了数据,迁移过程不顺利,大量重要文件在读取的时候才发现无法读取或者校验码错误。检查校验嘛错误的文件内容,都是一段有一段无,典型的raid0损毁后只能读取不连续的一半内容的状态。大概救了5成数据。

        重启会短暂处于堪用可读写状态,不久就会变成只读,哪怕三个虚拟硬盘看起来都是正常的,也不能恢复为读写。

        因为近期在做数据整理迁移,存储空间不够,所以并没有及时拍快照,所以直接删除的那些虚拟磁盘文件都无法通过快照召回了,简直就是天才操作。

        在发生只读情况后,我给DSM虚拟机拍摄了完整快照,每个磁盘都有快照,可以随时回溯。

        经过痛苦的代码和查阅资料、分析我的阵列信息,目前似乎是重组成功,正在等待三块硬盘的数据同步一遍,看看是否会有奇迹发生。

后话:zfs无论怎么样反正一直稳如老狗,管他群晖宿主怎么崩溃,反正从头到尾一点问题也没有。除了碎片真的多(

—————————————————————————————————————————————————

好了,文学时间结束,现在是代码时间了

        首先了解到群晖的阵列原理:

                群晖的硬盘是否有顺序的实验https://www.hao4k.cn/thread-43258-1-1.html

                群晖阵列底层逻辑:https://post.m.smzdm.com/p/az5005qo/      

        群晖阵列修复实例

                https://kenvix.com/post/fix-syno-dsm7-disk-damaged/

       群晖root ssh登陆等:

                群晖:7.2获取root权限及开启root账号登陆的办法_网络存储_什么值得买

        Linux阵列命令实例:

                linux之磁盘阵列实战_51CTO博客_48盘位磁盘阵列

                询问GPT得到的延伸命令:

                        要使用 mdadm 创建一个 RAID 5 设备,指定三个设备路径 /dev/sda/dev/sdb/dev/sdc,可以使用以下命令:mdadm -C /dev/md0 -l 5 -n 3 /dev/sda /dev/sdb /dev/sdc                                 

参数解释:

  • -C: 创建一个新的 RAID 设备。
  • /dev/md0: 要创建的 RAID 设备名称。
  • -l 5: 指定 RAID 级别为 RAID 5。
  • -n 3: 指定 RAID 中的设备数量,这里是 3 个设备。
  • /dev/sda /dev/sdb /dev/sdc: 用于 RAID 的物理设备路径。

                        这个命令会创建一个名为 /dev/md0 的 RAID 5 设备,包含 /dev/sda/dev/sdb/dev/sdc 三个设备。

        

检查阵列信息:

# cat /proc/mdstat

Personalities : [raid1] [raid6] [raid5] [raid4] [raidF1]

md3 : active raid5 sdi5[2] sdj5[3]       10535601664 blocks super 1.2 level 5, 64k chunk, algorithm 2 [3/2] [_UU]

md4 : active raid5 sdj6[1] sdk6[2]       7596672 blocks super 1.2 level 5, 64k chunk, algorithm 2 [3/2] [_UU]

md2 : active raid1 sdh5[0]       22827328 blocks super 1.2 [1/1] [U]

md1 : active raid1 sdh2[0]       2097088 blocks [12/1] [U___________] md0 : active raid1 sdh1[0]       8388544 blocks [12/1] [U___________] unused devices: <none>

        显然,虽然群晖的存储页面显示所有三个硬盘都正常,但是实际上有一个硬盘并没有在阵列里

查看阵列详情

        # mdadm -D /dev/md3 /dev/md3:        

        Version : 1.2   Creation Time : Sat Sep 14 20:01:35 2024      

        Raid Level : raid5      

        Array Size : 10535601664 (10047.53 GiB 10788.46 GB)  

        Used Dev Size : 5267800832 (5023.77 GiB 5394.23 GB)    

        Raid Devices : 3   Total Devices : 2    

        Persistence : Superblock is persistent    

        Update Time : Sun Nov  3 18:26:45 2024          

        State : clean, degraded  Active Devices : 2 Working Devices : 2  Failed Devices : 0   Spare Devices : 0          

        Layout : left-symmetric      Chunk Size : 64K            Name : xxxxx:3  (local to host xxxxx)            

        UUID : xxxxxx:ae3fe676:52e95223:xxxxxxx         

        Events : 136214    

        Number   Major   Minor   RaidDevice State        -       0        0        0      removed        

        2       8      133        1      active sync   /dev/sdi5        

        3       8      149        2      active sync   /dev/sdj5

        ~# mdadm -D /dev/md4

        /dev/md4:        

        Version : 1.2  

        Creation Time : Sun Oct 27 09:49:11 2024      

        Raid Level : raid5      

        Array Size : 7596672 (7.24 GiB 7.78 GB)  

        Used Dev Size : 3798336 (3.62 GiB 3.89 GB)    

        Raid Devices : 3   Total Devices : 2    

        Persistence : Superblock is persistent    

        Update Time : Sun Nov  3 18:26:40 2024          

        State : clean, degraded  

        Active Devices : 2 Working Devices : 2  Failed Devices : 0   Spare Devices : 0          

        Layout : left-symmetric      Chunk Size : 64K            

        Name : DiskCenter:4  (local to host DiskCenter)            

        UUID : xxxxxx:bac4cbf2:3a707649:xxxxx         

        Events : 74    

        Number   Major   Minor   RaidDevice State      

          -       0        0        0      removed        

        1       8      150        1      active sync   /dev/sdj6        

        2       8      166        2      active sync   /dev/sdk6                     

这个大小只有7.78G都raid5阵列mt4就是我在背景介绍部分提到的坑

我使用的虚拟磁盘为5032G 5033G和5034G,根据群晖的阵列原理,多出来的小空间组成了一些小的raid1和raid5。

分析阵列组成发现,sdi的第5分区、sdj的第5分区(以下简化为sdx5或sdx6)组成了最大的阵列部分,而sdj6 sdk6组成了小的raid5,都是降级的raid5。三块硬盘,sdj sdk sdi那你会发现每个阵列都正好缺了一个硬盘的部分。

因为三个磁盘一定是在线的,所以我尝试停止并重新扫描阵列

# mdadm -Sf /dev/md3

mdadm: stopped /dev/md3

# mdadm -Sf /dev/md4

mdadm: stopped /dev/md4

# mdadm --assemble --scan

mdadm: /dev/md/3 has been started with 2 drives (out of 3).

dadm: /dev/md/4 has been started with 2 drives (out of 3).

mdadm: giving up.

但是自动扫描也扫不出东西来

上文中有人提到恢复阵列的实战中,可以通过重建阵列并修改uuid的方法来重新恢复存储空间,其原因就是虚拟磁盘的io读写可能发生超时,于是群晖就直接降级使用了???我勒哥豆啊

他使用的是单盘raid1,询问gpt得到raid5的代码,尝试重建raid5

##!!!警告:我的宿主机有完整快照备份,因此这些操作都可以完全回溯,如果要继续,务必做好数据备份!!!##

# mdadm -Cf /dev/md4 -e1.2 -n3 -l5 /dev/sdk6 /dev/sdi6 /dev/sdj6 -uxxxxxxx:bac4cbf2:3a707649:xxxxxxx

mdadm: /dev/sdk6 appears to be part of a raid array:        level=raid5 devices=3 ctime=Sun Oct 27 09:49:11 2024

mdadm: /dev/sdi6 appears to be part of a raid array:        level=raid5 devices=3 ctime=Sun Oct 27 09:49:11 2024

mdadm: /dev/sdj6 appears to be part of a raid array:        level=raid5 devices=3 ctime=Sun Oct 27 09:49:11 2024

Continue creating array? y

mdadm: array /dev/md4 started.

#   mdadm -Cf /dev/md3 -e1.2 -n3 -l5 /dev/sdk5 /dev/sdi5 /dev/sdj5 -uxxxxxx:ae3fe676:52e95223:xxxxxx

mdadm: /dev/sdk5 appears to be part of a raid array:        level=raid5 devices=3 ctime=Sat Sep 14 20:01:35 2024

mdadm: /dev/sdi5 appears to be part of a raid array:        level=raid5 devices=3 ctime=Sat Sep 14 20:01:35 2024

mdadm: /dev/sdj5 appears to be part of a raid array:        level=raid5 devices=3 ctime=Sat Sep 14 20:01:35 2024

Continue creating array? (y/n) y

mdadm: array /dev/md3 started.

查看阵列状态

~# cat /proc/mdstat

Personalities : [raid1] [raid6] [raid5] [raid4] [raidF1]

md3 : active raid5 sdj5[2] sdi5[1] sdk5[0]      

10535601664 blocks super 1.2 level 5, 64k chunk, algorithm 2 [3/3] [UUU]      

[>....................]  resync =  0.0% (4451328/5267800832) finish=697.3min speed=125792K/sec

md2 : active raid1 sdh5[0]       22827328 blocks super 1.2 [1/1] [U]

md1 : active raid1 sdh2[0]       2097088 blocks [12/1] [U___________]

md0 : active raid1 sdh1[0]       8388544 blocks [12/1] [U___________]

可以看到大伙都在火热同步中,这个命令应该不是把原来的删了重建而是原地重组???

再次提醒,做好备份做好备份

这次也提醒一个问题,群晖本身对于阵列的处理机制似乎还不是很好,系统本身也有很多陈年累月的问题(比如重启后基于容器的网页服务被停用),自带的webui也不能完全反映问题,警告的分级不清晰(文件都损坏了还只是警告一个“Checksum Mismatch”?应该报大警才对)还需要用户有linux的基础才能解决很多问题。以后不会拿群晖做存储管理,或者说会更加谨慎至少。

具体我也不懂,现在正在重建,等一个后续吧

后续:

使用群晖madam重组阵列后,群晖存储访问那些之前损毁的文件,依然还是损毁的不连续状态。但是阵列本身确实重组成功了,从只读堪用变成仅只读了((

现在全部导入另一个虚拟机,使用ufs recovery访问确定是存在数据损坏了。难道是写入缓存什么的问题?先尝试全阵列扫一遍看看有没有发现吧

扫描发现,越新的数据的损毁越严重,而比较旧的数据因为有快照的缘故———依然损毁严重,重要数据都设置了快照保护,然而某些操作好像忽略了快照的存在一样。而且损坏的范围没有规律,新拷贝的数据、旧拷贝的数据;经常读写、极少访问的数据;大型文件、小型文件;有快照保护、无快照保护都是或随机或连续出现损坏……

找了一圈发现,还好最重要的数据如照片和工程,基本都还有原始存档,只是分散在手机和电脑里。此次数据大奔溃的影响应该可以降低到一成以下。

总结:

        重要数据3+2+1,常用工程raid10,不常用数据磁带+云端。raid5介于不常用与常用间,重组数据要检查。

后记(居然还有后记,要不出个第二季?):

        极大概率确定为群晖的写入缓存机制导致,因为群晖默认是使用内存写入缓存的。这就意味着断电数据会丢失。而尤其虚拟机系统,开关机经常不是正常关机。正常使用倒不会反复断电重启。连zfs这么稳的文件系统,也出现过反复强制关机下崩溃损毁,更不用说群晖使用的btrfs了。


虽然我也没想出第二季,但是很可惜还是来了……


第二次群晖单盘阵列进入只读状态的数据恢复

经过上次的三盘raid5有很多奇妙问题后,这一次我使用了虚拟机单盘结构,因为我的底层宿主使用的是使用raid10的机械硬盘+ssd缓存的ZFS文件系统,稳如泰山属于是。

然而一段时间过去了,某一天发现web应用无法写入数据了,后台一看好家伙,存储池read-only警告了。于是立刻进行了虚拟机全盘快照,重启后只读恢复了,显示系统分区损坏,于是修复了系统分区,一切安好。后来一个月相安无事,就将前文的快照删除了。于是又过了一个月,又是一个readonly红牌来袭,这就让我心脏有所紧张了,这一次就立马把所有上面的重要数据迁移出去,并准备系统分析一下产生这个问题的根源在什么地方。

进入群晖命令行,使用sudo -i进入root用户操作:

#查看所有文件系统

btrfs filesystems show

#获取到挂载路径



#检查scrub状态

btrfs scrub status /dev/mapper/cachedev_0

#scrub状态没有信息



#检查设备状态

btrfs device stats /dev/mapper/cachedev_0

[/dev/mapper/cachedev_0].write_io_errs   4

[/dev/mapper/cachedev_0].read_io_errs    0

[/dev/mapper/cachedev_0].flush_io_errs   0

[/dev/mapper/cachedev_0].corruption_errs 1

[/dev/mapper/cachedev_0].generation_errs 0

#显示没有读io错误,但是有一堆写io错误。难道又是写延迟导致的?

#确认核心数据迁移完成后使用磁盘管理器的“转换为可读写”选项恢复池功能(因为没找到命令行怎么搞)

#再次运行scrub

btrfs scrub start /dev/mapper/cachedev_0

btrfs scrub status -v /dev/mapper/cachedev_0

#因为群晖没有watch命令所以使用如下结构检测​​​​​​​scrub进度

while true; do  
  echo "==== $(date) ===="  
  btrfs scrub status -R /dev/mapper/cachedev_0
  sleep 5   
done 

完成后的结果是

scrub started at Mon Jun 30 17:20:01 2025 and finished after 04:12:52
	data_extents_scrubbed: 31390039
	tree_extents_scrubbed: 360850
	data_bytes_scrubbed: 1964511379456
	tree_bytes_scrubbed: 5912166400
	read_errors: 0
	csum_errors: 0
	verify_errors: 0
	no_csum: 46079
	csum_discards: 0
	super_errors: 0
	malloc_errors: 0
	uncorrectable_errors: 0
	unverified_errors: 0
	corrected_errors: 0
	last_physical: 2072493686784

也就是没有坏的文件块

未完待续

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐