ZFS 自动备份用于定期将 ZFS 文件系统备份到其他位置。它试图成为最友好的使用和易于调试的 ZFS 备份工具。
项目描述
ZFS 自动备份
介绍
ZFS-autobackup 试图成为最可靠和最容易使用的工具,同时具有所有功能。
您可以将其用作备份工具、复制工具或快照工具。
您可以通过设置自定义来选择要备份的内容ZFS property。这使得添加/删除特定数据集或仅备份整个池变得容易。
其他设置仅在命令行中指定:只需设置和测试您的 zfs-autobackup 命令并修复您可能遇到的所有问题。完成后,您只需将命令复制/粘贴到 cron 或脚本即可。
由于它使用 ZFS 命令,因此您可以通过指定--debug. 如果您遇到一些奇怪的问题或错误,这也很有帮助。您可以只复制粘贴失败的命令并在命令行上使用它。(我在其他工具中错过的东西)
其他工具缺少的一个重要功能是可靠的--test选项:这使您可以查看 zfs-autobackup 将做什么并调整您的参数。它会做所有事情,除了对您的系统进行更改。
特征
- 跨操作系统工作:通过Linux、FreeBSD/FreeNAS和SmartOS 测试。
- 学习曲线低:无需复杂的守护程序或服务,无需额外的软件或网络。(仅阅读此页)
- 与现有的复制系统配合得很好。(如 Proxmox HA)
- 通过查看简单的 ZFS 属性自动选择要备份的文件系统。(递归)
- 创建一致的快照。(以原子方式一次拍摄所有快照。)
- 多种备份模式:
- 在同一台服务器上备份本地数据。
- 通过 SSH 将本地数据“推送”到备份服务器。
- 通过 SSH 从服务器“拉”远程数据并在本地备份。
- 甚至在将备份推送到另一台服务器的同时从服务器中提取数据。(源服务器和目标服务器之间的零信任)
- 可以通过简单的 cronjob 安排或直接从命令行运行。
- 支持恢复中断的传输。
- ZFS 加密支持:可以在传输过程中解密/加密甚至重新加密数据集。
- 支持压缩发送。(使用 pigz、zstd 等)
- IO 缓冲以加快传输速度。
- 带宽速率限制。
- 来自和到相同数据集的多个备份没有问题。
- 在执行任何其他操作之前创建快照。(确保你至少有一个快照,如果一切都失败了)
- 检查所有内容,但在可能的情况下尝试继续处理非致命错误。(完成后报告错误计数)
- 能够手动“完成”失败的备份以查看发生了什么。
- 易于调试并具有测试模式。打印实际的 unix 命令。
- 对较旧的快照使用渐进式细化。
- 在重要的快照上使用 zfs-holds,这样它们就不会被意外破坏。
- 自动恢复失败的传输。
- 可以从现有的常用快照继续。(例如容易迁移)
- 优雅地处理源上不再存在的数据集。
- 支持通过自定义管道发送/接收 ZFS。
- 简易安装:
- 只需通过 pip 安装 zfs-autobackup。
- 只需要安装在一侧。
- 用 python 编写并使用 zfs-commands,不需要特殊的 3rd 方依赖项或编译库。
- 没有单独的配置文件或属性。只需一个 zfs-autobackup 命令,您就可以在备份脚本中复制/粘贴。
安装
您只需要在启动备份的一侧安装 zfs-autobackup。对方不需要任何额外的配置。
使用点子
大多数服务器上推荐的方法是使用pip:
[root@server ~]# pip install --upgrade zfs-autobackup
这也可用于将 zfs-autobackup 升级到最新的稳定版本。
要安装最新的 beta 版本,请添加该--pre选项。
使用 easy_install
在较旧的服务器上,您可能必须使用 easy_install
[root@server ~]# easy_install zfs-autobackup
例子
在本例中,我们将备份一台名为server1的机器到名为 的机器backup。
设置 SSH 登录
zfs-autobackup 需要通过 ssh 进行无密码登录。这意味着生成一个 ssh 密钥并将其复制到远程服务器。
生成 SSH 密钥backup
在运行 zfs-autobackup 的备份服务器上,您需要创建一个 SSH 密钥。您只需执行一次。
使用ssh-keygen命令并将密码留空:
root@backup:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:McJhCxvaxvFhO/3e8Lf5gzSrlTWew7/bwrd2U2EHymE root@backup
The key's randomart image is:
+---[RSA 2048]----+
| + = |
| + X * E . |
| . = B + o o . |
| . o + o o.|
| S o .oo|
| . + o= +|
| . ++==.|
| .+o**|
| .. +B@|
+----[SHA256]-----+
root@backup:~#
将 SSH 密钥复制到server1
现在您需要将密钥的公共部分复制到server1
该ssh-copy-id命令是自动执行此操作的便捷工具。它只会询问您的密码。
root@backup:~# ssh-copy-id root@server1.server.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@server1.server.com'"
and check to make sure that only the key(s) you wanted were added.
root@backup:~#
这允许备份服务器在server1没有密码的情况下以 root 身份登录。
选择要备份的文件系统
选择一个唯一且一致的备份名称很重要。在这种情况下,我们将备份命名为:offsite1.
在源 zfs 系统上,将autobackup:offsite1zfs 属性设置为 true:
[root@server1 ~]# zfs set autobackup:offsite1=true rpool
[root@server1 ~]# zfs get -t filesystem,volume autobackup:offsite1
NAME PROPERTY VALUE SOURCE
rpool autobackup:offsite1 true local
rpool/ROOT autobackup:offsite1 true inherited from rpool
rpool/ROOT/server1-1 autobackup:offsite1 true inherited from rpool
rpool/data autobackup:offsite1 true inherited from rpool
rpool/data/vm-100-disk-0 autobackup:offsite1 true inherited from rpool
rpool/swap autobackup:offsite1 true inherited from rpool
...
ZFS 属性inherited由子数据集决定。由于我们在最高数据集上设置了属性,因此我们实际上是在备份整个池。
因为我们不想备份所有内容,我们可以通过将属性设置为 false 来排除某些文件系统:
[root@server1 ~]# zfs set autobackup:offsite1=false rpool/swap
[root@server1 ~]# zfs get -t filesystem,volume autobackup:offsite1
NAME PROPERTY VALUE SOURCE
rpool autobackup:offsite1 true local
rpool/ROOT autobackup:offsite1 true inherited from rpool
rpool/ROOT/server1-1 autobackup:offsite1 true inherited from rpool
rpool/data autobackup:offsite1 true inherited from rpool
rpool/data/vm-100-disk-0 autobackup:offsite1 true inherited from rpool
rpool/swap autobackup:offsite1 false local
...
autobackup-property 可以有 3 个值:
true:备份数据集及其所有子项false:不要备份数据集及其所有子项。(用于排除某些数据集)child:只备份数据集的孩子,而不是数据集本身。
仅使用 zfs-command 来设置这些属性,而不是 zpool 命令。
运行 zfs-autobackup
在备份服务器上运行脚本,从 --ssh-source 指定的服务器中拉取数据。
[root@backup ~]# zfs-autobackup --ssh-source server1.server.com offsite1 backup/server1 --progress --verbose
#### Settings summary
[Source] Datasets on: server1.server.com
[Source] Keep the last 10 snapshots.
[Source] Keep every 1 day, delete after 1 week.
[Source] Keep every 1 week, delete after 1 month.
[Source] Keep every 1 month, delete after 1 year.
[Source] Send all datasets that have 'autobackup:offsite1=true' or 'autobackup:offsite1=child'
[Target] Datasets are local
[Target] Keep the last 10 snapshots.
[Target] Keep every 1 day, delete after 1 week.
[Target] Keep every 1 week, delete after 1 month.
[Target] Keep every 1 month, delete after 1 year.
[Target] Receive datasets under: backup/server1
#### Selecting
[Source] rpool: Selected (direct selection)
[Source] rpool/ROOT: Selected (inherited selection)
[Source] rpool/ROOT/server1-1: Selected (inherited selection)
[Source] rpool/data: Selected (inherited selection)
[Source] rpool/data/vm-100-disk-0: Selected (inherited selection)
[Source] rpool/swap: Ignored (disabled)
#### Snapshotting
[Source] rpool: No changes since offsite1-20200218175435
[Source] rpool/ROOT: No changes since offsite1-20200218175435
[Source] rpool/data: No changes since offsite1-20200218175435
[Source] Creating snapshot offsite1-20200218180123
#### Sending and thinning
[Target] backup/server1/rpool/ROOT/server1-1@offsite1-20200218175435: receiving full
[Target] backup/server1/rpool/ROOT/server1-1@offsite1-20200218175547: receiving incremental
[Target] backup/server1/rpool/ROOT/server1-1@offsite1-20200218175706: receiving incremental
[Target] backup/server1/rpool/ROOT/server1-1@offsite1-20200218180049: receiving incremental
[Target] backup/server1/rpool/ROOT/server1-1@offsite1-20200218180123: receiving incremental
[Target] backup/server1/rpool/data@offsite1-20200218175435: receiving full
[Target] backup/server1/rpool/data/vm-100-disk-0@offsite1-20200218175435: receiving full
...
请注意,这称为“拉取”备份:备份服务器从服务器拉取备份。这通常是首选方式。
也可以让服务器将其备份推送到备份服务器。然而,这具有安全隐患。在这种情况下,您可以反过来设置 SSH 密钥并在服务器上使用 --ssh-target 参数。
自动备份
现在每次运行该命令时,zfs-autobackup 都会创建一个新快照并复制您的数据。
较旧的快照最终将被删除,具体取决于--keep-source和--keep-target设置。(默认值显示在上面的“设置摘要”下)
一旦为您的情况设置了正确的设置,您就可以将命令存储在 cronjob 中。
或者只是创建一个脚本并在需要时手动运行它。
用作快照工具
您可以使用 zfs-autobackup 仅制作快照。
只是不指定目标路径:
root@ws1:~# zfs-autobackup test --verbose
zfs-autobackup v3.0 - Copyright 2020 E.H.Eefting (edwin@datux.nl)
#### Source settings
[Source] Datasets are local
[Source] Keep the last 10 snapshots.
[Source] Keep every 1 day, delete after 1 week.
[Source] Keep every 1 week, delete after 1 month.
[Source] Keep every 1 month, delete after 1 year.
[Source] Selects all datasets that have property 'autobackup:test=true' (or childs of datasets that have 'autobackup:test=child')
#### Selecting
[Source] test_source1/fs1: Selected (direct selection)
[Source] test_source1/fs1/sub: Selected (inherited selection)
[Source] test_source2/fs2: Ignored (only childs)
[Source] test_source2/fs2/sub: Selected (inherited selection)
#### Snapshotting
[Source] Creating snapshots test-20200710125958 in pool test_source1
[Source] Creating snapshots test-20200710125958 in pool test_source2
#### Thinning source
[Source] test_source1/fs1@test-20200710125948: Destroying
[Source] test_source1/fs1/sub@test-20200710125948: Destroying
[Source] test_source2/fs2/sub@test-20200710125948: Destroying
#### All operations completed successfully
(No target_path specified, only operated as snapshot tool.)
这也允许您在白天制作多个快照,但只在晚上服务器不忙时备份数据。
注意:在这种模式下,细化时不考虑指定的目标调度,它只通过查看保留知道快照是普通快照。因此,请确保您的源计划保留您以后仍要传输的快照。
精简过时的快照
更薄的是破坏源和目标上旧快照的东西。
稀释器运行“无状态”:快照的名称或属性中没有任何内容表明它将保留多长时间。每次 zfs-autobackup 运行时,它都会查看所有现有快照的时间戳。从那里它将根据您的计划确定哪些快照已过时。这种无状态系统的优点是您可以随时更改时间表。
请注意,精简只会破坏与 zfs-autobackup 的命名模式匹配的快照。如果您使用--other-snapshots,它不会在将这些快照复制到目标后销毁它们。
销毁丢失的数据集
当数据集在源上已被破坏或取消选择,但仍存在于目标上时,我们称其为缺失数据集。缺失的数据集仍将按计划进行稀疏化。
最终快照永远不会被销毁,除非您使用以下选项指定截止日期:--destroy-missing
在这种情况下,它将查看我们拍摄的最后一个快照,并确定是否早于您指定的截止日期。例如:--destroy-missing 30d将在最后一次快照后 30 天开始销毁事物。
截止日期后
当截止日期过去时,我们所有的快照,除了最后一个将被销毁。不考虑正常的细化时间表。
数据集必须具有以下属性才能最终真正销毁:
- 数据集没有直接的子文件系统或卷。
- 剩下的唯一快照是 zfs-autobackup 创建的最后一个快照。
- 剩余的快照没有克隆。
细化时间表
默认的细化计划是:10,1d1w,1w1m,1m1y。
时间表由多个规则组成,由一个分隔,
一个普通数字指定您希望始终保留多少快照,无论时间或间隔如何。
其他规则的格式为:<Interval><TTL>.
- 间隔:快照之间的最小间隔。间隔小于此的快照将被销毁。
- TTL:快照的最大生命周期,之后它们将被销毁。
- 这些是可用于间隔和 TTL 的时间单位:
y: 年m: 月d: 天h: 小时min: 分钟s: 秒
由于这听起来可能很复杂,因此该--verbose选项将向您展示这一切的含义:
[Source] Keep the last 10 snapshots.
[Source] Keep every 1 day, delete after 1 week.
[Source] Keep every 1 week, delete after 1 month.
[Source] Keep every 1 month, delete after 1 year.
仅当任何规则不再需要快照时,才会销毁快照。
您可以根据需要指定任意数量的规则。规则的顺序无关紧要。
请记住,是否经常运行 zfs-autobackup 取决于您:如果您想保留每小时的快照,则必须确保至少每小时运行一次。
但是,如果您运行它的频率高于或低于此,也没有问题:瘦身器仍会保留一组最佳快照,以尽可能好地匹配您的日程安排。
如果您想保留尽可能少的快照,只需指定 0。(--keep-source=0例如)
如果您想保留所有快照,只需指定一个非常高的数字。
有关稀释剂的更多详细信息
我们将举例说明稀释剂的工作原理。
假设我们想要 3 个更细的规则:
- 我们希望将每日快照保留 7 天。
- 我们希望将每周快照保留 4 周。
- 我们希望将每月快照保留 12 个月。
到目前为止,我们在随机时刻拍摄了 4 张快照:
对于每条规则,Thiner 都会将时间线划分为块,并将每个快照分配给一个块。
一个块只能分配一个快照:如果多个快照属于同一个块,它只会将它分配给我们想要保留的最旧的。
颜色显示快照属于哪个块:
- 快照 1:此快照属于每日块 1、每周块 0 和每月块 0。但是每日块太旧。
- 快照 2:由于每周块 0 和每月块 0 已经有快照,它只属于每日块 4。
- 快照 3:此快照属于每日块 8 和每周块 1。
- 快照 4:由于每日块 8 已经有快照,所以这个不属于任何东西,可以立即删除。(自上次快照以来将暂时保留)
zfs-autobackup 将在每次运行时重新评估:一旦快照不再属于任何块,它将被销毁。
仍然必须发送到目标的源上的快照不会被破坏。(如果目标仍然想要它们,根据目标时间表)
zfs-autobackup 如何处理加密
在正常操作中,数据集被原封不动地传输:
- 加密的源数据集将按原样发送并在目标端保持加密状态。(在 ZFS 中,这称为原始模式)如果您不想访问数据,则不需要目标端的密钥。
- 简单的源数据集将保持在目标上。(即使指定的目标路径已加密。)
基本上你不必做任何事情或担心任何事情。
解密/加密
如果您想在传输过程中更改数据集的加密状态,情况会有所不同:
- 如果要在发送加密数据集之前对其进行解密,则应使用该
--decrypt选项。然后数据集将直接存储在目标中。 - 如果要在收到纯数据集时对其进行加密,则应使用该
--encrypt选项。然后数据集将加密存储在目标中。(已经加密的数据集仍将在原始模式下原封不动地发送。) - 如果您还想使用目标端加密重新加密加密数据集,您可以使用这两个选项。
注意 1:--encrypt 选项将依赖于从目标端的父数据集继承加密参数。您负责设置这些密钥并加载密钥。所以 --encrypt 不能保证加密:如果你不设置它,它就不能加密。
注意 2:在早期阶段确定您想要什么:如果您在初始同步后更改 --encrypt 或 --decrypt 参数,您可能会遇到奇怪而奇妙的错误。(没什么危险的)
使用 zfs 加密时的一些常见错误:
cannot receive incremental stream: kernel modules must be upgraded to receive this stream.
如果您忘记使用 --encrypt,而目标数据集已经加密,则会发生这种情况。(确实很奇怪的错误信息)
传输缓冲、压缩和速率限制。
如果您通过慢速链接传输,使用--compress=zstd-fast. 这将在发送之前压缩数据,因此它使用更少的带宽。另一种方法是使用 --zfs-compressed:这将传输已经完整压缩的块。(--compress 通常会压缩得更好,但使用更多的资源。--zfs-compressed 使用最少的资源,但如果您想在目标上使用不同的压缩方法,则可能是一个缺点。)
您还可以使用该--rate选项限制数据速率。
该--buffer选项也可能会有所帮助,因为它充当 IO 缓冲区:zfs 发送在完全空闲和大量数据之间变化很大。当 zfs send 空闲时,缓冲区将继续通过慢速链路传输数据。
也可以使用 和 添加自定义发送或接收--send-pipe管道--recv-pipe。
这些选项都一起工作,接收端的缓冲区仅在适当时添加。当所有选项都处于活动状态时:
在发送方:
zfs 发送 -> 发送缓冲区 -> 自定义发送管道 -> 压缩 -> 传输速率限制器
在接收方:
解压->自定义recv管道->缓冲区->zfs recv
在快照前后运行自定义命令
您可以在快照之前和之后运行命令以冻结数据库以使 on 例如使磁盘上的数据在快照之前保持一致。
命令将在源端执行。为此使用--pre-snapshot-cmd和--post-snapshot-cmd选项。
例如:
zfs-autobackup \
--pre-snapshot-cmd 'daemon -f jexec mysqljail1 mysql -s -e "set autocommit=0;flush logs;flush tables with read lock;\\! echo \$\$ > /tmp/mysql_lock.pid && sleep 60"' \
--pre-snapshot-cmd 'daemon -f jexec mysqljail2 mysql -s -e "set autocommit=0;flush logs;flush tables with read lock;\\! echo \$\$ > /tmp/mysql_lock.pid && sleep 60"' \
--post-snapshot-cmd 'pkill -F /jails/mysqljail1/tmp/mysql_lock.pid' \
--post-snapshot-cmd 'pkill -F /jails/mysqljail2/tmp/mysql_lock.pid' \
backupfs1
pre/post 命令期间的故障处理:
- 如果预命令失败,zfs-autobackup 将退出并出现错误。(执行后命令后)
- 所有后置命令总是被执行。即使预命令或实际快照失败。这样你就可以确保这些东西总是被清理和解冻。
提示
- 如果
--debug出现问题并且您想查看执行的命令,请使用。这也将在第一个错误处停止。 - 您可以通过创建两个 cronjob 来拆分快照和发送任务。只需省略目标路径即可创建单独的快照程序定时作业。
- 将
readonly目标文件系统的属性设置为on. 这可以防止目标端的更改。(通常,如果有更改,下一次备份将失败并需要 zfs 回滚。)请注意,只读意味着您不能直接更改数据集的内容。它仍然可以接收新的数据集和操作属性等。 - 用于
--clear-refreservation节省备份服务器上的空间。 - 用于
--clear-mountpoint防止目标服务器在重新启动期间将备份的文件系统挂载到错误的位置。
性能提示
如果您有大量数据集,请务必牢记以下提示。
此外,在数据传输期间使用 --buffer 选项添加 IO 缓冲可能会有所帮助。这可能会加快速度,因为它可以消除 zfs 发送或接收期间频繁发生的突然 IO 突发。
一些统计数据
为了了解 zfs-autobackup 的速度有多快,我在笔记本电脑上使用 SKHynix_HFS512GD9TNI-L2B0B 磁盘进行了一些测试。我正在使用 zfs 2.0.2。
我创建了 100 个空数据集并测量了 zfs-autobackup 的总运行时间。我使用了以下所有性能提示。(--no-holds, --allow-empty, ssh ControlMaster)
- 没有 ssh:15 秒。(>6 个数据集/秒)
- ssh-target 或 ssh-source=localhost:20 秒(5 个数据集/秒)
- ssh-target 和 ssh-source=localhost:24 秒(4 个数据集/秒)
大胆地说,我创建了 2500 个数据集,但这也没问题。因此,似乎应该可以将 zfs-autobackup 与数千个数据集一起使用。
如果您需要更多性能,请告诉我。
注意:ZFS 版本 2 中实际上存在性能回归:https ://github.com/openzfs/zfs/issues/11560使用 --no-progress 作为解决方法。
减少工作
您可以使用 --no-holds 和 --allow-empty 使 zfs-autobackup 生成更少的工作。
这为每个数据集节省了大量额外的 zfs 命令。
加速 SSH
您可以使您的 ssh 连接持久化并大大加快 zfs-autobackup:
在备份服务器上将其添加到您的 ~/.ssh/config 中:
Host *
ControlPath ~/.ssh/control-master-%r@%h:%p
ControlMaster auto
ControlPersist 3600
谢谢@mariusvw :)
指定 ssh 端口或选项
正确的方法是创建 ~/.ssh/config:
Host smartos04
Hostname 1.2.3.4
Port 1234
user root
Compression yes
这样您就可以将“smartos04”指定为主机。
还对慢速链接使用压缩。
查看 man ssh_config 以获得更多选项。
用法
usage: zfs-autobackup [-h] [--ssh-config CONFIG-FILE] [--ssh-source USER@HOST]
[--ssh-target USER@HOST] [--keep-source SCHEDULE]
[--keep-target SCHEDULE] [--pre-snapshot-cmd COMMAND]
[--post-snapshot-cmd COMMAND] [--other-snapshots]
[--no-snapshot] [--no-send] [--no-thinning] [--no-holds]
[--min-change BYTES] [--allow-empty] [--ignore-replicated]
[--strip-path N] [--clear-refreservation]
[--clear-mountpoint] [--filter-properties PROPERTY,...]
[--set-properties PROPERTY=VALUE,...] [--rollback]
[--destroy-incompatible] [--destroy-missing SCHEDULE]
[--ignore-transfer-errors] [--decrypt] [--encrypt]
[--zfs-compressed] [--test] [--verbose] [--debug]
[--debug-output] [--progress] [--send-pipe COMMAND]
[--recv-pipe COMMAND] [--compress TYPE] [--rate DATARATE]
[--buffer SIZE]
backup-name [target-path]
zfs-autobackup v3.1 - (c)2021 E.H.Eefting (edwin@datux.nl)
positional arguments:
backup-name Name of the backup (you should set the zfs property
"autobackup:backup-name" to true on filesystems you
want to backup
target-path Target ZFS filesystem (optional: if not specified,
zfs-autobackup will only operate as snapshot-tool on
source)
optional arguments:
-h, --help show this help message and exit
--ssh-config CONFIG-FILE
Custom ssh client config
--ssh-source USER@HOST
Source host to get backup from.
--ssh-target USER@HOST
Target host to push backup to.
--keep-source SCHEDULE
Thinning schedule for old source snapshots. Default:
10,1d1w,1w1m,1m1y
--keep-target SCHEDULE
Thinning schedule for old target snapshots. Default:
10,1d1w,1w1m,1m1y
--pre-snapshot-cmd COMMAND
Run COMMAND before snapshotting (can be used multiple
times.
--post-snapshot-cmd COMMAND
Run COMMAND after snapshotting (can be used multiple
times.
--other-snapshots Send over other snapshots as well, not just the ones
created by this tool.
--no-snapshot Don't create new snapshots (useful for finishing
uncompleted backups, or cleanups)
--no-send Don't send snapshots (useful for cleanups, or if you
want a serperate send-cronjob)
--no-thinning Do not destroy any snapshots.
--no-holds Don't hold snapshots. (Faster. Allows you to destroy
common snapshot.)
--min-change BYTES Number of bytes written after which we consider a
dataset changed (default 1)
--allow-empty If nothing has changed, still create empty snapshots.
(same as --min-change=0)
--ignore-replicated Ignore datasets that seem to be replicated some other
way. (No changes since lastest snapshot. Useful for
proxmox HA replication)
--strip-path N Number of directories to strip from target path (use 1
when cloning zones between 2 SmartOS machines)
--clear-refreservation
Filter "refreservation" property. (recommended, safes
space. same as --filter-properties refreservation)
--clear-mountpoint Set property canmount=noauto for new datasets.
(recommended, prevents mount conflicts. same as --set-
properties canmount=noauto)
--filter-properties PROPERTY,...
List of properties to "filter" when receiving
filesystems. (you can still restore them with zfs
inherit -S)
--set-properties PROPERTY=VALUE,...
List of propererties to override when receiving
filesystems. (you can still restore them with zfs
inherit -S)
--rollback Rollback changes to the latest target snapshot before
starting. (normally you can prevent changes by setting
the readonly property on the target_path to on)
--destroy-incompatible
Destroy incompatible snapshots on target. Use with
care! (implies --rollback)
--destroy-missing SCHEDULE
Destroy datasets on target that are missing on the
source. Specify the time since the last snapshot, e.g:
--destroy-missing 30d
--ignore-transfer-errors
Ignore transfer errors (still checks if received
filesystem exists. useful for acltype errors)
--decrypt Decrypt data before sending it over.
--encrypt Encrypt data after receiving it.
--zfs-compressed Transfer blocks that already have zfs-compression as-
is.
--test dont change anything, just show what would be done
(still does all read-only operations)
--verbose verbose output
--debug Show zfs commands that are executed, stops after an
exception.
--debug-output Show zfs commands and their output/exit codes. (noisy)
--progress show zfs progress output. Enabled automaticly on ttys.
(use --no-progress to disable)
--send-pipe COMMAND pipe zfs send output through COMMAND (can be used
multiple times)
--recv-pipe COMMAND pipe zfs recv input through COMMAND (can be used
multiple times)
--compress TYPE Use compression during transfer, defaults to zstd-adapt
if TYPE is not specified. (gzip, pigz-fast, pigz-slow,
zstd-fast, zstd-slow, zstd-adapt, xz, lzo, lz4)
--rate DATARATE Limit data transfer rate (e.g. 128K. requires
mbuffer.)
--buffer SIZE Add zfs send and recv buffers to smooth out IO bursts.
(e.g. 128M. requires mbuffer)
Full manual at: https://github.com/psy0rz/zfs_autobackup
故障排除
它一直在询问我的 SSH 密码
您忘记通过 SSH 密钥设置自动登录,请查看示例如何执行此操作。
它说“无法接收增量流:无效的备份流”
这通常意味着您在备份期间在目标端创建了一个新快照。如果您重新启动 zfs-autobackup,它将自动中止部分接收的无效快照并重新开始。
它说“无法接收增量流:自最近的快照以来目的地已被修改”
这意味着文件已在目标端以某种方式进行了修改。
您可以使用 --rollback 自动回滚此类更改。还可以尝试销毁目标数据集并在下次运行时使用 --clear-mountpoint。这样就不会挂载了。
它说“内部错误:无效参数”
在某些情况下(Linux -> FreeBSD),这意味着目标系统不完全支持某些属性。
尝试使用类似的东西:--filter-properties xattr 或--ignore-transfer-errors。
zfs 接收失败,但快照似乎接收成功。
如果您在不同的操作系统/zfs 版本或功能集之间传输,就会发生这种情况。
尝试使用 --ignore-transfer-errors 选项。这将忽略错误。它仍然会检查快照是否真的被正确接收。
恢复示例
可以使用简单的 zfs 命令进行恢复。例如,使用它来将特定 SmartOS 磁盘映像恢复到临时恢复位置:
root@fs1:/home/psy# zfs send fs1/zones/backup/zfsbackups/smartos01.server.com/zones/a3abd6c8-24c6-4125-9e35-192e2eca5908-disk0@smartos01_fs1-20160110000003 | ssh root@2.2.2.2 "zfs recv zones/restore"
之后,您可以将磁盘映像从临时位置重命名为您创建的新 SmartOS 机器的位置。
使用 Zabbix-jobs 进行监控
你可以使用我的 zabbix-jobs 脚本来监控备份。(https://github.com/psy0rz/stuff/tree/master/zabbix-jobs)
将此命令直接放在 cronjob 中的 zfs_backup 命令之后:
zabbix-job-status backup_smartos01_fs1 daily $?
这将使用退出代码更新 zabbix 服务器,并且还会在作业未运行超过 2 天时提醒您。
使用 HA 复制备份 proxmox 集群
由于 proxmox 的性质,我们不得不对 zfs-autobackup 进行一些改进。这可能也会使其他系统受益,这些系统将自己的复制与 zfs-autobackup 结合使用。
rpool/data 下的所有数据都可以在集群的多个节点上。这些文件系统的命名在整个集群中是唯一的。因此,我们应该将所有节点的 rpool/data 备份到同一目的地。这样我们就不会对被复制的文件系统进行重复备份。由于有多种选择,您甚至可以迁移主机,zfs-autobackup 就可以了。(它会自动从新节点获取下一次备份)
在下面的示例中,我们有 3 个节点,分别命名为 pve1、pve2 和 pve3。
准备 proxmox 节点
无需准备,脚本会处理一切。您只需要设置 ssh 密钥,以便备份服务器可以访问 proxmox 服务器。
提示:确保您的备份服务器有防火墙,并且无法从任何生产机器访问。
备份服务器上的 SSH 配置
我使用 ~/.ssh/config 来指定如何访问各个主机。
在此示例中,我们正在制作一个异地副本并使用端口转发来访问 proxmox 机器:
Host *
ControlPath ~/.ssh/control-master-%r@%h:%p
ControlMaster auto
ControlPersist 3600
Compression yes
Host pve1
Hostname some.host.com
Port 10001
Host pve2
Hostname some.host.com
Port 10002
Host pve3
Hostname some.host.com
Port 10003
备份脚本
我在备份服务器上使用以下备份脚本。
根据您的需要调整变量 HOSTS TARGET 和 NAME。
#!/bin/bash
HOSTS="pve1 pve2 pve3"
TARGET=rpool/pvebackups
NAME=prox
zfs create -p $TARGET/data &>/dev/null
for HOST in $HOSTS; do
echo "################################### RPOOL $HOST"
# enable backup
ssh $HOST "zfs set autobackup:rpool_$NAME=child rpool/ROOT"
#backup rpool to specific directory per host
zfs create -p $TARGET/rpools/$HOST &>/dev/null
zfs-autobackup --keep-source=1d1w,1w1m --ssh-source $HOST rpool_$NAME $TARGET/rpools/$HOST --clear-mountpoint --clear-refreservation --ignore-transfer-errors --strip-path 2 --verbose --no-holds $@
zabbix-job-status backup_$HOST""_rpool_$NAME daily $? >/dev/null 2>/dev/null
echo "################################### DATA $HOST"
# enable backup
ssh $HOST "zfs set autobackup:data_$NAME=child rpool/data"
#backup data filesystems to a common directory
zfs-autobackup --keep-source=1d1w,1w1m --ssh-source $HOST data_$NAME $TARGET/data --clear-mountpoint --clear-refreservation --ignore-transfer-errors --strip-path 2 --verbose --ignore-replicated --min-change 300000 --no-holds $@
zabbix-job-status backup_$HOST""_data_$NAME daily $? >/dev/null 2>/dev/null
done
该脚本还会将备份状态发送到 Zabbix。(如果你安装了我的 zabbix-job-status 脚本https://github.com/psy0rz/stuff/tree/master/zabbix-jobs)
赞助商名单
该项目由以下机构赞助:
- JetBrains(向我提供了他们整个专业产品线的许可证,https://www.jetbrains.com/pycharm/)