ZFS 快照简介
ZFS 快照是存储池某个时间点的只读副本。与其他文件系统的快照方法不同,ZFS 快照不需要复制或移动数据,因此创建和删除快照非常快,且不会对系统性能产生大的影响。此外,因为 ZFS 快照只存储自快照创建后数据的改变,所以它们使用的空间非常小。
ZFS 快照工作原理基于 ZFS 的 copy-on-write 机制。在 ZFS 中,当数据被修改时,ZFS 不是直接覆盖原有的数据,而是在不同的位置写入新的数据。只有在新的数据成功写入后,ZFS 才会更新指向这些数据的指针。这种机制保证了 ZFS 操作的原子性,防止了数据的部分写入,从而保证了数据的一致性。
当创建 ZFS 快照时,ZFS 会保留一个指向当前数据状态的指针。这意味着即使数据被修改,原有的数据仍然可以通过快照访问。因此,ZFS 快照只需要存储自快照创建后数据的改变,而原有的数据则由存储池和所有的快照共享。
ZFS 快照有许多用途。例如,您可以使用快照来保护数据,防止误删除或误修改。您也可以使用快照来创建数据的历史版本,以便于恢复旧的数据或分析数据的变化。此外,ZFS 还允许您将快照发送到远程的 ZFS 系统,这可以用于数据备份或复制。
ZFS 快照管理
这里基于 SSD 文件系统来简单说一下快照管理。
# 查看文件系统,已经存在 SSD 文件系统
[root@localhost ~]# df -lh
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 3.1G 8.8M 3.1G 1% /run
/dev/mapper/rl-root 70G 3.7G 67G 6% /
/dev/sdb2 1014M 303M 712M 30% /boot
/dev/sdb1 599M 7.0M 592M 2% /boot/efi
/dev/mapper/rl-home 145G 1.1G 144G 1% /home
tmpfs 1.6G 4.0K 1.6G 1% /run/user/0
SSD 3.6T 128K 3.6T 1% /SSD
# 添加一个文件
[root@localhost SSD]# echo "123" > 1.txt
# 查看文件是存在的
[root@localhost SSD]# ls -l
total 2
-rw-r--r-- 1 root root 4 Jun 15 20:36 1.txt
# 创建快照,这里是基于 SSD 这个文件系统或卷创建快照,并非 SSD 存储池创建快照。
[root@localhost SSD]# zfs snap SSD@snap20230615
# 查看快照信息
[root@localhost SSD]# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
SSD@snap20230615 0B - 35.9K -
# 删除对应文件
[root@localhost SSD]# rm -rf 1.txt
# 文件已经没有了
[root@localhost SSD]# ll
total 0
# 回滚快照
[root@localhost SSD]# zfs rollback SSD@snap20230615
# 文件恢复
[root@localhost SSD]# ll
total 2
-rw-r--r-- 1 root root 4 Jun 15 20:36 1.txt
# 删除快照
[root@localhost SSD]# zfs destroy SSD@snap20230615
# 克隆快照与快照不同,克隆快照可以编辑管理文件,快照是只读的。
# 克隆快照,需要先创建一个快照,再进行克隆
[root@localhost SSD]# zfs snap SSD@snap20230615
[root@localhost SSD]# zfs clone SSD@snap20230615 SSD/my_clone
# 查看克隆
[root@localhost /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
SSD 360K 3.52T 35.9K /SSD
SSD/my_clone 0B 3.52T 35.9K /SSD/my_clone
# 克隆以后就会自动创建对应文件系统
[root@localhost SSD]# df -lh
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 3.1G 8.8M 3.1G 1% /run
/dev/mapper/rl-root 70G 3.7G 67G 6% /
/dev/sdb2 1014M 303M 712M 30% /boot
/dev/sdb1 599M 7.0M 592M 2% /boot/efi
/dev/mapper/rl-home 145G 1.1G 144G 1% /home
tmpfs 1.6G 4.0K 1.6G 1% /run/user/0
SSD 3.6T 128K 3.6T 1% /SSD
SSD/my_clone 3.6T 128K 3.6T 1% /SSD/my_clone
# 进入对应目录
[root@localhost SSD]# cd /SSD/my_clone
# 向 1.txt 文件中添加数据
[root@localhost my_clone]# echo "789" >> 1.txt
# 查看文件已经更改
[root@localhost my_clone]# cat 1.txt
123
456
789
# 但我们查看原有/SSD/1.txt没有变化
[root@localhost my_clone]# cat /SSD/1.txt
123
456
# 删除快照克隆
[root@localhost /]# zfs destroy SSD/my_clone
Shell 脚本快照自动管理
因为木子的数据备份采用是 rsync
同步备份(会进行同步删除),有时候难免出现文件误删除想恢复等情况,使用 ZFS 快照就可以更好的保障这一点。在网上看了很多开源的 ZFS 快照管理工具,像 zfs-periodic、zfs-snapshot-mgmt、zfsnap2、zfstools 等,有些过于复杂,有些相对简单,都不太符合需求,所以决定自己写一个脚本来实现简单的快照自动管理。zfs_auto_snap.sh
脚本主要实现每 30 分钟创建一个新的快照,并同时检测有没有超过 30 天的快照,如果存在超过 30 天的快照,自动删除对应快照。
[root@demo Script]# cat > zfs_auto_snap.sh << \EOF
#!/bin/bash
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
# 设置 ZFS 文件系统和快照前缀
ZFS_DATASET="SSD"
SNAPSHOT_PREFIX="snap"
# 获取当前日期的时间戳
CURRENT_DATE=$(/usr/bin/date +%s)
# 创建新的快照
new_snapshot="$ZFS_DATASET@$SNAPSHOT_PREFIX$(/usr/bin/date +%Y%m%d%H%M)"
# 如果您有多个子文件系统,可以使用 -r 进行递归快照,如果有多个父文件系统,还需要调整整个脚本,或者创建多个计划任务。
/usr/sbin/zfs snapshot -r "$new_snapshot"
# 列出所有ZFS快照
snapshot_list=$(/usr/sbin/zfs list -H -t snapshot -o name -r "$ZFS_DATASET")
# 循环处理每个快照
while IFS= read -r snapshot; do
# 获取快照创建时间并转换为时间戳
snapshot_creation_date=$(/usr/bin/date -d "$(/usr/sbin/zfs get -H -o value creation "$snapshot")" +%s)
# 计算快照存在的天数
days_difference=$(( (CURRENT_DATE - snapshot_creation_date) / (60*60*24) ))
# 如果超过30天,删除快照
if [ "$days_difference" -gt 30 ]; then
echo "Deleting snapshot: $snapshot"
/usr/sbin/zfs destroy "$snapshot"
fi
done <<< "$snapshot_list"
EOF
# 设置计划任务
[root@demo Script]# crontab -l
*/30 * * * * /root/Script/zfs_auto_snap.sh
# 检测快照情况
[root@demo Script]# zfs list -H -t snapshot
SSD@snap202401200700 2.74M - 119G -
SSD@snap202401200730 2.93M - 119G -
SSD@snap202401200800 1.95M - 119G -
SSD@snap202401200830 1.96M - 119G -
ZFS 快照说明
刚好有群友提到快照的问题,用过 TrueNAS 的朋友可能会发现,创建快照 Web 管理界面写的是基于数据集(DATASET),包括很多比较权威的资料上也是这样写的,从木子个人理解来说,不应该叫作数据集。因为数据集是文件系统、卷、快照的统称,而我们在进行快照的时候,实际上是对文件系统和卷进行快照,并不会对快照进行再次快照,所以更加合理的说话应该是对文件系统与卷进行快照。这个我们在查看 zfs snapshot
帮助时候也可以看到。
[root@demo ~]# zfs snapshot
missing snapshot argument
usage:
snapshot [-r] [-o property=value] ... <filesystem|volume>@<snap> ...
For the property list, run: zfs set|get
For the delegated permission list, run: zfs allow|unallow
写在最后
在这篇文章中,我们对 ZFS 快照的工作原理和应用进行了深入的探讨。希望这些信息能帮助您更好地理解和利用 ZFS 快照来保护和管理您的数据。然而,ZFS 的功能远不止于此,快照只是其中的一部分。
在 ZFS 中,除了文件系统和快照,还有一个重要的概念,那就是“卷”。卷是一个可以作为块设备使用的存储实体,它们在一些特定的场景下,如虚拟化,数据库存储等,都有非常重要的作用。
在下一篇文章中,我们将聚焦于 ZFS 的卷管理,从创建和配置卷,到理解卷如何与文件系统和快照交互,我们将带领您深入了解这一重要特性。让我们期待下一篇文章,继续探索 ZFS 的世界。
变更记录
- 2024-01-20
- 新增 ZFS 快照自动管理脚本。
- 2024-01-22
- 新增 ZFS 快照说明。