一、

前言概述

书接上回,https://zskjohn.blog.csdn.net/article/details/160741859 Linux|操作系统|最新版openzfs编译记录,上文将zfs文件系统编译安装完毕了,也做了一些总结,但总结的不够全面,本文在做一些补充;其次,是zfs文件系统安装完毕后并没有开始实际使用,计划在安装过zfs文件系统的服务器上安装pg数据库,测试下zfs文件系统的闪回功能是否能够如愿,也就是深入研究下zfs文件系统和数据库系统之间的深度融合,即落地实践

上文的zfs源码和适用于centos7的zfs文件系统 二进制rpm安装包见下面链接,有需要的同学自取:

通过网盘分享的文件:zfs文件系统通过网盘分享的文件:zfs文件系统
链接: https://pan.baidu.com/s/1hBs5xTSkaxhRVORu9AiP-g 提取码: msw7 
--来自百度网盘超级会员v7的分享

注:gz文件是zfs文件系统的源码,xz文件是内核源码,bz文件是在centos7虚拟机上编译出来的产出物,里面包括了所有的zfs文件系统的rpm文件

https://blog.csdn.net/alwaysbefine/article/details/161169607  Linux|操作系统|最新版zfs编译后的适用于centos7的rpm安装包完全离线安装介绍

这个是详细的离线centos7使用rpm安装zfs文件系统,zfs-2.4.1-newrpm.tar.gz是最新的rpm包,包括zfs文件系统部署所需的所有依赖,具体如何安装请看这个文章

二、

zfs文件系统编译成功后的一些总结

1、zfs文件系统的编译和gcc版本并没有严重依赖,因此,编译器使用系统自带的gcc-4.8即可,这个是和一些软件的编译的显著区别,也就是对编译工具没有太多的依赖问题

2、zfs文件系统的编译对于交叉编译是比较全面的,因为在编译zfs文件系统的过程中,发现了很多关于交叉编译的帮助介绍;因此后续可以练习交叉编译

3、zfs文件系统编译的make阶段需要修改一些makefile的编译配置,根本原因是zfs源码对于系统的cpu性能有一定的检测,在虚拟机环境由于虚拟机的局限性问题,需要屏蔽对于系统cpu的检测,具体的修改配置见上文

4、zfs文件系统的正常运行需要更多的内存和cpu,据推测是因为该文件系统需要不停的校验数据,说通俗点就是该文件系统对于硬件资源需要更多相比于普通文件系统

5、zfs文件系统的稳定性并不太确定,需要留待以后测试后确定

6、zfs文件系统由于是编译的内核模块,因此,需要写配置文件,命令为 : echo zfs | sudo tee /etc/modules-load.d/zfs.conf,这样即使重启后,仍能正确加载zfs模块

7、上文make rpm命令生成的zfs-dkms-2.4.1-1.el7.noarch.rpm安装前会校验内核版本,如果有低于4.18的内核版本,即使该内核并没有使用也会拒绝安装,因此,解决方案为将不相关的内核全部删除即可,删除方法为yum remove 内核版本,例如yum remove kernel-3.10.0-1062.el7 kernel-devel-3.10.0-1062.el7

8、zfs文件系统编译需要无删减的正常的版本号大于4.18的内核,长期稳定支持版也就是lt内核版本经反复测试不可以使用,ml内核版本也不可用,主要原因是一些内核模块在长期稳定版本内已精简去除,因此,推荐从内核源码编译一个新的全面的内核使用

9、rpm安装包其实也是临时编译,各位同学安装部署的时候应该就明白了

总结完毕,以后有新的情况在补充到这里,下面开始zfs文件系统的正式使用测试

三、

关键概念

计划先介绍概念,下一章节仔细介绍实操问题

zfs存储池

  • 概念:这是ZFS的基石。您将一块或多块物理磁盘(或文件)聚合为一个统一的存储资源池,称为“zpool”。池管理所有底层细节,如冗余、设备故障和存储空间分配。

  • 操作:您首先需要创建池。池的冗余和数据分布策略通过vdev来定义。一个池由一个或多个vdev组成。

虚拟设备

  • 概念:vdev是池中物理设备的基本组织单元。它决定了数据的冗余和性能特性。一旦vdev中的某块磁盘损坏,整个vdev将失效,进而可能危及整个池。​ 因此,vdev的配置至关重要。

  • 常见vdev类型

    类型

    最少磁盘数

    冗余能力

    可用容量

    典型场景

    条带

    1

    无。任一磁盘损坏即丢失数据。

    N * 磁盘容量

    追求最大性能与容量,数据可丢弃。

    镜像

    2

    可损失N-1块盘。

    单块磁盘容量

    高可用性、关键数据,如操作系统盘。

    RAIDZ1

    2

    可损失1块盘。

    (N-1) * 磁盘容量

    平衡容量与冗余,类似RAID 5。

    RAIDZ2

    3

    可损失2块盘。

    (N-2) * 磁盘容量

    更高安全性,类似RAID 6。

    RAIDZ3

    4

    可损失3块盘。

    (N-3) * 磁盘容量

    用于超大阵列,提供极高容错。

  • 本例中使用RAID-Z2
# 使用单个磁盘创建简单池
 zpool create mypool /dev/sdb

# 创建镜像池(类似 RAID1)
 zpool create mymirror mirror /dev/sdb /dev/sdc

# 创建 RAID-Z1 池(类似 RAID5,允许一块磁盘故障)
 zpool create myraidz raidz /dev/sdb /dev/sdc /dev/sdd

# 创建 RAID-Z2 池(允许两块磁盘故障)
 zpool create myraidz2 raidz2 /dev/sdb /dev/sdc /dev/sdd /dev/sde

本例中,VMware虚拟机已添加三块硬盘,硬盘情况如下:

[root@centos1 opt]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sdd               8:48   0   20G  0 disk 
sdb               8:16   0   20G  0 disk 
sr0              11:0    1  4.4G  0 rom  /mnt
sdc               8:32   0   20G  0 disk 
sda               8:0    0  200G  0 disk 
├─sda2            8:2    0  195G  0 part 
│ └─centos-root 253:0    0  195G  0 lvm  /
└─sda1            8:1    0  800M  0 part /boot

使用RAID-Z2 池

[root@centos1 opt]# zpool create mypool raidz /dev/sdb /dev/sdc /dev/sdd
[root@centos1 opt]# zpool list
NAME     SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
mypool  59.5G   217K  59.5G        -         -     0%     0%  1.00x    ONLINE  -

可以看到,创建的时候没有回显,这个是正常的情况,查看池状态:

# 查看所有池
 zpool list
zpool status

# 查看详细状态
 zpool status -v

# 查看池的 I/O 统计
 zpool iostat -v
[root@centos1 opt]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sdd               8:48   0   20G  0 disk 
├─sdd9            8:57   0    8M  0 part 
└─sdd1            8:49   0   20G  0 part 
sdb               8:16   0   20G  0 disk 
├─sdb9            8:25   0    8M  0 part 
└─sdb1            8:17   0   20G  0 part 
sr0              11:0    1  4.4G  0 rom  /mnt
sdc               8:32   0   20G  0 disk 
├─sdc9            8:41   0    8M  0 part 
└─sdc1            8:33   0   20G  0 part 
sda               8:0    0  200G  0 disk 
├─sda2            8:2    0  195G  0 part 
│ └─centos-root 253:0    0  195G  0 lvm  /
└─sda1            8:1    0  800M  0 part /boot
[root@centos1 opt]# blkid
/dev/sda1: UUID="277dd10e-fe61-4163-b2cf-45f68cc4903b" TYPE="xfs" 
/dev/sda2: UUID="NbO3jS-79TU-KjIw-SdP9-jRWL-NDfy-AfVC30" TYPE="LVM2_member" 
/dev/sr0: UUID="2019-09-11-18-50-31-00" LABEL="CentOS 7 x86_64" TYPE="iso9660" PTTYPE="dos" 
/dev/mapper/centos-root: UUID="f7d7a8b8-998c-4441-b315-8c534a98e663" TYPE="xfs" 
/dev/sdd1: LABEL="mypool" UUID="6972120639383134127" UUID_SUB="8401739302345159012" TYPE="zfs_member" PARTLABEL="zfs-3f67081b8ea52865" PARTUUID="9cf041f5-7aeb-3c49-9d1f-0b159f562d32" 
/dev/sdd9: PARTUUID="f20d21c8-2840-264a-8101-efef6aaef780" 
/dev/sdc1: LABEL="mypool" UUID="6972120639383134127" UUID_SUB="5242556028257818377" TYPE="zfs_member" PARTLABEL="zfs-2f3350307d4a9762" PARTUUID="fd4869b6-f082-3245-ba70-4dc5b28a061f" 
/dev/sdc9: PARTUUID="9bb803a8-cc83-4248-9a22-0dbc91311de2" 
/dev/sdb1: LABEL="mypool" UUID="6972120639383134127" UUID_SUB="13051836529633263918" TYPE="zfs_member" PARTLABEL="zfs-a409b2d7f9bd65fa" PARTUUID="477ad45c-d65a-a746-9097-da6543b32359" 
/dev/sdb9: PARTUUID="1fcb6269-b9ef-b845-b49b-7e0d9f0870f1" 

可以观察到,分区已经自动生成,现在磁盘是池化状态了,还没有开始正式使用,因为没有挂载点

那么,快速使用这个数据池呢?非常简单的一个命令:zfs set mountpoint=/data1 mypool 

此时,可以看到有一个根文件夹/data1已经自动建立,属性如下:

[root@centos1 ~]# df -Th
Filesystem              Type      Size  Used Avail Use% Mounted on
devtmpfs                devtmpfs  3.9G     0  3.9G   0% /dev
tmpfs                   tmpfs     3.9G     0  3.9G   0% /dev/shm
tmpfs                   tmpfs     3.9G  8.9M  3.9G   1% /run
tmpfs                   tmpfs     3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/mapper/centos-root xfs       195G   17G  179G   9% /
/dev/sr0                iso9660   4.4G  4.4G     0 100% /mnt
/dev/sda1               xfs       797M  209M  588M  27% /boot
tmpfs                   tmpfs     794M     0  794M   0% /run/user/0
mypool                  zfs        20G  128K   20G   1% /data1

可以看到该挂载点的文件系统格式是zfs了,但这里需要注意一下大小是20G,池子大小创建的时候是三个20G的磁盘,现在是只有20G了,这里的意思是sdb,sdc,sdd这三个磁盘任意两个损坏了,文件系统仍然是正常的

如果是RAID-Z1,三个20G的硬盘将会被最终格式化为40G,这三个硬盘即使任意一个磁盘损坏,文件系统仍然是正常的

ZFS 通过“隐藏”底层的磁盘分区复杂性让存储部署变得极其简单。这种“简单粗暴”是 ZFS 设计哲学的一部分——让管理员专注于数据逻辑(数据集、快照、属性),而非硬件细节(分区、扇区、RAID 条带)。

这里的操作等同于普通的整盘挂载,不需要分区和格式化了,非常简单快速就挂载好了。

那么,该方式是非常简单粗暴的,并不能对磁盘管理做一个精细化,个性化的设置

当然,也可以分区后在创建池,这些是很灵活的,例如像这样:

# 1. 使用 fdisk/gdisk 对磁盘进行分区(例如创建 /dev/sdb1)
# 2. 使用分区 ID 或磁盘 ID 创建池(更稳定,可混合使用)
sudo zpool create mypool raidz /dev/disk/by-id/scsi-0QEMU_disk1-part1 /dev/disk/by-id/scsi-0QEMU_disk2-part1

# 或者使用分区路径
sudo zpool create mypool raidz /dev/sdb1 /dev/sdc1

在生产环境中,为了避免 I/O 竞争和简化故障排查,强烈建议使用整块磁盘(/dev/sdb)或通过磁盘 ID(/dev/disk/by-id/)来创建 ZFS 池。除非你有非常特殊的混合存储需求,否则不要轻易使用分区。不使用硬件 RAID 卡(HBA 模式直通)是目前公认的最佳实践

原因如下:

  • 端到端数据完整性:ZFS 对所有数据块计算校验和(Checksum)。当它检测到数据损坏(比如磁盘静默错误)时,它能利用 RAID-Z 的冗余数据自动修复坏块。硬件 RAID 通常只保证“写入不丢”,但不做读取校验。

  • 避免写洞(Write Hole):传统 RAID 在断电时可能发生“写洞”导致数据不一致。ZFS 采用写时复制(Copy-on-Write)和事务性模型,从根本上杜绝了写洞。

  • 运维透明:ZFS 的 zpool status命令能直接显示哪块物理磁盘响应慢或报错。如果使用硬件 RAID,你需要依赖 RAID 卡的管理工具(如 MegaCLI)才能看到底层磁盘状态,运维非常麻烦。

删除pool和dataset(数据集):

[root@centos1 ~]# zfs destroy mypool
cannot destroy 'mypool': operation does not apply to pools
use 'zfs destroy -r mypool' to destroy all datasets in the pool
use 'zpool destroy mypool' to destroy the pool itself

这里要多说一句,这些删除仅仅是从zfs的层面删除,还是可以随时import和export回来的,因为通过fdisk 底层命令可以看到分区仍然存在(可以看到是gpt分区,属性是Solaris):
[root@centos1 ~]# fdisk /dev/sdb
WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: gpt
Disk identifier: 0A78AA6D-AEE1-FB4A-BA23-BE05D1241361


#         Start          End    Size  Type            Name
 1         2048     41924607     20G  Solaris /usr &  zfs-a409b2d7f9bd65fa
 9     41924608     41940991      8M  Solaris reserve 

因此,如果想要彻底删除zfs所有相关的分区,需要fdisk或者parted等命令进底层挨个删除(不建议这么做,直接重新格式化会比较好)

由于显示的是gpt分区表,因此有很多不常见的属性:

Command (m for help): l
  1 EFI System                     C12A7328-F81F-11D2-BA4B-00A0C93EC93B
  2 MBR partition scheme           024DEE41-33E7-11D3-9D69-0008C781F39F
  3 Intel Fast Flash               D3BFE2DE-3DAF-11DF-BA40-E3A556D89593
  4 BIOS boot                      21686148-6449-6E6F-744E-656564454649
  5 Sony boot partition            F4019732-066E-4E12-8273-346C5641494F
  6 Lenovo boot partition          BFBFAFE7-A34F-448A-9A5B-6213EB736C22
  7 PowerPC PReP boot              9E1A2D38-C612-4316-AA26-8B49521E5A8B
  8 ONIE boot                      7412F7D5-A156-4B13-81DC-867174929325
  9 ONIE config                    D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149
 10 Microsoft reserved             E3C9E316-0B5C-4DB8-817D-F92DF00215AE
 11 Microsoft basic data           EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
 12 Microsoft LDM metadata         5808C8AA-7E8F-42E0-85D2-E1E90434CFB3
 13 Microsoft LDM data             AF9B60A0-1431-4F62-BC68-3311714A69AD
 14 Windows recovery environment   DE94BBA4-06D1-4D40-A16A-BFD50179D6AC
 15 IBM General Parallel Fs        37AFFC90-EF7D-4E96-91C3-2D7AE055B174
 16 Microsoft Storage Spaces       E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D
 17 HP-UX data                     75894C1E-3AEB-11D3-B7C1-7B03A0000000
 18 HP-UX service                  E2A1E728-32E3-11D6-A682-7B03A0000000
 19 Linux swap                     0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
 20 Linux filesystem               0FC63DAF-8483-4772-8E79-3D69D8477DE4
 21 Linux server data              3B8F8425-20E0-4F3B-907F-1A25A76F98E8
 22 Linux root (x86)               44479540-F297-41B2-9AF7-D131D5F0458A
 23 Linux root (ARM)               69DAD710-2CE4-4E3C-B16C-21A1D49ABED3
 24 Linux root (x86-64)            4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709
 25 Linux root (ARM-64)            B921B045-1DF0-41C3-AF44-4C6F280D3FAE
 26 Linux root	(IA-64)             993D8D3D-F80E-4225-855A-9DAF8ED7EA97
 27 Linux reserved                 8DA63339-0007-60C0-C436-083AC8230908
 28 Linux home                     933AC7E1-2EB4-4F13-B844-0E14E2AEF915
 29 Linux RAID                     A19D880F-05FC-4D3B-A006-743F0F84911E
 30 Linux extended boot            BC13C2FF-59E6-4262-A352-B275FD6F7172
 31 Linux LVM                      E6D6D379-F507-44C2-A23C-238F2A3DF928
 32 FreeBSD data                   516E7CB4-6ECF-11D6-8FF8-00022D09712B
 33 FreeBSD boot                   83BD6B9D-7F41-11DC-BE0B-001560B84F0F
 34 FreeBSD swap                   516E7CB5-6ECF-11D6-8FF8-00022D09712B
 35 FreeBSD UFS                    516E7CB6-6ECF-11D6-8FF8-00022D09712B
 36 FreeBSD ZFS                    516E7CBA-6ECF-11D6-8FF8-00022D09712B
 37 FreeBSD Vinum                  516E7CB8-6ECF-11D6-8FF8-00022D09712B
 38 Apple HFS/HFS+                 48465300-0000-11AA-AA11-00306543ECAC
 39 Apple UFS                      55465300-0000-11AA-AA11-00306543ECAC
 40 Apple RAID                     52414944-0000-11AA-AA11-00306543ECAC
 41 Apple RAID offline             52414944-5F4F-11AA-AA11-00306543ECAC
 42 Apple boot                     426F6F74-0000-11AA-AA11-00306543ECAC
 43 Apple label                    4C616265-6C00-11AA-AA11-00306543ECAC
 44 Apple TV recovery              5265636F-7665-11AA-AA11-00306543ECAC
 45 Apple Core storage             53746F72-6167-11AA-AA11-00306543ECAC
 46 Solaris boot                   6A82CB45-1DD2-11B2-99A6-080020736631
 47 Solaris root                   6A85CF4D-1DD2-11B2-99A6-080020736631
 48 Solaris /usr & Apple ZFS       6A898CC3-1DD2-11B2-99A6-080020736631
 49 Solaris swap                   6A87C46F-1DD2-11B2-99A6-080020736631
 50 Solaris backup                 6A8B642B-1DD2-11B2-99A6-080020736631
 51 Solaris /var                   6A8EF2E9-1DD2-11B2-99A6-080020736631
 52 Solaris /home                  6A90BA39-1DD2-11B2-99A6-080020736631
 53 Solaris alternate sector       6A9283A5-1DD2-11B2-99A6-080020736631
 54 Solaris reserved 1             6A945A3B-1DD2-11B2-99A6-080020736631
 55 Solaris reserved 2             6A9630D1-1DD2-11B2-99A6-080020736631
 56 Solaris reserved 3             6A980767-1DD2-11B2-99A6-080020736631
 57 Solaris reserved 4             6A96237F-1DD2-11B2-99A6-080020736631
 58 Solaris reserved 5             6A8D2AC7-1DD2-11B2-99A6-080020736631
 59 NetBSD swap                    49F48D32-B10E-11DC-B99B-0019D1879648
 60 NetBSD FFS                     49F48D5A-B10E-11DC-B99B-0019D1879648
 61 NetBSD LFS                     49F48D82-B10E-11DC-B99B-0019D1879648
 62 NetBSD concatenated            2DB519C4-B10E-11DC-B99B-0019D1879648
 63 NetBSD encrypted               2DB519EC-B10E-11DC-B99B-0019D1879648
 64 NetBSD RAID                    49F48DAA-B10E-11DC-B99B-0019D1879648
 65 ChromeOS kernel                FE3A2A5D-4F32-41A7-B725-ACCC3285A309
 66 ChromeOS root fs               3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC
 67 ChromeOS reserved              2E0A753D-9E48-43B0-8337-B15192CB1B5E
 68 MidnightBSD data               85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7
 69 MidnightBSD boot               85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7
 70 MidnightBSD swap               85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7
 71 MidnightBSD UFS                0394EF8B-237E-11E1-B4B3-E89A8F7FC3A7
 72 MidnightBSD ZFS                85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7
 73 MidnightBSD Vinum              85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7
 74 Ceph Journal                   45B0969E-9B03-4F30-B4C6-B4B80CEFF106
 75 Ceph Encrypted Journal         45B0969E-9B03-4F30-B4C6-5EC00CEFF106
 76 Ceph OSD                       4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D
 77 Ceph crypt OSD                 4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D
 78 Ceph disk in creation          89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE
 79 Ceph crypt disk in creation    89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE
 80 OpenBSD data                   824CC7A0-36A8-11E3-890A-952519AD3F61
 81 QNX6 file system               CEF5A9AD-73BC-4601-89F3-CDEEEEE321A1
 82 Plan 9 partition               C91818F9-8025-47AF-89D2-F030D7000C2C

可以得出一个明确的结论:zfs文件系统是上层系统,内核强相关的,它的分区实现并不是通过调用底层程序来实现的,这一个过程是完全自动化的。ZFS 是内核级的存储栈重构,其磁盘管理是“去分区表”的自动化抽象

简单来说,ZFS 跳过了传统分区表这一层,直接坐在了磁盘驱动器的上一层。这就是为什么在 ZFS 最佳实践中,我们强调“不要用硬件 RAID,也不要预先分区”。

完全自动化体现在以下三点:

  • 无需预分区:最佳实践是直接使用整盘(/dev/sdX),ZFS 会自动处理磁盘布局,无需人工干预分区大小。

  • 动态扩容:添加新磁盘时,只需 zpool add,池容量自动扩展,无需调整分区。

  • 元数据自管理:ZFS 自动管理校验和、快照、克隆等所有元数据,对用户透明。

zfs的数据集的概念

  • 概念:在存储池之上创建的逻辑存储单元。您可以将其理解为传统文件系统中的“目录”或“分区”,但功能强大得多。数据集是实际存储文件、设置属性(如压缩、加密)和创建快照的载体。

  • 类型

    • 文件系统:标准的、可挂载的POSIX文件系统。

    • ZVOL:一个模拟的块设备,可以用于创建swap或供虚拟机使用。

  • 操作:您可以像创建目录一样轻松创建、销毁数据集,并为其设置独立的属性。

对于数据集的核心理解

概念

传统存储

ZFS 存储

物理存储

硬盘

存储池 (zpool)

逻辑划分

分区 (Partition)

数据集 (Dataset)

格式化

文件系统 (ext4/xfs)

数据集自动包含文件系统

挂载

mount 分区到目录

数据集自动挂载到指定路径

zfs文件系统的快照与克隆

  • 快照:数据集在某一时间点的只读副本。它占用空间极少(仅记录变化),创建速度极快,是数据备份、版本回滚的核心。

  • 克隆:基于快照创建的可写副本。初期不占用额外空间,后续独立变化。常用于数据分支测试。

四、

存储池的创建和销毁

使用zpool create命令,其核心语法为:

sudo zpool create <池名称> <vdev类型> <磁盘1> <磁盘2> ...

创建示例:

  1. 创建一个由2块磁盘组成的镜像池(高可用):

    
      
    
      
    zpool create mypool mirror /dev/sdb /dev/sdc
  2. 创建一个由4块磁盘组成的RAIDZ1池(允许坏1块盘):

    
      
    
      
    zpool create mypool raidz1 /dev/sdb /dev/sdc /dev/sdd /dev/sde
  3. 创建更复杂的池(例如:2个镜像vdev组成的池,兼具性能和容量):

    
      
    
      
    zpool create mypool mirror /dev/sdb /dev/sdc mirror /dev/sdd /dev/sde

    此池容量为2块磁盘之和,性能接近2块磁盘的并行读写,且可容忍每个镜像中坏掉1块盘。

查看zpool的状态:

[root@centos1 ~]# zpool list -v
NAME         SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
mypool      59.5G   446K  59.5G        -         -     0%     0%  1.00x    ONLINE  -
  raidz2-0  59.5G   446K  59.5G        -         -     0%  0.00%      -    ONLINE        -
    sdb     20.0G      -      -        -         -      -      -      -    ONLINE        -
    sdc     20.0G      -      -        -         -      -      -      -    ONLINE        -
    sdd     20.0G      -      -        -         -      -      -      -    ONLINE        -

注意事项:

  1. 使用整盘而非分区:建议将整个磁盘(如/dev/sdb)提供给ZFS,让其直接管理,避免分区表引入的单点故障和复杂度。

  2. vdev的扩展性:池的容量通过添加新的vdev来扩展。例如,可以向一个已有镜像vdev的池中,再添加一个由新磁盘组成的镜像vdev。

  3. 混合vdev警告避免在同一个池中混合不同类型的vdev(如一个镜像vdev和一个RAIDZ1 vdev)。池的整体性能和数据分布将受制于最慢的那个vdev,且空间分配会不均衡。

  4. 单盘vdev风险:一个仅由单个“条带”vdev(即一块盘)组成的池,没有任何冗余。该盘损坏将导致整个池数据丢失。

总结:创建vdev是ZFS部署中最需谨慎的步骤。请根据上方的决策图明确您的冗余需求容量目标,选择正确的vdev类型,并遵循使用整盘、及时验证的原则。规划得当的存储池是数据安全的基石。

存储池销毁的完整流程与注意事项

核心命令


sudo zpool destroy <池名称>
关键步骤与安全确认
  1. 终极确认:在执行前,请再次确认池名称。一个简单的拼写错误可能导致灾难。

    
      
    
      
    # 首先,列出所有池,双重确认目标池名
    zpool list
  2. 执行销毁

    
      
    
      
    # 例如,销毁名为 `oldpool` 的存储池
    sudo zpool destroy oldpool

    命令执行后没有确认提示,会直接、静默地完成。这是ZFS的设计哲学:假设管理员明确知道自己在做什么。

  3. 验证结果:销毁后,再次使用 zpool list命令,该池应从列表中消失。

高级选项与场景
  • 强制销毁(危险!):如果池被标记为“故障”或设备丢失导致无法正常导入,但您仍坚持要销毁其元数据,可以使用 -f标志。

    
      
    
      
    sudo zpool destroy -f corrupted_pool

    警告:这仅用于清理无法正常操作的池的元数据标签,不会恢复或擦除磁盘上的实际数据块。磁盘需要重新格式化才能安全使用。

  • 销毁后的磁盘处理:销毁操作仅移除了ZFS的元数据。磁盘上的原有数据实际上仍可能存在,直到被新数据覆盖。若要彻底清空磁盘以移作他用或归还,建议使用 wipefsdd命令清除磁盘开头部分的标签和分区信息。

    
      
    
      
    # 示例:清除 /dev/sdb 上的所有文件系统签名
    sudo wipefs -a /dev/sdb
关于操作权限的说明

总结与强烈建议

  1. 三思而后行:销毁前,务必确认数据已迁移或备份。

  2. 核对名称:使用 zpool list做最后确认。

  3. 理解后果:操作不可逆,且无确认提示。这个非常非常重要哦!!!!!

数据集的创建和销毁

在已创建的存储池之上,数据集是您实际用于存储文件、设置属性和管理快照的逻辑容器。您可以将其视为一个功能超级增强版的“目录”或“分区”。

核心创建命令


# 基本创建
zfs create <池名>/<数据集路径>

# 示例:在存储池 `mypool` 下创建一个名为 `data` 的数据集
zfs create mypool/data
##可以看到直接挂载到data1目录下了

[root@centos1 ~]# zfs create mypool/data
[root@centos1 ~]# ls /data1/
data

创建后,该数据集通常会自动挂载/<池名>/<数据集路径>(例如 /mypool/data),您可以直接开始使用。

创建时的高级控制(一次性设置属性)

创建命令可结合关键属性设置,一步到位,提升效率:



# 创建时启用压缩和设置挂载点
zfs create -o compression=lz4 -o mountpoint=/home/projects mypool/projects

# 创建时设置配额(限制该数据集最大使用空间为100G)
zfs create -o quota=100G mypool/home/user1
创建嵌套数据集(推荐的结构化方式)

ZFS鼓励使用嵌套数据集来替代传统目录,以实现精细化的属性管理和快照控制。



# 创建父数据集
zfs create mypool/apps
# 在父数据集下创建子数据集
zfs create mypool/apps/database
zfs create mypool/apps/webserver

优势:每个子数据集可以拥有独立的压缩、加密、配额和快照策略,管理非常灵活。


数据集的销毁:不可逆的删除操作

销毁数据集将永久删除该数据集内的所有文件、其所有快照以及其下的所有子数据集(如果使用递归选项)。操作前必须确认。

核心销毁命令与验证


# 1. 首先,务必确认要销毁的数据集名称和其包含的内容
zfs list -r mypool/data  # 列出`mypool/data`及其所有子数据集
zfs list -t snapshot -r mypool/data  # 列出该数据集下的所有快照

# 2. 销毁单个数据集(如果该数据集下无子数据集,且无挂载的文件系统正在使用)
zfs destroy mypool/obsolete_data
递归销毁(强制、危险!)

如果数据集包含子数据集或快照,必须使用 -r(递归)参数。



# 递归销毁 `mypool/apps/old` 及其所有子数据集和快照
zfs destroy -r mypool/apps/old

系统会提示确认,因为此操作不可逆。

强制卸载并销毁

如果数据集正忙(文件被打开、进程占用),无法销毁,可使用 -f强制卸载并销毁。



# 强制递归销毁
zfs destroy -rf mypool/apps/old

警告-f会强制终止使用该数据集的进程,可能导致数据损坏或程序异常,仅在其他方法无效时使用。

模拟销毁(安全预演)

在执行前,强烈建议使用 -n(干跑)和 -v(详细)参数进行模拟,查看哪些对象将被删除。



zfs destroy -rvn mypool/apps/old

输出将显示“would destroy”列表,而不会执行任何实际删除。这是最重要的安全步骤。

核心效率要点与权限总结

操作

命令示例

关键注意事项

通常所需权限

创建

zfs create pool/ds

可结合 -o一次性设置属性;鼓励嵌套结构。

已加入 zfs组的用户即可。

递归销毁

zfs destroy -r pool/ds

务必先 -n模拟;确认目标无误;递归会删除所有子项和快照。

通常需要 sudoroot,即使已在 zfs组。

强制销毁

zfs destroy -rf pool/ds

终极手段,会强制终止相关进程,可能导致问题。

必须 sudoroot

最佳实践流程

  1. 创建前规划:根据管理和备份需求,用嵌套数据集构建清晰的树形结构。

  2. 销毁前三步

    a. 列内容zfs list -r -t all <目标数据集>查看所有子项和快照。

    b. 做模拟zfs destroy -rvn <目标数据集>确认删除范围。

    c. 再执行:执行实际的 zfs destroy -r命令。

通过将数据集作为核心管理单元,您可以实现比传统目录精细得多的存储策略控制,这是发挥ZFS威力的关键。

数据集的最终意义:实现存储管理的“逻辑化”和“精细化”

在传统文件系统(如ext4)中,在一个分区里创建目录。所有目录共享相同的属性(压缩、配额、加密等),快照也只能针对整个卷进行。

ZFS的数据集彻底改变了这一模式,其核心意义在于:

1. 独立的属性管理(核心价值)

每个数据集都可以拥有自己独立的属性设置,并可以随时更改,互不影响。这实现了极致的灵活性:

  • 压缩:为mypool/db设置compression=zstd高强度压缩,为mypool/vm设置compression=lz4快速压缩,为mypool/backup关闭压缩。

  • 配额与预留空间:为mypool/home/alice设置quota=200G硬性上限,为关键项目mypool/projectX设置reservation=1T确保空间始终可用。

  • 挂载点:自由控制每个数据集挂载到文件系统的何处(mountpoint=/data/projectA)。

  • 加密:可以对单个数据集启用加密,而不必加密整个池。

2. 精确的快照与克隆
  • 快照粒度:您可以仅对mypool/www/production数据集创建秒级快照,而不会影响同池下的mypool/www/testing。这节省了时间和空间。

  • 克隆目标明确:您可以从一个数据集的快照克隆出一个独立的、可写的新数据集,用于开发测试或数据恢复,而不会牵连其他数据。

3. 高效的空间使用与监控
  • 空间核算zfs list可以清晰看到每个数据集的实际使用量(USED)、快照占用量、属性限制等。您可以快速定位是哪个项目或用户占用了大量空间。

  • 写时复制(CoW)共享:所有数据集和它们的快照共享池中的相同数据块。只有发生变化时才会占用新空间。这比为每个部门创建独立的LVM卷或分区要节省得多。

4. 权限与委托管理

您可以将特定数据集的管理权限(如创建快照、销毁数据集)安全地委托给普通用户或应用程序,而无需授予其整个存储池的管理权。这极大地提升了管理安全性和自动化能力。

一个直观的生产场景对比

假设您有一个存储池ssdpool,需要承载数据库、Web服务器日志和用户家目录。

  • 传统方式(使用目录)

    
      
    
      
    /ssdpool/
        ├── database/       # 无法单独设置压缩或配额
        ├── weblogs/        # 日志轮转影响整个池的性能
        └── home/           # 某个用户占满空间会导致所有服务中断

    管理混乱,属性一刀切,问题难以隔离。

  • ZFS方式(使用数据集)

    
      
    
      
    # 创建具有独立属性的数据集
    zfs create -o recordsize=16K -o compression=zstd -o logbias=throughput ssdpool/db
    zfs create -o compression=gzip -o atime=off ssdpool/logs
    zfs create -o quota=100G -o compression=lz4 ssdpool/home/alice
    zfs create -o quota=50G -o compression=lz4 ssdpool/home/bob
    
    # 结果挂载点
    /ssdpool/db/      # 为数据库优化
    /ssdpool/logs/    # 为日志文件优化
    /ssdpool/home/alice/ # 有空间硬限制
    /ssdpool/home/bob/   # 独立的空间限制

    每个单元可独立管理、监控、快照和恢复。

总结

数据集的最终意义,是将存储池提供的“物理资源块”,转化为了无数个可独立配置、安全隔离、高效管理的“逻辑存储服务单元”。

它让您能够:

  • 按需配置:为不同类型的数据应用最合适的存储策略。

  • 精准管控:实现子项目、部门或用户级别的空间、性能和功能控制。

  • 提升效率:通过细粒度快照和克隆,极大简化了数据保护、测试和开发流程。

  • 简化运维:通过清晰的属性继承和空间核算,快速定位和解决问题。

因此,在ZFS最佳实践中,强烈建议即使最初需求简单,也至少创建一个数据集来使用,而不是直接向存储池根目录写入数据。这为未来的管理留下了最大的灵活性和扩展性。

制数据集大小的主要方法和命令:

1. 配额:设置使用上限(硬限制)

配额​ 是数据集及其所有子数据集、快照等总共能消耗的最大磁盘空间。这是最常用的限制手段。

  • 设置配额

    
      
    
      
    # 将数据集 `mypool/projects` 的大小限制在 500GB
    zfs set quota=500G mypool/projects
  • 效果:当 mypool/projects下所有文件、快照等占用的空间总和达到500GB时,写入操作将失败并返回“磁盘空间不足”错误。

2. 预留:保证最低空间(软保证)

预留​ 是从存储池中预先划出并保证给该数据集使用的空间。这部分空间不会被其他数据集占用。

  • 设置预留

    
      
    
      
    # 保证 `mypool/critical_db` 至少有 200GB 可用空间
    zfs set reservation=200G mypool/critical_db
  • 效果:存储池会优先满足所有数据集的“预留”空间之和。即使池空间紧张,critical_db也至少有200GB可用。它通常与配额结合使用,为关键应用提供空间保障。

3. 引用配额与引用预留(更精确的控制)

上述标准配额和预留包含了子数据集和快照的空间。若需仅控制数据集自身数据,使用“引用”版本。

  • 引用配额:仅限制数据集自身数据的大小,不包括其快照和子数据集。

    
      
    
      
    # `mypool/home/alice` 自己的文件不能超过100GB,但其快照和子目录不受此限
    zfs set refquota=100G mypool/home/alice
  • 引用预留:仅保证数据集自身数据可用的空间。

    
      
    
      
    zfs set refreservation=50G mypool/home/alice

4. 空间核算与监控

控制大小的前提是清晰了解空间使用情况。

  • 查看所有数据集的空间使用情况

    
      
    
      
    zfs list -o name,used,avail,refer,quota,reservation,refquota,refreserv
    • USED:数据集及其所有后代(子数据集、快照)占用的总空间。

    • AVAIL:数据集当前可用的空间。

    • REFER:数据集自身数据(不包含快照和子集)的大小,这是判断是否超“引用配额”的关键。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐