快照和克隆
快照概述
快照(snapshot)是文件系统或卷的一个只读副本。创建快照几乎不花时间且最初不会占用磁盘空间。随着数据集的数据发生变化,快照会逐渐长大。
克隆(clone)是一个可写入的卷或文件系统,它的初始内容与被克隆的数据集相同。只能从快照创建克隆。
快照包括以下功能:
- 系统重启后快照依然存在
- 理论上的最大快照数是264个
- 快照不使用单独的后备存储。快照直接使用与创建它们的文件系统或卷相同的存储池中的磁盘空间
- 递归快照作为一个整体操作快速创建。这样快照数据总是在一个一致的时间创建。
不能直接访问卷的快照,但可以对其进行克隆、备份、回滚登操作。
top
创建和销毁快照
使用命令zfs snapshot或zfs snap创建快照,该命令的唯一参数是要创建的快照的名称。快照名称格式如下:
- filesystem@snapname
- volume@snapname
快照名称必须满足ZFS组件命名规则的要求。
以下示例创建system1/home/kaydo的快照,命名为friday:
$ zfs snapshot system1/home/kaydo@friday
使用-r选项为所有子文件系统创建快照:
$ zfs snapshot -r system1/home@snap1
$ zfs list -t snapshot -r system1/home
NAME USED AVAIL REFER MOUNTPOINT
system1/home@snap1 0 - 2.11G -
system1/home/kaydo@snap1 0 - 115M -
system1/home/glori@snap1 0 - 2.00G -
system1/home/hsolo@snap1 0 - 2.00G -
system1/home/cpark@snap1 0 - 57.3M -
快照没有可编辑的属性,任何数据集属性都无法应用到快照上。例如:
$ zfs set compression=on system1/home/kaydo@friday
cannot set property for 'system1/home/kaydo@friday':
this property can not be modified for snapshots
使用zfs destroy命令可以销毁快照。
$ zfs destroy system1/home/kaydo@friday
不能删除有快照的数据集。例如:
$ zfs destroy system1/home/kaydo
cannot destroy 'system1/home/kaydo': filesystem has children
use '-r' to destroy the following datasets:
system1/home/kaydo@tuesday
system1/home/kaydo@wednesday
system1/home/kaydo@thursday
另外,如果从快照创建了克隆,在销毁快照之前需要先销毁克隆。
top
保存快照
由于不同的自动快照或数据保留策略,较旧的快照有时会被无意中破坏。如果删除的快照是正在进行的ZFS发送和接收操作的一部分,则操作可能会失败。为避免此类情况,应考虑保留快照。
保留(holding)快照可以防止它被破坏。此外,此功能允许使用zfs destroy -d命令在删除最后一个克隆之前删除带有克隆的快照。
每个快照都有一个关联的用户引用计数(user-reference count),它的初始值为零。每当快照进行保留时,此计数会增加1,每当释放保留时,此计数会减少1。
在使用zfs destroy销毁快照时,快照的用户引用计数必须为零才能被销毁。
可以保留一个快照,或快照中的一部分。以下例子在保留目标system1/home/kaydo@snap1上放了一个保留标记keep:
$ zfs hold keep system1/home/kaydo@snap1
使用-r选项可以递归保留快照的所有子文件系统:
$ zfs snapshot -r system1/home@now
$ zfs hold -r keep system1/home@now
此语法向给定的快照或快照集添加了单个引用keep。每个快照都有自己的标签命名空间,并且保持标签在该空间内必须是唯一的。如果快照上存在保留,则尝试使用zfs destroy命令销毁该保留的快照将失败。例如:
$ zfs destroy system1/home/kaydo@snap1
cannot destroy 'system1/home/kaydo@snap1': dataset is busy
要销毁一个保留的快照,需要使用-d选项:
$ zfs destroy -d system1/home/kaydo@snap1
使用zfs holds命令可以显示保留的快照:
$ zfs holds system1/home@now
NAME TAG TIMESTAMP
system1/home@now keep Fri Aug 3 15:15:53 2012
$ zfs holds -r system1/home@now
NAME TAG TIMESTAMP
system1/home/kaydo@now keep Fri Aug 3 15:15:53 2012
system1/home/glori@now keep Fri Aug 3 15:15:53 2012
system1/home/hsolo@now keep Fri Aug 3 15:15:53 2012
system1/home/cpark@now keep Fri Aug 3 15:15:53 2012
system1/home@now keep Fri Aug 3 15:15:53 2012
使用zfs release命令释放保留:
$ zfs release -r keep system1/home@now
释放保留后就可以用zfs destroy命令销毁快照了:
$ zfs destroy -r system1/home@now
两个属性标识快照保留信息:
- destroyer属性
如果使用zfs destroy -d命令将快照标记为延迟销毁,此属性被设置on,否则被设置为off。
- userrefs属性
快照上的保留数字。
top
重命名ZFS快照
只能在创建快照的池和数据集中重命名快照。例如:
$ zfs rename system1/home/kaydo@snap1 system1/home/kaydo@today
也可以使用以下语法简化操作:
$ zfs rename system1/home/kaydo@snap1 today
以下操作不支持,因为目标池和文件系统名称跟源池和文件系统名称不同:
$ zfs rename system1/home/kaydo@today pool/home/kaydo@saturday
cannot rename to 'pool/home/kaydo@today': snapshots must be part of same
dataset
使用-r选项可以对所有子快照进行递归改名:
$ zfs list -t snapshot -r users/home
NAME USED AVAIL REFER MOUNTPOINT
users/home@now 23.5K - 35.5K -
users/home@yesterday 0 - 38K -
users/home/glori@yesterday 0 - 2.00G -
users/home/hsolo@yesterday 0 - 1.00G -
users/home/nneke@yesterday 0 - 2.00G -
$ zfs rename -r users/home@yesterday @2daysago
$ zfs list -t snapshot -r users/home
NAME USED AVAIL REFER MOUNTPOINT
users/home@now 23.5K - 35.5K -
users/home@2daysago 0 - 38K -
users/home/glori@2daysago 0 - 2.00G -
users/home/hsolo@2daysago 0 - 1.00G -
users/home/nneke@2daysago 0 - 2.00G -
top
显示和访问快照
默认情况下,使用zfs list命令时不会显示快照。必须使用zfs list -t snapshot命令来显示快照信息。
也可以启用池的listsnapshots属性。例如:
$ zpool get listsnapshots system1
NAME PROPERTY VALUE SOURCE
system1 listsnapshots off default
$ zpool set listsnapshots=on system1
$ zpool get listsnapshots system1
NAME PROPERTY VALUE SOURCE
system1 listsnapshots on local
文件系统的快照保存在文件系统根目录的.zfs/snapshot目录里面。
比如,如果system1/home/kaydo被挂载到/home/kaydo,则快照system1/home/kaydo@thursday会保存在/home/kaydo/.zfs/snapshot/thursday目录里。
$ ls /system1/home/kaydo/.zfs/snapshot
thursday tuesday wednesday
以下例子显示如何列出快照:
$ zfs list -t snapshot -r system1/home
NAME USED AVAIL REFER MOUNTPOINT
system1/home/kaydo@tuesday 45K - 2.11G -
system1/home/kaydo@wednesday 45K - 2.11G -
system1/home/kaydo@thursday 0 - 2.17G -
以下例子显示如何列出特定文件系统的快照:
$ zfs list -r -t snapshot -o name,creation system1/home
NAME CREATION
system1/home/kaydo@tuesday Fri Aug 3 15:18 2012
system1/home/kaydo@wednesday Fri Aug 3 15:19 2012
system1/home/kaydo@thursday Fri Aug 3 15:19 2012
system1/home/glori@today Fri Aug 3 15:24 2012
system1/home/hsolo@today Fri Aug 3 15:24 2012
top
ZFS快照的磁盘空间占用
创建快照时,其磁盘空间最初在快照和文件系统之间共享,也可能与以前的快照共享。随着文件系统的更改,以前共享的磁盘空间将称为快照的唯一空间,因此将计入快照的已用属性中。
此外,删除快照可能会增加其他快照特有的磁盘空间量。
快照的空间引用属性值与创建快照时文件系统的值相同。
可以识别有关如何使用used属性值的其他信息。新的只读文件系统属性描述克隆、文件系统和卷的磁盘空间使用情况。
$ zfs list -o space -r rpool
NAME AVAIL USED USEDSNAP USEDDS USEDREFRESERV USEDCHILD
rpool 124G 9.57G 0 302K 0 9.57G
rpool/ROOT 124G 3.38G 0 31K 0 3.38G
rpool/ROOT/solaris 124G 20.5K 0 0 0 20.5K
rpool/ROOT/solaris/var 124G 20.5K 0 20.5K 0 0
rpool/ROOT/solaris-1 124G 3.38G 66.3M 3.14G 0 184M
rpool/ROOT/solaris-1/var 124G 184M 49.9M 134M 0 0
rpool/VARSHARE 124G 39.5K 0 39.5K 0 0
rpool/dump 124G 4.12G 0 4.00G 129M 0
rpool/export 124G 63K 0 32K 0 31K
rpool/export/home 124G 31K 0 31K 0 0
rpool/swap 124G 2.06G 0 2.00G 64.7M 0
top
回滚ZFS快照
使用zfs diff命令可以识别ZFS快照差异。
例如,创建两个快照:
$ ls /system1/home/kaydo
fileA
$ zfs snapshot system1/home/cpark@snap1
$ ls /system1/home/kaydo
fileA fileB
$ zfs snapshot system1/home/cpark@snap2
识别这两个快照的差异:
$ zfs diff system1/home/cpark@snap1 system1/home/cpark@snap2
M /system1/home/kaydo/
+ /system1/home/kaydo/fileB
在输出的结果中,M标识被修改的目录,+标识failB存在于后面的快照。
下面输出结果中,R表明快照中被重命名的内容:
$ mv /system1/kaydo/fileB /system1/kaydo/fileC
$ zfs snapshot system1/kaydo@snap2
$ zfs diff system1/kaydo@snap1 system1/kaydo@snap2
M /system1/kaydo/
R /system1/kaydo/fileB -> /system1/kaydo/fileC
下表总结了zfs diff命令标识的文件或目录更改:
文件或目录的改变 |
标识 |
文件或目录被修改|文件或目录链接被修改 |
M |
文件或目录存在于较旧的快照中,但不存在于较新的快照中 |
-- |
文件或目录存在于较新的快照中,但不存在于较旧的快照中 |
+ |
文件或目录已经重命名 |
R |
如果使用zfs diff命令比较不同的快照,则会显示高级差异,例如新的文件系统或目录。
以下例子中,sales文件系统有两个子文件系统,每个子文件系统包含文件data和logs。
$ zfs list -r sales
NAME USED AVAIL REFER MOUNTPOINT
sales 1.75M 66.9G 33K /sales
sales/data 806K 66.9G 806K /sales/data
sales/logs 806K 66.9G 806K /sales/logs
比较的结果:
$ zfs diff sales@snap1 sales@snap2
M /sales/
+ /sales/logs
可以使用类似以下的语法递归识别快照差异:
$ zfs diff -r -E sales@snap1
D /sales/ (sales)
+ /sales/data
D /sales/data/ (sales/data)
+ /sales/data/dfile.1
+ /sales/data/dfile.2
+ /sales/data/dfile.3
$ zfs diff -r -E sales@snap2
D /sales/ (sales)
+ /sales/data
+ /sales/logs
D /sales/logs/ (sales/logs)
+ /sales/logs/lfile.1
+ /sales/logs/lfile.2
+ /sales/logs/lfile.3
D /sales/data/ (sales/data)
+ /sales/data/dfile.1
+ /sales/data/dfile.2
+ /sales/data/dfile.3
在输出结果中,已D开头并以(name)结尾的行标识文件系统(数据集)和挂载点。
top
ZFS克隆概述
克隆是一个可写卷或文件系统,其初始内容与从中创建克隆的数据集相同。
与快照一样,创建克隆几乎是即时的,并且最初不会占用额外的磁盘空间。此外,还可以对克隆进行快照。
克隆不会继承从中创建克隆的数据集的属性。使用zfs get和zfs set命令查看和改变克隆的数据集的属性。
由于克隆最初与原始快照共享所有磁盘空间,因此其已用属性值最初为零。对克隆进行更改时,它会占用更多磁盘空间。原始快照的used属性不包括克隆占用的磁盘空间。
top
创建ZFS克隆
使用zfs clone命令创建克隆,指定从中创建克隆的快照或数据集以及新文件系统或卷的名称,该名称可以位于ZFS层次结构中的任何位置。
新数据集的类型(例如,文件系统或卷)与从中创建克隆的快照的类型相同。不能在与原始文件系统快照所在的池不同的池中创建文件系统的克隆。
以下例子从快照system1/ws/gate@yesterday创建克隆system1/home/megra/bug123:
$ zfs snapshot system1/ws/gate@yesterday
$ zfs clone system1/ws/gate@yesterday system1/home/megra/bug123
以下例子从快照projects/newproject@today为临时用户创建克隆工作空间project/teamA/tempuser:
$ zfs snapshot projects/newproject@today
$ zfs clone projects/newproject@today projects/teamA/tempuser
$ zfs set share.nfs=on projects/teamA/tempuser
$ zfs set quota=5G projects/teamA/tempuser
top
销毁ZFS克隆
$ zfs destroy system1/home/megra/bug123
使用ZFS克隆替换ZFS文件系统
使用zfs promote命令可以用克隆的文件系统替换掉正在运行的ZFS文件系统。
$ zfs create system1/test
$ zfs create system1/test/productA
$ zfs snapshot system1/test/productA@today
$ zfs clone system1/test/productA@today system1/test/productAbeta
$ zfs list -r system1/test
NAME USED AVAIL REFER MOUNTPOINT
system1/test 104M 66.2G 23K /system1/test
system1/test/productA 104M 66.2G 104M /system1/test/productA
system1/test/productA@today 0 - 104M -
system1/test/productAbeta 0 66.2G 104M /system1/test/productAbeta
$ zfs promote system1/test/productAbeta
$ zfs list -r system1/test
NAME USED AVAIL REFER MOUNTPOINT
system1/test 104M 66.2G 24K /system1/test
system1/test/productA 0 66.2G 104M /system1/test/productA
system1/test/productAbeta 104M 66.2G 104M /system1/test/productAbeta
system1/test/productAbeta@today 0 - 104M -
top
保存、发送和接收ZFS数据
zfs send命令创建写入标准输出的快照的流表示形式。
默认情况下,生成完整的流。可以将输出重定向到一个文件或一个不同的系统。
zfs receive命令创建一个快照,其内容在标准输入提供的流中指定。
如果接收到一个完整的流,就会创建一个新的文件系统。
还可以发送ZFS快照数据并接收ZFS快照数据和文件系统。
在这个Oracle Solaris版本中,zfs send命令通过–w compress选项得到了增强。此选项使系统能够执行原始数据传输。在这种类型的传输中,压缩的数据块在源磁盘上按原样读取,在目标磁盘上按原样写入。操作过程中未发生解压再压缩。
此外,此版本还包括恢复传输ZFS数据的功能。特别是,由于网络中断或系统故障,大量ZFS数据的传输可能会中断。为了避免再次重新发送整个内容,可以使用-C选项来恢复发送zfs数据。
以下时用于保存ZFS数据的备份解决方案:
- 企业备份产品
提供以下功能:
- 文件系统快照和回滚快照
创建文件系统的副本,并在必要时恢复到以前的文件系统版本
- 保存快照
使用zfs send和zfs receive命令,可以在快照之间保存增量更改,但不能单独恢复文件。必须还原整个文件系统快照。
- 远程复制
将文件系统从一个系统复制到另一个系统。此过程不同于可能跨WAN镜像设备的传统卷管理产品。不需要特殊配置或硬件。
- 存档实用程序
比如tar|cpio|pax或第三方备份产品。tar|cpio可以传输NFSv4级别ACLs,但是pax不可以。
top
使用其他备份产品保存ZFS数据
除了使用zfs send和zfs receive命令以外,还可以使用存档实用程序(如tar和cpio命令)保存zfs文件。
ZFS快照流的类型
zfs send命令可以创建一个包含一个或多个快照的流。然后,可以使用zfs receive命令重建文件系统或卷。
用于创建快照流的zfs send选项确定生成的流格式类型。
- 完整流(默认)
包含从创建数据集到指定快照的所有数据集内容
它包含一个文件系统或卷,最多包含指定的快照。该流不包含命令中指定的快照以外的快照。
- 增量流
由一个快照和另一个快照之间的差异组成
流包是包含一个或多个完整或增量流的流类型,流包的类型包括:
- 复制流包
由指定的数据集以其子体组成。包括所有中间快照。要接收流,源数据集必须存在于目标存储池中。
假设以下数据集及其来源列表是按照它们出现的顺序创建的:
NAME ORIGIN
pool/a -
pool/a/1 -
pool/a/1@clone -
pool/b -
pool/b/1 pool/a/1@clone
pool/b/1@clone2 -
pool/b/2 pool/b/1@clone2
pool/b@pre-send -
pool/b/1@pre-send -
pool/b/2@pre-send -
pool/b@send -
pool/b/1@send -
pool/b/2@send -
假设使用以下语法创建了复制流包:
$ zfs send -R pool/b@send ...
这个包将包含以下完整和增量流:
TYPE SNAPSHOT INCREMENTAL FROM
full pool/b@pre-send -
incr pool/b@send pool/b@pre-send
incr pool/b/1@clone2 pool/a/1@clone
incr pool/b/1@pre-send pool/b/1@clone2
incr pool/b/1@send pool/b/1@send
incr pool/b/2@pre-send pool/b/1@clone2
incr pool/b/2@send pool/b/2@pre-send
输出中,pool/a/1@clone快照没有包含在复制流包中。因此,只能在已具有pool/a/1@clone快照的池中接收复制流包。
- 自包含(self-contained)复制流包
这种类型的包不依赖于流包中未包含的任何数据集。可以使用与以下示例类似的语法创建复制流包:
$ zfs send -Rc pool/b@send...
示例包将包含以下完整和增量流:
TYPE SNAPSHOT INCREMENTAL FROM
full pool/b@pre-send -
full pool/b/1@clone2 -
incr pool/b@send pool/b@pre-send
incr pool/b/1@pre-send pool/b/1@clone2
incr pool/b/1@send pool/b/1@send
incr pool/b/2@pre-send pool/b/1@clone2
incr pool/b/2@send pool/b/2@pre-send
与非自包含复制流相比,应注意,此自包含复制流具有完整的pool/b/1@clone2快照。
此快照是一个集成的数据集,其克隆源位作为数据合并到其中;clone2不再是具有独立来源的完整克隆。这使得接收pool/b/1快照时没有外部依赖项成为可能。
- 递归流包
由指定的数据集及其子体组成。
- 自包含递归流包
这种类型的包不依赖于流包中未包含的任何数据集。
top
发送一个ZFS快照
使用zfs send命令发送快照流的副本,并在同一个系统上的另一个池或用于存储备份数据的不同系统上的另一个池中接收快照流。
例如:
$ zfs send pool/diant@snap1 | zfs recv spool/ds01
以上,zfs recv是zfs receive的简写。
如果要将快照流发送到不同的系统,使用ssh命令重定向zfs send的输出:
sys1$ zfs send pool/diant@snap1 | ssh sys2 zfs recv pool/hsolo
发送完整流时,目标文件系统不能存在。
如果需要存储多个副本,应考虑使用gzip命令压缩ZFS快照流。例如:
$ zfs send pool/fs@snap | gzip | backupfile.gz
例40 发送增量ZFS数据
使用zfs send -i命令可以发送增量数据。
sys1$ zfs send -i pool/diant@snap1 system1/diant@snap2 | ssh system2 zfs recv pool/hsolo
第一个变量(snap1)是较早的快照,第二个变量(snap2)是最后的快照。此例中,pool/hsolo文件系统必须已经存在以成功接收增量数据。
如果两个变量属于同一个文件系统,则只需要指定第二个变量的完整名称,例如:
sys1$ zfs send -i snap1 pool/diant@snap2 | ssh system2 zfs recv pool/hsolo
如果尝试从不同的文件系统snapshot1生成增量流,将会显示以下消息:
cannot send 'pool/fs@name': not an earlier snapshot from the
访问原始接收文件系统中的文件信息可能导致增量快照接收操作失败,并显示以下消息:
cannot receive incremental stream of pool/diant@snap2 into pool/hsolo:
most recent snapshot of pool/diant@snap2 does not match incremental source
如果需要访问原始接收的文件系统中的文件信息,并且还需要接收到的文件系统中的增量快照,可以考虑将atime属性设置为off。
如果需要存储多个副本,可考虑使用gzip命令压缩ZFS快照流:
$ zfs send pool/fs@snap | gzip > backupfile.gz
例41 使用原始传输发送ZFS数据
使用选项-w compress发送原始模式传输。
首先创建文件系统pool/compressed-fs:
$ zfs create -o compression=gzip-6 pool/compressed-fs
$ cp /usr/dict/words /pool/compressed-fs/
下一步创建快照并检查压缩比。出于比较目的,创建两个流以查看常规传输和原始传输中间的大小差异,注意,rawstream文件较小。
$ zfs snapshot pool/compressed-fs@snap
$ zfs get compressratio pool/compressed-fs@snap
NAME PROPERTY VALUE SOURCE
pool/compressed-fs@snap compressratio 2.80x -
$ zfs send pool/compressed-fs@snap > /tmp/stream
$ zfs send -w compress pool/compressed-fs@snap > /tmp/rawstream
$ ls -lh /tmp/*stream
-rw-r--r-- 1 root root 100K Dec 23 18:23 /tmp/rawstream
-rw-r--r-- 1 root root 304K Dec 23 18:23 /tmp/stream
下一步,在新位置接收原始传输流。要验证内容是否相同,将新文件系统与原始文件系统进行比较:
$ zfs receive pool/rawrecv < /tmp/rawstream
$ diff -r /pool/compressed-fs/ /pool/rawrecv/
例42 从Oracle Solaris 11.4.0数据集发送ZFS数据
默认情况下,可以在输出数据流中使用每记录校验和。要将数据传输到较旧的系统,必须使用nocheck禁用此功能。
$ zfs send -s nocheck pool/diant@snap1 | zfs recv pool/ds01
top
使用可恢复复制
使用zfs receive传输数据如果被中断,可以重新处理。
system1$ zfs send pool/diant@snap1 | ssh system2 zfs recv pool/hsolo
如果传输被中断,则数据集将不完整。可以使用以下一些列命令恢复传输:
system1$ ssh system2 zfs receive -C pool/hsolo | \
zfs send -C pool/diant@snap1 | \
ssh system2 zfs receive pool/hsolo
使用zfs list -I命令可以查看哪个数据集不完整。
top
接收ZFS快照
接收文件系统快照的注意事项:
- 快照和文件系统都被接收了
- 将卸载文件系统和所有子文件系统
- 文件系统在接收时无法访问
- 目标系统上不得存在与要接收的源文件系统同名的文件系统
例如:
$ zfs send system1/gozer@0830 > /bkups/gozer.083006
$ zfs receive system1/gozer2@today < /bkups/gozer.083006
$ zfs rename system1/gozer system1/gozer.old
$ zfs rename system1/gozer2 system1/gozer
如果对目标文件系统进行了更改,并且希望执行快照的另一次增量发送,则必须首先回滚接收文件系统。
下面例子,首先对文件系统进行修改:
sys2$ rm newsys/hsolo/file.1
然后执行system1/diant@snap3的增量发送。注意,必须先回滚接收文件系统以接收新的增量快照。或使用-F选项取消回滚步骤:
sys1$ zfs send -i system1/diant@snap2 system1/diant@snap3 | ssh sys2 zfs recv -F newsys/hsolo
当接收增量快照时,目标文件系统必须已经存在。
如果没有回滚,也没有使用-F选项,则会出现错误提示:
sys1$ zfs send -i system1/diant@snap4 system1/diant@snap5 | ssh sys2 zfs recv newsys/hsolo
cannot receive: distination has been modified since most recent snapshot
在-F选项成功之前,将执行以下检查:
top
将不同的属性值应用于ZFS快照流
可以发送具有特定文件系统属性值的ZFS快照流,然后在接收快照流时指定不同的本地属性值,或者指定在接收快照流时使用原始属性值来重新创建原始文件系统。
此外,可以在收到快照流时禁用文件系统属性。
top
保留原始属性值
在某些情况下,发送流中的文件系统属性可能不适用于接收文件系统,或者本地文件系统属性(如mountpoint属性值)可能会干扰恢复。
例如,假设system1/data文件系统禁用了compression(压缩)属性。system1/data文件系统的快照和属性(-p选项)一起发送到备份池,并在启用compression属性的情况下接收:
$ zfs get compression system1/data
NAME PROPERTY VALUE SOURCE
system1/data compression off default
$ zfs snapshot system1/data@snap1
$ zfs send -p system1/data@snap1 | zfs recv -o compression=on -d bpool
$ zfs get -o all compression bpool/data
NAME PROPERTY VALUE RECEIVED SOURCE
bpool/data compression on off local
此例中,当bpool池接收快照后启用了compressino属性。所以,对于bpool/data,compression属性值是on。
如果出于恢复目的将此快照流发送到新池restorepool,则可能需要保留所有原始快照属性。这种情况下,可以适用zfs send -b选项恢复原始快照属性。例如:
$ zfs send -b bpool/data@snap1 | zfs recv -d restorepool
$ zfs get -o all compression restorepool/data
NAME PROPERTY VALUE RECEIVED SOURCE
restorepool/data compression off off received
top
禁用原始属性值
如果快照流中有本地文件系统属性值,并且希望在收到该属性时禁用该属性,可适用zfs receive -x选项。
例如,以下命令发送主目录文件系统的递归快照流,其中所有文件系统属性保留给备份池,但没有配额属性值:
$ zfs send -R system1/home@snap1 | zfs recv -x quota bpool/home
$ zfs get -r quota bpool/home
NAME PROPERTY VALUE SOURCE
bpool/home quota none local
bpool/home@snap1 quota - -
bpool/home/glori quota none default
bpool/home/glori@snap1 quota - -
bpool/home/hsolo quota none default
bpool/home/hsolo@snap1 quota - -
如果没有使用-x选项接收递归快照,则将在接收的文件系统中设置配额属性:
$ zfs send -R system1/home@snap1 | zfs recv bpool/home
$ zfs get -r quota bpool/home
NAME PROPERTY VALUE SOURCE
bpool/home quota none received
bpool/home@snap1 quota - -
bpool/home/glori quota 10G received
bpool/home/glori@snap1 quota - -
bpool/home/hsolo quota 10G received
bpool/home/hsolo@snap1 quota - -
top
发送和接收复杂的ZFS快照流
这一节介绍在zfs send命令中使用-I|-R选项来发送和接收更复杂的快照流。
发送和接收复杂的ZFS快照流时,应注意:
- 使用-I选项可以将所有增量流从一个快照发送到累积快照。
还可以从原始快照发送增量流以创建克隆。
原始快照必须存在于接收端才能接收增量流。
- 使用-R选项可以发送所有子代文件系统的复制流。
接收到复制流时,将保留所有属性、快照、子代文件系统和克隆。
- 使用不包含-c选项的zfs send -r或zfs send -R命令发送包流的话,在某些情况下会忽略克隆的origin(来源)。
- 同时使用这两个选项发送增量复制流
- 将保留对属性的更改,以及快照和文件系统rename和destroy操作
- 当接收复制流时未指定-F选项,数据集的destroy操作会被忽略。因此,如果有必要,可以撤销接收操作并将文件系统恢复到以前的状态。
- 当发送增量流时,如果使用-I选项,则会发送snapA和snapD之间的所有快照,如果使用-i,则仅发送快照snapD(对于所有子体)。
要接收这些类型的zfs send流,接收系统必须运行能够发送它们的软件版本。流版本将递增。
例43 发送和接收复杂的ZFS快照流
可以使用-I选项将一组增量快照组合到一个快照中,例如:
$ zfs send -I pool/fs@snapA pool/fs@snapD > /snap/fs@all-I
然后可以删除增量快照snapB、snapC、snapD。
$ zfs destroy pool/fs@snapB
$ zfs destroy pool/fs@snapC
$ zfs destroy pool/fs@snapD
使用以下命令接收组合的快照:
$ zfs receive -d -F pool/fs < /snaps/fs@all-I
$ zfs list
NAME USED AVAIL REFER MOUNTPOINT
pool 428K 16.5G 20K /pool
pool/fs 71K 16.5G 21K /pool/fs
pool/fs@snapA 16K - 18.5K -
pool/fs@snapB 17K - 20K -
pool/fs@snapC 17K - 20.5K -
pool/fs@snapD 0 - 21K -
也可以使用-I组合一个快照和一个克隆快照以建立一个组合数据集,例如:
$ zfs create pool/fs
$ zfs snapshot pool/fs@snap1
$ zfs clone pool/fs@snap1 pool/clone
$ zfs snapshot pool/clone@snapA
$ zfs send -I pool/fs@snap1 pool/clone@snapA > /snaps/fsclonesnap-I
$ zfs destroy pool/clone@snapA
$ zfs destroy pool/clone
$ zfs receive -F pool/clone < /snaps/fsclonesnap-I
要将ZFS文件系统和所有子代文件系统复制到命名的快照,可以使用-R选项。收到此流时,所有属性、快照、子代文件系统和克隆都将保留。
以下示例为用户文件系统创建快照。为所有用户快照创建一个复制流。然后销毁并恢复原始文件系统和快照。
$ zfs snapshot -r users@today
$ zfs list
NAME USED AVAIL REFER MOUNTPOINT
users 187K 33.2G 22K /users
users@today 0 - 22K -
users/user1 18K 33.2G 18K /users/user1
users/user1@today 0 - 18K -
users/user2 18K 33.2G 18K /users/user2
users/user2@today 0 - 18K -
users/user3 18K 33.2G 18K /users/user3
users/user3@today 0 - 18K -
$ zfs send -R users@today > /snaps/users-R
$ zfs destroy -r users
$ zfs receive -F -d users < /snaps/users-R
$ zfs list
NAME USED AVAIL REFER MOUNTPOINT
users 196K 33.2G 22K /users
users@today 0 - 22K -
users/user1 18K 33.2G 18K /users/user1
users/user1@today 0 - 18K -
users/user2 18K 33.2G 18K /users/user2
users/user2@today 0 - 18K -
users/user3 18K 33.2G 18K /users/user3
users/user3@today 0 - 18K -
以下例子使用-R选项替代users文件系统及其子系统,然后发送复制流到另一个池users2。
$ zfs create users2 mirror c0t1d0 c1t1d0
$ zfs receive -F -d users2 < /snaps/users-R
$ zfs list
NAME USED AVAIL REFER MOUNTPOINT
users 224K 33.2G 22K /users
users@today 0 - 22K -
users/user1 33K 33.2G 18K /users/user1
users/user1@today 15K - 18K -
users/user2 18K 33.2G 18K /users/user2
users/user2@today 0 - 18K -
users/user3 18K 33.2G 18K /users/user3
users/user3@today 0 - 18K -
users2 188K 16.5G 22K /users2
users2@today 0 - 22K -
users2/user1 18K 16.5G 18K /users2/user1
users2/user1@today 0 - 18K -
users2/user2 18K 16.5G 18K /users2/user2
users2/user2@today 0 - 18K -
users2/user3 18K 16.5G 18K /users2/user3
users2/user3@today 0 - 18K -
top
ZFS数据的远程复制
使用zfs send和zfs recv命令可以将快照流从一个系统远程复制到另一个系统。
$ zfs seng system1/kaydo@today | ssh newsys zfs recv sandbox/restfs@today
以上操作将system1/kaydo@today快照数据发送到sandbox/restfs文件系统。此命令还在newsys系统创建一个restfs@today快照。
此例中,用户配置了使用远程系统的ssh。
top
监控ZFS池操作
发出ZFS命令启动后台任务以在数据上运行诸如发送(sending)、接收(receiving)、清理(scrubbing)、调整数据大小(resilvering data)等操作时,可以实时监视这些任务的状态和进度。
可以指定显示信息的频率,还可以指定监视多长时间。
监控池操作的命令是zpool monitor。(FreeBSD没有此命令)
- 开始时间
- 当前数据量
- 时间戳,如果适用,以每个功能为基础
- 任务开始时的数据量(如果适用)
可以显示有关单个池或系统上所有现有池中任务的信息。
zpool monitor的使用方法如下:
zpool monitor -t provider [-T d|u] [pool] [interval [count]]
- -t provider
指定显示任务信息的以下提供程序之一:
- send
- receive或则recv
- scrub
- resilver
- -T d|u
指定时间戳及其显示格式。d表示标准日期格式;u表示内部表示形式的打印表示形式。
- interval
显示信息更新的速率,以秒为单位。
- count
命令在指定间隔内显示任务相关信息的次数。
如果指定了count,命令将在指定的次数后停止。如果没有指定,命令会一直执行,直到按下Ctrl-C。
另外,使用zpool命令的–o选项,可以过滤要包含在命令输出中的显示字段;–p选项,可以以机器可解析格式显示信息。
命令输出根据特定字段排列信息:
- DONE
自zpool monitor命令发出以来已处理的数据量。
- OTHER
其他信息取决于指定的提供程序,例如正在处理的当前项或任务的当前状态。
- PCTDONE
已处理数据的百分比。
- POOL
从中检索信息的池。
- PROVIDER
提供信息的任务。
- SPEED
单位/秒,通常为字节,但取决于提供程序使用的单位。
- STRTTIME
提供程序在显示的任务上启动的时间。
- TAG
区分整个操作。标记值在任何时候都是唯一的,但值可以在后续操作中重用。例如,即使两个任务在同一个数据集上操作,两个同时进行的发送操作也会有不同的标记值。
- TIMELEFT
完成特定任务的相对时间。
- TIMESTMP
快照受监视数据的时间。
- TOTAL
估计要处理的数据总量。
例44 监视ZFS快照流
zfs send命令创建一个快照流。以下例子显示如何获取有关此任务的信息。信息将在5秒内更新两次:
$ zpool monitor -t send 5 2
POOL PROVIDER PCTDONE TOTAL SPEED TIMELEFT OTHER
poolA send 41.7 10.0G 5.93M 16m49s poolA/fs:1/team3@all
poolB send 53.9 10.0G 7.71M 10m13s poolB/fs1/team3@all
poolC send 97.9 10.0G 14.4M 14s poolC/fs1/team1@all
poolA send 43.5 10.0G 6.17M 15m40s poolA/fs:1/team3@all
poolB send 55.8 10.0G 7.95M 9m30s poolB/fs1/team3@all
poolC send 99.2 10.0G 14.5M 5s poolC/fs1/team1@all
例45 监视流的接收
此示例显示如何监视接收操作的状态和进度。在没有指定计数的情况下,信息每5秒持续更新一次。管理员按下Ctrl-C时,监视结束。
$ zpool monitor -t recv 5
pool provider pctdone total speed timeleft other
poolA receive 34.0 12.0G 6.01M 22m31s poolA/backup_all/fs2
poolA receive 68.0 6.01G 6.01M 5m28s poolA/backup_fs:1
poolB receive 20.6 10.0G 3.04M 44m39s poolB/backup_all/fs2
poolB receive 100.0 6.01G 9.48M 1s poolB/backup_fs1
poolB receive 16.7 12.0G 4.16M 41m04s poolB/pA-bkup/fs2
poolC receive 26.2 10.0G 3.98M 31m41s poolC/backup_all/fs2
^C
例46 监视重定位操作
此示例显示如何检查系统上所有三个ZFS池上的resilvering操作的状态。
$ zpool monitor -t resilver 5 4
pool provider pctdone total speed timeleft other
poolA resilver 10.7 12.0G 37.7M 4m50s (2/2)
poolB resilver 7.1 10.0G 31.5M 5m02s (2/2)
poolC resilver 1.8 10.0G 42.9M 3m54s (2/2)
poolA resilver 13.9 12.0G 38.0M 4m38s (2/2)
poolB resilver 9.0 10.0G 30.4M 5m07s (2/2)
poolC resilver 5.3 10.0G 41.7M 3m52s (2/2)
poolA resilver 14.7 12.0G 36.1M 4m50s (2/2)
poolB resilver 10.8 10.0G 29.2M 5m12s (2/2)
poolC resilver 7.2 10.0G 41.0M 3m51s (2/2)
poolA resilver 14.7 12.0G 32.8M 5m19s (2/2)
poolB resilver 10.8 10.0G 29.6M 5m08s (2/2)
poolC resilver 7.2 10.0G 40.7M 3m53s (2/2)
例47 监视擦洗操作
此示例显示如何监视poolB上的清理操作的进度。
$ zpool monitor -t scrub 5 poolB
pool provider pctdone total speed timeleft
poolB scrub 16.3 14.0G 35.3M 5m39s
poolB scrub 16.4 14.0G 33.2M 6m00s
poolB scrub 16.5 14.0G 31.1M 6m25s
poolB scrub 16.5 14.0G 29.3M 6m48s
^C
top
复制ZFS文件
使用cp -z命令可以快速复制大文件。
-z选项复制于每个记录关联的元数据,而不是复制元数据和所有数据。
对于记录大小为4K或更大的文件,此方法比使用标准的cp命令快得多。
FreeBSD的cp命令没有-z选项。
top
2021/12/27 & 28