ZFS配额和保留是用来限制一个特定的ZFS文件系统可以从ZFS池中使用的磁盘空间数量。
ZFS配额:假设你有一个大小为10GB的ZFS池。你在该池上创建了一个ZFS文件系统。如果你为这个ZFS文件系统设置了2GB的配额,那么这个ZFS文件系统只能使用池中的2GB磁盘空间。即使池上有可用的空间,它也不能使用超过这个数字。
ZFS保留:如果你为一个ZFS文件系统设置了2GB的配额,ZFS将不会立即为该文件系统分配2GB的磁盘空间。磁盘空间将根据需要进行分配,直到达到配额限制。想象一下,你的ZFS池上有许多文件系统,而且许多用户在向它们写东西。可能有一天,某个文件系统的配额没有达到,但其他文件系统已经占满了池子的磁盘空间。因此,即使文件系统从池中用掉了不到2GB的磁盘空间,它仍然不会向池中写入,因为池中没有任何空闲的磁盘空间。
为了解决这个问题,你可以使用ZFS保留。你可以为你非常特殊的ZFS文件系统设置2GB的预留空间,在你设置预留空间的那一刻,2GB的磁盘空间将从ZFS池中为该文件系统分配。这样一来,无论其他文件系统在该池上存储多少数据,你仍然会有专门的磁盘空间供你的文件系统使用,即使该池已满(没有任何可用的磁盘空间),你仍然能够在该文件系统上创建文件。
在这篇文章中,我将告诉你如何为ZFS文件系统配置配额和保留。那么,让我们开始吧。
创建ZFS池和文件系统
为了实验ZFS配额和保留,我将在ZFSpool pool1上创建一个ZFSpool1和4个ZFS文件系统fs1、fs2、fs3和fs4。如果你想跟着做,你也可以这样做。
本文将使用vdb和vdc存储设备来创建ZFSpool1。
$ sudo lsblk -e7 -d

要使用vdb和vdc存储设备创建ZFSpool1,运行以下命令。
$ sudo zpool create -f pool1 vdb vdc

一个ZFSpool pool1应该被创建。
$ sudo zfs list

用下面的命令在ZFSpool pool1上创建文件系统fs1,fs2,fs3, 和fs4。
$ sudo zfs create pool1/fs1
$ sudo zfs create pool1/fs2
$ sudo zfs create pool1/fs3
$ sudo zfs create pool1/fs4

ZFS文件系统fs1、fs2、fs3和fs4应该在ZFSpool1上创建。
$ sudo zfs list

配置ZFS文件系统配额
要为一个ZFS文件系统设置配额,你必须配置该ZFS文件系统的quota和refquota属性。
配额:该配额将为数据、文件系统快照和文件系统克隆设置。所以,你的文件系统、文件系统快照和文件系统克隆的数据总大小不能超过配额限制。
简而言之。
文件系统数据大小+文件系统快照大小+文件系统克隆大小<配额限制
refquota:配额限制只为文件系统数据设置,而不是为文件系统快照和文件系统克隆设置。
简而言之。
文件系统数据大小<refquota限制
默认情况下,配额和refquota属性在任何ZFS文件系统上都没有设置。所以,任何ZFS文件系统的文件系统数据、文件系统快照和文件系统克隆可以跨越整个ZFS池的大小。
正如你所看到的,默认情况下,ZFS文件系统fs1的配额和refquota属性被设置为无。对于fs2、fs3和fs4文件系统也是如此。
$ sudo zfs get refquota,quota pool1/fs1

要为ZFS文件系统fs1设置2GB的配额,运行以下命令。
$ sudo zfs set quota=2G pool1/fs1

正如你所看到的,为ZFS文件系统fs1设置了2GB的配额。
$ sudo zfs get quota pool1/fs1

在为ZFS文件系统fs1设置了2GB的配额后,fs1文件系统的可用磁盘空间**(AVAIL**)应该是2GB,而不是poolpool1的可用磁盘空间**(本例中为8.72GB**),正如你在下面的截图中看到的。
$ sudo zfs list

你已经为ZFS文件系统fs1设置了2GB的配额。所以,你不能在文件系统fs1上保留超过2GB的数据。想象一下,创建一些文件系统快照和克隆,用去了大约1GB的磁盘空间。在这种情况下,你将只有1GB的磁盘空间可用于fs1文件系统上的数据。如果文件系统快照和克隆占用了约1.5GB的磁盘空间,你将只有500MB的磁盘空间可用于fs1文件系统上的数据。这是个问题。
有时,你可能想拨出一些磁盘空间只用于存储ZFS文件系统上的数据,这样文件系统快照和克隆就不会占用ZFS文件系统的所有可用磁盘空间。你可以为此设置refquota属性。
比方说,你想为ZFS文件系统fs2设置2GB的配额,并将1GB的磁盘空间只用于数据。这样,你就只能用1GB的磁盘空间来存储文件系统快照和克隆。
为ZFS文件系统fs2设置2GB的配额,如下所示。
$ sudo zfs set quota=2G pool1/fs1

正如你所看到的,为ZFS文件系统fs2设置了2GB的配额。
$ sudo zfs list

要为ZFS文件系统fs2划出1GB的磁盘空间,只用于存储数据,请按如下方法设置文件系统fs2的refquota属性。
$ sudo zfs set refquota=1G pool1/fs2

正如你所看到的,在ZFS文件系统fs2上,refquota属性被设置为1GB, 而配额属性被设置为2GB。
$ sudo zfs get refquota,quota pool1/fs2

ZFS文件系统fs2的可用磁盘空间应该是1GB (1024MB)--你使用refquota属性看到的大小,你可以在下面的截图中看到。
$ sudo zfs list

配额设置好后,让我们看看当你在ZFS文件系统fs1和fs2上创建文件时,磁盘空间是如何分配的。
在ZFS文件系统fs1中创建一个200MB的文件test.img,方法如下。
$ sudo dd if=/dev/random of=/pool1/fs1/test.img bs=1M count=200 status=progress

在ZFS文件系统fs2中创建一个100MB的文件test.img,如下所示。
$ sudo dd if=/dev/random of=/pool1/fs2/test.img bs=1M count=100 status=progress

正如你所看到的,fs1使用了200MB的磁盘空间,fs2使用了poolpool1的100MB的磁盘空间。总的来说,从poolpool1中使用了300MB的磁盘空间。尽管你已经为fs1和fs2文件系统设置了配额,但只有所需的磁盘空间从poolpool1分配给fs1和fs2文件系统。
$ sudo zfs list

如果你想只为ZFS文件系统的数据设置配额,而不是为文件系统的快照和克隆设置配额,那么只需在你想要的ZFS文件系统上设置refquota属性。你不需要设置配额属性。这样一来,文件系统快照和克隆可以从ZFS池中占用所需的磁盘空间。但是配额限制将只放在你存储在ZFS文件系统上的数据上。
如果你没有拍摄任何文件系统快照或进行文件系统克隆,那么quota和refquota的工作方式是一样的。你使用哪一个并不重要。
配置ZFS文件系统保留
先前,你已经看到,当你在ZFS文件系统上设置配额时,不会从ZFS池中为该文件系统自动分配磁盘空间。磁盘空间是在该文件系统上创建文件时分配的。这没有什么问题。但是,有的时候你不希望这样。
在某些情况下,你可能想从池中为一个特定的ZFS文件系统分配一些磁盘空间。这样,即使其他文件系统填满了池子,你的ZFS文件系统上仍然有空闲空间。这就是ZFS预订的用途。
要为一个ZFS文件系统设置保留,你必须配置该ZFS文件系统的保留 和保留 属性。
**保留:**磁盘空间将被保留给ZFS池中的ZFS文件系统的数据、文件系统快照和文件系统克隆。
**拒绝保留:**磁盘空间将只保留给ZFS池中的ZFS文件系统的数据。没有磁盘空间将被保留给文件系统快照和文件系统克隆。
默认情况下,保留和刷新 属性不在任何ZFS文件系统上设置。所以,ZFS不会为ZFS池中的任何ZFS文件系统的数据、文件系统快照和文件系统克隆分配任何磁盘空间。
正如你所看到的,在ZFS文件系统fs3上,保留和保留的属性默认情况下被设置为无。对于fs1、fs2和fs4文件系统也是如此。
$ sudo zfs get a reservation,refreservation pool1/fs3

默认情况下,ZFS文件系统fs3和fs4拥有与poolpool1相同的可用磁盘空间(8.43 GB)。
$ sudo zfs list

要从池中为ZFS文件系统fs3保留2GB 的磁盘空间(用于文件系统数据、快照和克隆),请设置ZFS文件系统fs3的保留属性如下。
$ sudo zfs set reservation=2G pool1/fs3

正如你所看到的,ZFS文件系统fs3的保留属性被设置为2GB 。
$ sudo zfs get reservation pool1/fs3

注意,在将ZFS文件系统fs3的保留属性设置为2GB后,立即从ZFS池pool11中使用了2GB。另外,ZFS文件系统fs3的可用磁盘空间比ZFS池12多了2GB。
$ sudo zfs list

要为池中的ZFS文件系统fs4只保留1GB 的磁盘空间(不用于快照和克隆),请按如下方式设置ZFS文件系统fs4的refreservation属性。
$ sudo zfs set refreservation=1G pool1/fs4

在下面的截图中你可以看到,ZFS文件系统fs4的refreservation属性应该被设置为1GB。
$ sudo zfs get refreservation pool1/fs4

注意,在为ZFS文件系统fs4设置refreservation属性为1GB后,立即从ZFS文件系统fs41中使用1GB。1GB也从ZFS池pool12中被使用,ZFS文件系统fs4的可用磁盘空间比ZFS池pool14多1GB3。
$ sudo zfs list

配置ZFS文件系统保留和配额的关系
你也可以在ZFS文件系统上与配额一起使用保留。让我们看看一些例子。
假设你想为ZFS文件系统fs3设置2GB的配额,并从ZFS池中为ZFS文件系统fs3保留2GB 的磁盘空间(用于存储文件系统数据、快照和克隆)。
要做到这一点,请设置ZFS文件系统fs3的配额和保留属性,如下所示。
$ sudo zfs set quota=2G reservation=2G pool1/fs3

ZFS文件系统fs3的配额和预订属性应该被设置为**2GB,**你可以在下面的截图中看到。
$ sudo zfs get quota,reservation pool1/fs3

ZFS文件系统fs3的可用磁盘空间应该被设置为2GB。2GB的磁盘空间也应该从ZFS池pool1中为ZFS文件系统fs3保留。
$ sudo zfs list

假设你想为ZFS文件系统fs4设置一个2GB 的配额。但是,你想只允许1GB的磁盘空间用于存储文件系统数据,另外1GB用于存储文件系统快照和克隆。另外,你想保留1GB的磁盘空间来存储ZFS池中的ZFS文件系统fs4。
要做到这一点,设置ZFS文件系统fs4的quota、refquota和refreservation属性,如下所示。
$ sudo zfs set quota=2G refquota=1G refreservation=1G pool1/fs4

ZFS文件系统fs4的配额属性应该被设置为2GB,而refquota和refreservation属性应该被设置为**1GB,**你可以在下面的截图中看到。
$ sudo zfs set quota,refquota,refreservation pool1/fs4

ZFS文件系统fs4的可用磁盘空间应该被设置为1GB。1GB的磁盘空间也应该被保留给ZFS池pool1的ZFS文件系统fs4。
$ sudo zfs list

假设你想为ZFS文件系统fs4设置一个2GB 的配额。但是,你想只允许1GB的磁盘空间用于存储文件系统数据,另外1GB用于存储文件系统快照和克隆。另外,你想保留2GB的磁盘空间用于存储文件系统数据、快照和克隆,并从该保留空间中保留1GB的磁盘空间,只存储ZFS文件系统fs4。
要做到这一点,请设置ZFS文件系统fs4的quota、refquota、reservation和refreservation属性,如下所示。
$ sudo zfs set quota=2G refquota=1G reservation=2G refreservation=1G pool1/fs4

正如你所看到的,ZFS文件系统fs4的配额和预订属性被设置为2GB,而refquota和refreservation属性被设置为1GB。
$ sudo zfs get quota,refquota,reservation,refreservation pool1/fs4

早些时候,ZFS文件系统从poolpool1保留了1GB的磁盘空间。现在,它又保留了1GB。总的来说,ZFS文件系统fs4从ZFSpool1中保留了2GB的磁盘空间。同时,为ZFS文件系统fs4设置了配额限制。
$ sudo zfs list

禁用ZFS文件系统保留
你可以将ZFS文件系统的保留和刷新属性设置为无或0,以禁用对该ZFS文件系统的保留。
要禁用对ZFS文件系统fs4的保留,请将ZFS文件系统fs4的保留和refreservation属性设置为无,方法如下。
$ sudo zfs set reservation=none refreservation=none pool1/fs4

应禁用ZFS文件系统fs4的保留。
$ sudo zfs get a reservation,refreservation pool1/fs4

正如你所看到的,2GB的磁盘空间(从4.49GB到现在的2.29GB)从ZFS池pool1中被移除,因为ZFS文件系统fs4的保留被禁用。
$ sudo zfs list

禁用ZFS文件系统配额
你可以将 ZFS 文件系统的quota和refquota 属性设置为none或0,以禁用该 ZFS 文件系统的配额。
要禁用 ZFS 文件系统fs4 的配额,请将 ZFS 文件系统fs4的quota和refquota 属性设置为none,如下所示。
$ sudo zfs set quota=none refquota=none pool1/fs4

应该禁用ZFS文件系统fs4的配额。
$ sudo zfs get quota,refquota pool1/fs4

正如你所看到的,不再为ZFS文件系统fs4设置配额限制了。
$ sudo zfs list

总结
在这篇文章中,我已经讨论了ZFS文件系统的配额和保留功能。我已经向你展示了如何为ZFS文件系统配置配额和保留。我还向你展示了如何从ZFS文件系统中禁用配额和保留。