zfs 速查手册

存储池配置

单个磁盘 无冗余,挂载为 /mypool,无需在 /etc/fstab 中添加条目。

zpool create mypool disk1

条带(RAID-0) 无冗余,任意一块磁盘损坏都会导致数据全部丢失。性能高,可用容量为所有磁盘总和。

zpool create mystripe disk1 disk2

镜像(RAID-1) 可承受一块磁盘损坏,VDEV 在 zpool status 输出中显示为 mirror-0,可并行读取所有磁盘,写入速度较慢,总容量低于 RAID-0。

zpool create mymirror mirror disk1 disk2

单奇偶校验(RAID-Z1) 至少需要 3 块磁盘,可承受 1 块磁盘损坏,奇偶校验信息分布在所有磁盘上,读写速度较快,性能相当,容量约为 66%。在 zpool status 输出中显示为 raidz1-0 VDEV。

zpool create paritypool raidz disk1 disk2 disk3

双奇偶校验(RAID-Z2) 每个 VDEV 可承受 2 块磁盘损坏,比 RAID-Z1 慢,至少需要 4 块磁盘,可用容量约为 50%。

zpool create myraidz2 raidz2 disk1 disk2 disk3 disk4

RAID10 至少需要 4 块磁盘,每个 VDEV 可承受 1 块磁盘损坏,读速快,写速为单个磁盘的一半,容量为 50%。是冗余性、容量和性能的良好折中方案。

zpool create myr10 mirror disk1 disk2 mirror disk3 disk4

三奇偶校验(RAID-Z3) 比 RAID-Z2 稍慢,每个 VDEV 可承受 3 块磁盘损坏,至少需要 5 块磁盘,可用容量约为 40%。

zpool create myz3 raidz3 disk1 disk2 disk3 disk4 disk5

显示存储池状态

显示存储池状态【包括磁盘配置、错误信息、适用的更新、上次 scrub 时间(若有)】

zpool status

显示存储池容量、已用空间和可用空间

zpool list

显示存储池 I/O 统计信息

zpool iostat

选项:

  • -v 显示各个设备

  • -w 显示 I/O 延迟

  • -r 显示请求大小直方图

  • -l 显示等待时间统计

  • -q 显示队列统计

显示存储池的管理命令历史

zpool history

选项:

  • -l 详细格式

  • -i 仅显示事务组等事件

获取存储池属性及其值,并可使用 zpool set 修改默认值

zpool get

特殊 VDEV

二级 ARC(L2ARC)

当数据不再适合存储在 ZFS 主内存缓存(ARC:自适应替换缓存)时,L2ARC 充当快速读取缓存。读取请求将由 L2ARC 处理,需使用高速存储设备(如闪存)才能获得显著效果。使用 cache 关键字将设备添加到存储池。

zpool add mypool cache /dev/nda0

ZFS 意图日志(ZFS intent log, ZIL)

将同步写入转换为异步写入(不影响读取),使应用程序能更快确认数据已写入,类似于数据库事务日志。当写入完成并存储到底层存储介质后,ZIL 将被清除。ZIL 需要快速存储设备,但无需大容量。使用关键字 log 将设备添加到存储池。

zpool add mypool log /dev/nda1

备用盘(Spare)

备用盘在替换故障磁盘之前不会参与 I/O 操作,可以由手动操作或外部故障管理软件触发替换。使用关键字 spare 添加备用盘。

zpool add mypool spare /dev/nda2

存储池扩展

将单磁盘存储池转换为 RAID1

为单磁盘存储池设备 /dev/nda0 添加镜像磁盘 /dev/nda1

zpool attach mypool mirror /dev/nda0 /dev/nda1

替换故障磁盘

将存储池中的故障磁盘 /dev/nda2 替换为设备 /dev/nda3

zpool replace mypool /dev/nda2 /dev/nda3

存储池导入/导出

导出存储池

完成 I/O 操作后,从文件系统层次结构中卸载存储池。可在其他系统上导入以恢复存储池状态。

zpool export mypool

导入存储池

将存储池导入当前系统。

  • 扫描 ZFS 存储池标识

    zpool import
  • 通过 ID 或名称导入存储池

    zpool import mypool
  • 重命名存储池

    zpool import oldname newname
  • 在不同路径下挂载已导入的存储池(防止覆盖现有存储池)

    zpool import -R /media mypool
  • 以只读模式导入存储池

    zpool import -o readonly mypool
  • 尝试恢复最近销毁的存储池

    zpool import -D mypool

ZFS 数据集

数据集位于存储池之上,并占用其空间。访问方式如下:mypool/data。每个存储池创建时,都会默认生成一个与其同名的顶级数据集。例如,执行以下命令:

zpool create test disk1

将创建一个名为 test 的存储池和数据集,顶级数据集将挂载为 /test,并可包含子数据集。

创建数据集

创建一个名为 ds 的新数据集,大部分属性继承自父数据集:

zfs create mypool/ds

创建多个数据集:

zfs create -p mypool/home/fred

显示数据集信息

列出已用空间、可用空间和挂载点

zfs list

按 ZFS 路径显示数据集

zfs list mypool/ds

列出数据集及其子数据集

zfs list -r mypool/ds

限制显示数据集的层级深度

zfs list -d 1 mypool/home

仅显示数据集名称

zfs list -o name mypool/home

移除输出头部

zfs list -Ho name mypool/home

修改显示顺序

zfs list -o used,avail,refer,name

按列排序

zfs list -rs refer mypool/home

倒序排列

zfs list -rS refer mypool/home

显示存储池可用空间

列出每个数据集及其子数据集的可用空间和已用空间,包括快照和任何预留空间:

zfs list -o space

推荐:使用该命令代替 df -h


重命名数据集

重命名数据集或在存储池层次结构内移动数据集,类似于 Unix mv 命令:

zfs rename mypool/home/fred mypool/home/eva

销毁数据集

模拟销毁(不会执行实际删除):

zfs destroy -nv mypool/old

输出

would destroy mypool/old

执行销毁并显示结果

zfs destroy -v mypool/old

输出

will destroy mypool/old

递归销毁数据集及其子数据集

zfs destroy -r mypool/testdata

属性管理

数据集通过继承父数据集的大部分属性来提高灵活性。子数据集可根据需要覆盖这些属性。仅可更改 SOURCE 列中的默认属性,存储池的属性规则相同。

显示属性

多种方式可以查看存储池和数据集的属性:

  • 查看存储池的属性

    zpool get all mypool
  • 查看数据集的属性

    zfs get all mypool/dataset
  • 查看单个属性(容量)

    zpool get capacity mypool
  • 查看多个属性(容量与健康状态)

    zpool get capacity,health mypool

修改属性

  • 禁用访问时间更新(可提高性能):

    zfs set atime=off mypool
  • 更改挂载点

    zfs set mountpoint=/media mypool/ds

自定义属性

可为数据集定义自定义属性(key=value),数据集会继承这些属性,但可更改其值。

  • 创建自定义属性

    zfs set warranty:expires=2048/04/20 mypool
  • 列出自定义属性

    zfs get warranty:expires mypool
  • 重置属性值(继承父级值):

    zfs inherit warranty:expires mypool
  • 删除自定义属性(递归删除):

    zfs inherit -r warranty:expires mypool

数据完整性检查(Scrub)

ZFS 在数据存储时会计算并存储校验和,覆盖整个数据集层次结构。I/O 错误、驱动故障、内存损坏、损坏的电缆等因素可能导致校验和不匹配。

如果存储池具有足够的冗余(如镜像或 RAID-Z),ZFS 可以检测到这些错误并自动修复(自我修复)。

建议 每月运行一次 Scrub,重新计算校验和。如果发现数据损坏,ZFS 会从冗余 VDEV 获取正确的数据并修正错误。

启动 Scrub

zpool scrub mypool

查看 Scrub 进度和错误信息

zpool status

ZFS 无需 fsck,因为 ZFS 自带数据完整性检查机制。

卷(Volumes)

ZFS 卷使用连续的存储池空间,并可通过 iSCSI 在网络上导出。当使用非 ZFS 文件系统格式化卷时,该文件系统仍可自动利用 ZFS 的底层功能。


创建卷

创建一个 10GB 的 ZFS 卷

zfs create -V 10G mypool/vol1

创建稀疏卷(Sparse Volume)

稀疏卷是 超分配 的卷,不会立即占用预留空间,而是随着数据的增长逐步填充。

创建一个 1PB(1 PB)稀疏卷

zfs create -V 1P -s mypool/sparse1PBvol

配额(Quota)

每个数据集默认可以使用整个存储池的空间。配额用于限制数据集的最大存储量。ZFS 严格 执行配额限制,任何超出配额的写入都会被阻止。


定义配额

ZFS 默认无配额。可使用 zfs set 命令为特定数据集设置配额:

zfs set quota=10G mypool/dataset

该配额适用于该数据集及其子数据集(包括未来创建的子数据集)。这些数据集 共享 配额总量。

如果仅想限制 父数据集本身,不影响子数据集,则使用 refquota

zfs set refquota=10G mypool/dataset

用户和组配额

  • 限制特定用户的存储空间

    zfs set userquota@fred=10G mypool/home/fred
  • 限制某个用户组的存储空间

    zfs set groupquota@projectX=100G mypool/projectX

显示配额信息

  • 查询数据集的配额

    zfs get quota mypool/dataset
  • 查询 refquota

    zfs get refquota mypool/home/fred
  • 查询用户配额

    zfs userspace mypool/home/fred
  • 查询组配额

    zfs groupspace mypool/projectX

移除配额

将数据集的配额取消(refquota 也同样适用):

zfs set quota=none mypool/home/fred

预留空间(Reservation)

预留(Reservation)确保存储池中一定量的空间始终可用,不受其他数据集占用。这减少了存储池的可用空间,但可以防止单个数据集占满整个池,有助于容量规划。

定义预留空间

使用 reservation 属性设置数据集的预留空间:

zfs set reservation=100G mypool/home

预留空间 会被子数据集继承。如果只想对该数据集本身生效,而不影响子数据集,则使用 refreservation

zfs set refreservation=10G mypool/home/eve

显示预留空间

  • 查看数据集的预留空间

    zfs get reservation mypool/home/eve
  • 查看 USEDREFRESERV 列中的预留空间

    zfs list -o space

移除预留空间

reservationrefreservation 设为 none

zfs set reservation=none mypool/home/eve

快照(Snapshots)

快照提供了一种 快速保存数据集只读状态 的方法,可用于恢复数据集到特定时间点的状态。无需回滚整个快照,也可以单独恢复其中的文件。

ZFS 通过 .zfs 目录提供只读访问,可从快照中读取文件。


创建快照

  • 创建快照

    zfs snapshot mypool/ds@mysnapshot
  • 简写命令

    zfs snap mypool/ds@mysnapshot
  • 递归创建快照(包含所有子数据集)

    zfs snap -r mypool/ds@mysnapshot

显示快照

  • 列出所有快照

    zfs list -t snap mypool/ds
  • 列出数据集及其所有子数据集的快照

    zfs list -rt snap mypool/ds

显示自上次快照以来的写入数据量

  • written 属性显示自上次快照以来写入的数据量。

  • 配合 usedreferenced 属性可以直观查看存储池空间使用情况:

zfs list -rt all -o name,used,refer,written mypool

比较快照

使用 zfs diff 比较当前数据集与某个快照之间的更改:

zfs diff mypool/ds@backup

输出说明

符号
说明

+

新增文件

-

删除文件

M

修改文件

R

重命名文件(应用于目录时表示元数据更改)

对比 两个快照 之间的更改:

zfs diff mypool/ds@backup1 mypool/ds@backup2

快照回滚(Snapshot Rollback)

回滚操作会 丢弃当前数据集的状态,恢复到指定快照的状态。所有在该快照之后创建的数据 都会被删除

zfs rollback mypool/ds@backup2

如果要回滚到更早的快照,必须先使用选项 -r 删除所有中间快照

zfs rollback -r mypool/ds@backup1

挂载快照(Snapshot Mounting)

可将快照 以只读方式 挂载到文件系统:

mount -t zfs mypool/ds@backup /mnt/backup

删除快照(Snapshot Deletion)

模拟删除(Dry Run)

建议先执行 模拟删除(选项 -n)查看即将删除的内容,配合 -v 显示详细信息:

zfs destroy -vn mypool/ds@backup

如果确认无误,去掉 -n 选项执行删除:

zfs destroy -v mypool/ds@backup

递归删除快照

删除指定快照及其所有子快照:

zfs destroy -rv mypool/ds@backup

删除快照范围(Delete Range)

假设快照列表如下:

mypool@a  
mypool@b  
mypool@c  
mypool@d  
mypool@e  
  • 删除快照 @b@d(含 @d

    zfs destroy -v mypool@b%d
  • 删除 @b 及其后所有快照

    zfs destroy -v mypool@b%
  • 删除 @b 及之前的所有快照

    zfs destroy -v mypool@%b

快照保护(ZFS Holds)

ZFS 能为快照创建 保护标记(tag),被标记的快照不能删除。可以对一个快照添加 多个 保护标记,只有 所有标记都被移除 后,快照才可以删除。

创建快照保护(Hold)

zfs hold keepme mypool/home@important

递归列出快照的所有 Holds

zfs holds -r mypool/home@important

解除快照保护(Release Hold)

zfs release keepme mypool/home@important

克隆(Clones)

克隆是 可写的快照副本,创建的克隆数据集 包含原快照的所有数据

创建克隆

zfs clone mypool/ds@backup mypool/myclone

克隆数据集的 origin 属性指向其 来源快照

zfs get origin mypool/myclone

解除克隆对原快照的依赖(Promote Clone)

ZFS 不允许删除 有依赖克隆的快照。要删除原快照,必须 先提升克隆为独立数据集promote):

zfs promote mypool/myclone

此时:

  • origin 属性消失

  • 该快照成为克隆的新基础

  • 原快照可安全删除

删除克隆(Clone Removal)

可像删除普通数据集一样删除克隆:

zfs destroy mypool/myclone

加密(Encryption)

ZFS 支持数据集加密,每个数据集可以有独立的密钥。一些元数据仍然保持未加密状态,以便执行 scrub 等操作。

创建加密数据集(Create Encrypted Dataset)

设置数据集的加密密码:

zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt mypool/secret

查看加密状态(Load Status)

获取密钥状态:

zfs get keystatus mypool/secret

加载密钥(Load Key)

解锁数据集:

zfs load-key mypool/secret

权限委派(Delegation)

ZFS 允许将 ZFS 命令的权限 委派给非 root 用户。

授权用户(Delegate Permission to User)

授予用户 joeatime 属性的修改权限:

zfs allow -u joe atime mypool/dataset

查看现有权限(Display Delegations)

zfs allow mypool/dataset

撤销用户权限(Remove Delegation)

移除 joecompression 权限:

zfs unallow -u joe compression mypool/dataset

授权给用户组(Delegate Permission to Group)

授予 mygroupatime 属性权限:

zfs allow -g mygroup atime mypool/dataset

允许用户委派权限(Delegate Permission to Delegate)

授予 jill 允许其他用户管理数据集权限的权限:

zfs allow -u jill allow mypool/dataset

创建权限集合(Create a Set of Permissions)

创建权限集合 @myset,包含 mountsnapshotrollbackdestroy 权限:

zfs allow -s @myset mount,snapshot,rollback,destroy mypool/dataset

应用权限集合(Use Permission Set for Delegations)

@myset 赋予用户 jill

zfs allow -u jill @myset mypool/dataset

快照发送与接收(Sending and Receiving Snapshots)

ZFS 能以字节流的方式 本地和通过网络传输快照,可用于备份。

将快照写入文件(Write Snapshot to a File)

zfs send mypool/ds@backup > dsbackup

要恢复快照,可使用 zfs receive,并通过 -v 选项显示详细信息:

zfs send -v mypool/ds@backup > target

从快照创建数据集(Create Dataset from Snapshot)

zfs recv mypool/backup < dsbackup

显示传输详细信息:

zfs recv -v mypool/backup < dsbackup

不使用中间文件进行复制(Replication Without Intermediary File)

直接通过管道传输快照数据:

zfs send mypool/ds@backup | zfs recv mypool/new

通过 SSH 复制(Replication via SSH)

使用 SSH 传输快照到另一台主机的 ZFS 池:

zfs send poolA/ds@backup | ssh host zfs recv poolB/new

权限管理(Send and Receive Permissions)

发送权限(Send Permissions)

允许 sender 用户发送数据集:

zfs allow -u sender send,snapshot mypool/source

接收权限(Receive Permissions)

接收方 receiver 需要额外的权限:

zfs allow -u receiver compression,mountpoint,mount,create,receive mypool/destination

最后更新于