ZFS系列(十四)获取设置ZFS数据集属性

本文介绍如何ZFS文件系统(或者叫ZFS数据集)的各种属性。

动机

与Zpool属性一样,数据集也包含可以更改的属性。因为数据集是实际存储数据的地方,所以有比存储池多得多的属性。此外,属性可以从父数据集继承。同样,并不是每个属性都是可调的。许多是只读的。但是,这再次使我们能够根据存储需求优化文件系统。ZFS数据集的另一个方面是能够设置您自己的自定义属性。这些属性被称为“用户属性”,不同于“native 属性”。

因为有太多的属性,所以我决定把管理放在“显眼的地方”,并把属性和一些最后的想法放在文章的最后。

获取并设置属性

与获取和设置存储池属性一样,也有一些方法可以获取数据集属性——您可以一次获取所有属性,只获取一个属性,或多个属性,以逗号分隔。例如,假设我只想获得数据集的压缩比。可以用以下命令:

1
2
3
# zfs get compressratio tank/test
NAME PROPERTY VALUE SOURCE
tank/test compressratio 1.00x -

如果想要获得多个设置,比如数据集使用的磁盘数量,以及可用磁盘的数量,以及压缩比,可以用以下命令:

1
2
3
4
# zfs get used,available,compressratio tank/test
tank/test used 1.00G -
tank/test available 975M -
tank/test compressratio 1.00x -

当然,如果想获得所有可用的设置,可以运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# zfs get all tank/test
NAME PROPERTY VALUE SOURCE
tank/test type filesystem -
tank/test creation Tue Jan 1 6:07 2013 -
tank/test used 1.00G -
tank/test available 975M -
tank/test referenced 1.00G -
tank/test compressratio 1.00x -
tank/test mounted yes -
tank/test quota none default
tank/test reservation none default
tank/test recordsize 128K default
tank/test mountpoint /tank/test default
tank/test sharenfs off default
tank/test checksum on default
tank/test compression lzjb inherited from tank
tank/test atime on default
tank/test devices on default
tank/test exec on default
tank/test setuid on default
tank/test readonly off default
tank/test zoned off default
tank/test snapdir hidden default
tank/test aclinherit restricted default
tank/test canmount on default
tank/test xattr on default
tank/test copies 1 default
tank/test version 5 -
tank/test utf8only off -
tank/test normalization none -
tank/test casesensitivity sensitive -
tank/test vscan off default
tank/test nbmand off default
tank/test sharesmb off default
tank/test refquota none default
tank/test refreservation none default
tank/test primarycache all default
tank/test secondarycache all default
tank/test usedbysnapshots 0 -
tank/test usedbydataset 1.00G -
tank/test usedbychildren 0 -
tank/test usedbyrefreservation 0 -
tank/test logbias latency default
tank/test dedup off default
tank/test mlslabel none default
tank/test sync standard default
tank/test refcompressratio 1.00x -
tank/test written 0 -

继承属性

正如您可能在上面的输出中注意到的,属性可以从它们的父类继承。在这种情况下,我将存储池文件系统“tank”上的压缩算法设置为“lzjb”(“tank”不仅仅是一个存储池—它是一个有效的ZFS数据集)。因此,在“tank”数据集下创建的任何数据集都将继承该属性。让我们创建一个嵌套数据集,看看它是如何发挥作用的:

1
2
3
4
5
6
# zfs create -o compression=gzip tank/test/one
# zfs get -r compression tank
NAME PROPERTY VALUE SOURCE
tank compression lzjb local
tank/test compression lzjb inherited from tank
tank/test/one compression gzip local

注意,”tank”和”tank/test”数据集使用”lzjb”压缩算法,其中”tank/test”从它的父”tank”继承了它。而对于“tank/test/one”数据集,我们选择了不同的压缩算法。现在让我们从”tank”继承父压缩算法,看看”tank/test/one”会发生什么:

1
2
3
4
5
6
# zfs inherit compression tank/test/one
# zfs get -r compression tank
NAME PROPERTY VALUE SOURCE
tank compression lzjb local
tank/test compression lzjb inherited from tank
tank/test/one compression lzjb inherited from tank

现在“zfs inherit”命令也支持递归。我可以将”tank”数据集设置为”gzip”,并递归地应用该属性到所有的子数据集:

1
2
3
4
5
6
7
# zfs set compression=gzip tank
# zfs inherit -r compression tank/test
# zfs get -r compression tank
NAME PROPERTY VALUE SOURCE
tank compression gzip local
tank/test compression gzip inherited from tank
tank/test/one compression gzip inherited from tank

使用“-r”开关时要非常小心。假设你快速输入命令,并给出“tank”数据集作为参数,而不是“tank/test”:

1
2
3
4
5
6
# zfs inherit -r compression tank
# zfs get -r compression tank
NAME PROPERTY VALUE SOURCE
tank compression off default
tank/test compression off default
tank/test/one compression off default

发生了什么事?所有的压缩算法都被重置为默认值“off”。因此,使用“zfs inherit”命令的“-r”递归参数要非常小心,因为这会使数据集的参数都变成默认值,并且递归应用到其所有的子数据集,并且不仅适用于数据集,还包括卷和快照。

用户数据集属性

了解了继承之后,就可以理解如何在数据集中设置自定义用户属性了。用户属性的目标是为特定的ZFS应用程序设计的,以利用这些设置。例如,poudriere是FreeBSD的一个工具,用于测试包的生产,并批量构建FreeBSD包。如果使用ZFS与FreeBSD,你可以为poudriere创建一个数据集,然后为它创建一些自定义属性。
自定义用户数据集属性对ZFS性能没有影响。将它们仅仅看作管理员和开发人员的“注释”。用户属性必须在属性名中使用冒号”:”以区别于native数据集属性。只能包含小写字母、数字、“:”、“-”、“。”和“_”。它们最多可以是256个字符,并且不能以破折号“-”开头。

要创建自定义属性,只需使用“module:property”语法。这不是ZFS强制执行的,但可能是最简洁明了的方法:

1
2
3
4
5
# zfs set poudriere:type=ports tank/test/one
# zfs set poudriere:name=my_ports_tree tank/test/one
# zfs get all tank/test/one | grep poudriere
tank/test/one poudriere:name my_ports_tree local
tank/test/one poudriere:type ports local

我不知道从ZFS文件系统中删除用户属性的方法。因此,如果它困扰您,并使您的属性列表变得混乱,那么删除用户属性的唯一方法是使用您想要的属性创建另一个数据集,复制数据,然后销毁旧的杂乱的数据集。当然,您也可以使用“zfs inherit”继承用户属性。

说了这么多,让我们来看看原生属性。

ZFS原生数据集属性

  • aclinherit:控制在创建文件和目录时如何继承ACL项。目前,从0.6.0-rc13版本开始,acl在Linux上的ZFS中不起作用。默认设置是“限制”。此属性的有效值为:
    (1)discard:不继承任何ACL属性
    (2)noallow:仅继承指定“deny”权限的ACL项
    (3)restricted:当继承ACL条目时,去掉“write_acl”和“write_owner”权限
    (4)passthrough:继承所有可继承的ACL表项,不做任何修改
    (5)passthrough-x:含义与passthrough相同,不过只有在文件创建模式也要求执行位的情况下,owner@, group@, and everyone@ ACE才会继承执行权限
  • aclmode:使用“chmod”命令控制如何修改ACL。”groupmask”为默认值,用于减少用户或组的权限。权限被减少,因此它们不大于组权限位,除非它是与文件或目录的所有者具有相同UID的用户条目。有效值为“discard”、“groupmask”和“passthrough”。
  • acltype:控制是否启用ACL以及如果启用,将使用何种类型的ACL。当文件系统将acltype属性设置为noacl(默认值)时,将禁用acl。将acltype属性设置为posixacl表示使用Posix ACLs。Posix ACLs是特定于Linux的,在其他平台上不起作用。Posix ACLs存储为xattr,因此不会覆盖任何可能设置的现有ZFS/NFSv4 ACLs。目前Linux只支持posixacls。
  • atime:控制在读取文件时是否更新文件的访问时间。默认是“on”。有效值为“on”和“off”。
  • available:只读属性,显示该数据集及其所有子数据集的可用空间,假设池上没有其他活动。可以通过它的缩写名“avail”来引用。可用性可能受到许多因素的限制,包括存储池中的物理空间、配额、保留和池中的其他数据集。
  • canmount:当使用“zfs mount”命令时,控制文件系统是否能够被挂载。默认是“on”。有效值为“on”、“off”或“noauto”。当设置了noauto选项时,数据集只能显式地挂载和卸载。当创建或导入数据集时,数据集不会自动挂载,也不会通过“zfs mount”命令挂载或通过“zfs unmount”命令卸载。此属性不会被继承。
  • casesensitivity:指定文件系统使用的文件名匹配算法是区分大小写、不区分大小写还是允许两种匹配方式的组合。默认值为“sensitive”。取值为“sensitive”、“insensitive”和“mixed”。在部署Unix POSIX和CIFS文件名的异构环境中,使用“mixed”值将是有益的。只能在创建数据集时设置。
  • checksum: 控制用于验证数据完整性的checksum。默认值是on,它会自动选择合适的算法。目前,该算法是“fletcher2”。合法取值为on、off、fletcher2、fletcher4或sha256。更改此属性只会影响新写入的数据,并且不会追溯应用。
  • clones:快照数据集只读属性。以逗号分隔的列表展示此快照的克隆数据集。如果该属性不为空,则不能销毁该快照(即使使用”-r”或”-f”选项也不能),需要先销毁克隆。
  • compression:控制此数据集的压缩算法。默认设置是“关闭”。有效值为on、off、lzjb、gzip、gzip- n、zle。“lzjb”算法为速度进行了优化,同时提供了良好的压缩比。“on”的设置默认为“lzjb”。建议您使用“lzjb”、“gzip”、“gzip-N”或“zle”而不是“on”,因为ZFS开发人员或包维护人员可能会更改“on”使用的算法。gzip压缩算法使用与“gzip”命令相同的压缩。您可以使用“gzip-N”指定gzip级别,其中“N”是1到9的有效数字。“zle”压缩的速度非常快。更改此属性只会影响新写入的数据,并且不会追溯应用。
  • compressratio:只读属性,显示在“compression”属性上设置的压缩算法所实现的压缩比。用乘数表示。不考虑快照;看到“refcompressratio”。默认情况下不启用压缩。
  • copies:控制要存储在此数据集中的副本数量。默认值为1。取值为1、2、3。这些副本是在池提供的任何冗余之外的。如果可能,副本存储在不同的磁盘上。多个副本所使用的空间将由关联的文件和数据集承担。更改此属性只会影响新写入的数据,并不能追溯应用。
  • creation:只读属性,显示创建数据集的时间。
  • defer_destroy:快照只读属性。如果使用”zfs destroy -d”命令将快照标记为延迟销毁,则此属性为”on”,否则,属性为“off”。
  • dedup:控制数据去重是否对该数据集有效。默认设置是“关闭”。取值为off、on、verify、sha256[,verify]。数据去重的校验和默认为SHA256。当启用“dedup”属性时,它将覆盖“checksum”属性。如果属性设置为“verify”,那么如果两个块具有相同的校验和,ZFS将逐个字节地与现有块进行比较,以确保两个块是相同的。更改此属性只会影响新写入的数据。在数据集中启用重复数据删除功能,将对存储池中的所有数据进行重复数据删除。
  • devices: 控制是否可以在此文件系统上打开设备节点。默认值为“on”。有效值为“on”和“off”。
  • exec:控制进程是否可以从该文件系统中执行。默认值为“on”。有效值为“on”和“off”。
  • groupquota@:限制指定组所使用的空间量。组空间消耗由“userquota@”属性标识。默认值为none。有效值为“none”或者以字节为单位的大小。
  • groupsused@: 只读属性,显示指定组在此数据集中所使用的空间量。每个文件的组都占用空间,如“ls -l”所示。有关更多信息,请参阅userused@属性。
  • logbias:控制如何使用SLOG(如果存在的话)。为ZFS提供关于如何处理同步请求的提示。默认值是“latency”,如果存在,将在池中使用SLOG。另一个有效值是“吞吐量”,它不会在同步请求上使用SLOG,而是直接进入磁盘。
  • mlslabel:mlslabel属性是一个敏感标签,用于确定是否可以将数据集挂载到启用了受信任扩展的系统上的某个区域中。默认值为none。有效值是Solaris Zones标签或“none”。注意,Zones是Solaris的特性,与GNU/Linux无关。然而,这可能是将来可以用SELinux和Linux容器实现的。
  • mounted: 只读属性,显示该数据集是否已挂载。此属性将显示“yes”或“no”。
  • mountpoint:控制用于此文件系统的挂载点。默认值为“/”。有效值是文件系统上的绝对路径、”none”或”legacy”。当“挂载点”属性更改时,新的目标必须不包含任何子文件。数据集将被卸载并重新挂载到新的目标。
  • nbmand: 控制文件系统是否应该用非阻塞的强制锁来挂载。用于CIFS客户端。默认值为“on”。有效值为“on”和“off”。只有在数据集卸载然后重新安装后,更改属性才会生效。
  • normalization: 指示当比较两个文件名时,文件系统是否应该对文件名执行unicode标准化,以及应该使用哪种标准化算法。默认值为none。取值为“formC”、“formD”、“formKC”、“formKD”。在创建数据集之后,不能更改此属性。
  • origin:克隆或卷的只读属性,显示创建克隆的快照。
  • primarycache:控制在主缓存(ARC)中缓存的内容。如果此属性设置为“all”,则会缓存用户数据和元数据。如果设置为“none”,则两者都不会被缓存。如果设置为”metadata”,则只缓存元数据。默认设置是“所有”。
  • quota: 限制数据集及其后代可以消耗的空间量。此属性强制对所使用的空间数量进行硬性限制。没有软限制。这包括后代所使用的所有空间,包括文件系统和快照。在已经拥有配额的数据集的后代上设置配额不会覆盖祖先的配额,而是施加一个额外的限制。不能对卷设置配额,因为volsize属性充当隐式配额。默认值为none。有效值为字节或none。
  • readonly: 控制是否可以修改此数据集。默认值是off。有效值为“on”和“off”。这个属性也可以通过它的缩写列名“rdonly”来引用。
  • recordsize:指定文件系统中文件的建议块大小。此属性专为访问固定大小记录中的文件的数据库工作负载而设计。ZFS根据为典型访问模式优化的内部算法自动调整块大小。指定的大小必须是2的乘方,大于等于512且小于等于128KB。改变文件系统的记录大小只影响之后创建的文件,现有文件不受影响。该属性也可以通过其缩短的列名“recsize”来表示。
  • refcompressratio:只读属性,显示由“引用”属性中占用的空间所实现的压缩比。
  • referenced:只读属性,显示数据集可以访问的数据量。最初,这个数字将与“used”属性相同。但是,当创建快照并修改数据时,这些数字就会出现分歧。这个属性可以通过它的缩写名称“refer”来表示。
  • refquota: 限制数据集可以消耗的空间量。此属性强制对所使用的空间数量进行硬性限制。该硬限制不包括派生文件系统和快照所使用的空间。默认值为none。有效值为“none”,大小以字节为单位
  • refreservation: 保证给数据集(不包括其派生数据集)的最小空间量。当使用的空间量低于此值时,数据集被视为占用了由rereservation指定的空间量。默认值为none。有效值为“none”和字节大小。该属性也可以通过其缩短的列名“refreserv”来引用。
  • reservation:保证给数据集及其后代的最小空间量。当使用的空间量低于此值时,数据集被视为占用了其预留所指定的空间量。保留在父数据集所使用的空间中计算,并计入父数据集的配额和保留。该属性也可以通过其缩短的列名reserve来引用。默认值为none。有效值为“none”和字节大小。
  • secondarycache:控制在辅助缓存(L2ARC)中缓存的内容。如果此属性设置为“all”,则会缓存用户数据和元数据。如果此属性设置为“none”,则不会缓存用户数据或元数据。如果此属性设置为“metadata”,则只缓存元数据。系统默认值为all。
  • setuid:控制文件系统中是否会标记setuid 位。
  • shareiscsi:指示是否将ZFS卷导出为iSCSI目标。目前,在Linux上的ZFS中还没有实现这一功能,但正在等待实现。有效值为“on”、“off”和“type=disk”。还可能支持其他磁盘类型。默认值为off。
  • sharenfs:指示是否将ZFS数据集导出为NFS导出,以及使用了哪些选项。默认值为“off”。有效值为”on”, “off”和有效的NFS导出选项列表。如果设置为“on”,则可以使用“zfs share”命令共享导出,并使用“zfs unshare”命令取消共享。在使用导出之前,主机上必须运行NFS守护进程。Debian和Ubuntu在启动守护进程之前,需要在/etc/exports文件中有一个有效的导出文件。
  • sharesmb: 是否将ZFS数据集导出为SMB共享。默认值为“off”。有效值为“on”和“off”。它将需要一个正在运行的Samba守护进程,就像NFS一样,并将使用“zfs share”和“zfs unshare”命令共享和取消共享
  • snapdir: 控制是否”.zfs”目录在文件系统的根目录中隐藏或可见。默认值为“hidden”。有效值是”hidden”和”visible”。即使设置为”hidden”值,仍然可以将目录cd到”.zfs”目录下,可以访问共享和快照。
  • sync:控制同步请求的行为(例如fsync, O_DSYNC)。默认值为“Default”,这是POSIX行为,以确保所有同步请求被写入稳定存储,所有设备被刷新,以确保数据不被设备控制器缓存。取值为default、always和disabled。“always”的值导致在系统调用返回之前写入和刷新每个文件系统事务。“disabled”的值
  • type:只读属性,显示文件系统的类型,可能是“数据集”、“卷”或者“快照”。
  • used:只读属性,显示此数据集及其所有子数据集所消耗的空间量。创建快照时,空间最初是在父数据集和它的快照之间共享的。当数据集中的数据被修改时,之前共享的空间对快照来说是唯一的,并且只在该快照的“used”属性中计算。此外,删除快照可以释放其他快照所独有的空间。
  • usedbychildren:只读属性,显示此数据集的子数据集所使用的空间量,如果销毁所有子数据集,则释放该空间。
  • usedbydataset:只读属性,显示此数据集本身使用的空间量。如果销毁该数据集,则释放该数据集所占用的空间。
  • usedbyrefreservation:只读属性,显示此数据集上的预留所使用的空间量,如果删除预留,将释放这些空间。
  • usedbysnapshots: 只读属性,显示此数据集的快照所消耗的空间量。换句话说,这是快照所独有的数据。注意,这不是每个快照“used”属性的总和,因为数据可以跨快照共享。
  • userquota@:限制指定用户所使用的空间量。与refquota属性类似,userquota空间计算不包括派生数据集(如快照和克隆)使用的空间。强制执行用户配额可能会延迟几秒钟。这种延迟意味着用户可能在系统注意到他们已经超过配额并开始使用EDQUOT错误消息拒绝额外的写入之前就已经超过了配额。这个属性在卷上、版本4之前的文件系统上或版本15之前的文件池上不可用。默认值为none。有效值为“none”和字节大小。
  • userrefs:快照上的只读属性,显示此快照上的用户持有数量。用户持有是使用zfs hold命令设置的。
  • userused@:只读属性,显示指定用户在此数据集中所使用的空间量。空间由每个文件的所有者承担,如“ls -l”所示。使用量由du和ls -s表示。有关更多信息,请参阅zfs userspace子命令。“userused@”属性在“zfs get all”中不会显示。@符号后面必须加上用户名,使用以下形式之一:
    (1)POSIX名称(例如,joe)
    (2)POSIX数字ID(例如,789)
    (3)SID名称(例如joe.smith@mydomain)
    (4)SID数字ID(例如,S-1-123-456-789)
  • utf8only:指示文件系统是否应该拒绝包含UTF-8字符集中不存在的字符的文件名。默认值为“off”。有效值为“on”和“off”。在创建数据集之后,无法更改此属性。
  • version: 这个文件系统的磁盘版本,它独立于池版本。此属性只能设置为稍后支持的版本。有效值是“当前”、“1”、“2”、“3”、“4”、“5”
  • volblocksize: 卷的只读属性,指定卷的块大小。一旦写入卷,就不能更改块大小,因此应该在创建卷时设置块大小。卷的默认blocksize为8KB。从512字节到128KB的任意2次方都有效。
  • vscan: 控制在打开和关闭文件时是否应该对常规文件进行病毒扫描。除了启用此属性外,还必须启用病毒扫描服务才能进行病毒扫描。默认值为“off”。有效值为“on”和“off”。
  • written: 只读属性,显示自上次快照以来写入此数据集的引用空间量。
  • written@:快照上的只读属性,该属性显示自指定快照以来写入此数据集的引用空间量。这是该数据集引用但指定快照未引用的空间。
  • xattr:控制是否为该文件系统启用扩展属性。默认值为“on”。有效值为“on”和“off”。
  • zoned:控制是否从非全局区域管理数据集。Zones是Solaris的一个特性,与Linux无关。默认值为“off”。有效值为“on”和“off”。

总结

您可能已经注意到,一些ZFS数据集属性在Linux上的ZFS中并没有完全实现,例如通过iSCSI共享卷。其他数据集属性适用于整个池,例如重复数据删除的情况,即使它们适用于特定的数据集。许多属性只适用于新写入的数据,并且没有追溯力。因此,要了解每个属性及其所提供的优点/缺点。因为父存储池也是一个有效的ZFS数据集,所以任何子数据集都将继承非默认属性。嵌套数据集、快照和卷也是如此。

使用ZFS数据集属性,您现在可以轻松地进行所有调优,目的是设置一个可靠的ZFS存储后端。所有的事情都是用“zfs”命令及其必要的子命令处理的。事实上,到目前为止,我们只学习了两个命令:“zpool”和“zfs”,但我们已经能够构建和配置功能强大、大型、冗余、一致、快速和调优的zfs文件系统。这在存储领域是前所未有的,特别是在GNU/Linux中。 剩下要讨论的唯一一件事就是一些最佳实践和注意事项,然后是一篇关于“zdb”命令(您应该永远不需要它)的简短文章,我们将完成本系列的工作。

参考资料

ZFS属性介绍

https://pthree.org/2013/01/02/zfs-administration-part-xvi-getting-and-setting-properties/

如果你觉得本文对你有帮助,欢迎打赏