zfs 速查手册
原文链接:OpenZFS Cheat Sheet
作者:Benedict Reuschling ([email protected])
原发布时间:2025 年 3 月
存储池配置
单个磁盘
无冗余,挂载为 /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
移除预留空间
将 reservation
或 refreservation
设为 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
属性显示自上次快照以来写入的数据量。配合
used
和referenced
属性可以直观查看存储池空间使用情况:
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)
授予用户 joe
对 atime
属性的修改权限:
zfs allow -u joe atime mypool/dataset
查看现有权限(Display Delegations)
zfs allow mypool/dataset
撤销用户权限(Remove Delegation)
移除 joe
的 compression
权限:
zfs unallow -u joe compression mypool/dataset
授权给用户组(Delegate Permission to Group)
授予 mygroup
组 atime
属性权限:
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
,包含 mount
、snapshot
、rollback
和 destroy
权限:
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
最后更新于