DIY NAS系列07 — ZFS 快照管理
本文最后更新于 183 天前,其中的信息可能已经有所发展或是发生改变。

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 快照说明。
Avatar photo

关于 木子

Founder of the Rocky Linux Chinese community, MVP、VMware vExpert、TVP, advocate for cloud native technologies, with over ten years of experience in site reliability engineering (SRE) and the DevOps field. Passionate about Cloud Computing、Microservices、CI&CD、DevOps、Kubernetes, currently dedicated to promoting and implementing Rocky Linux in Chinese-speaking regions.
用一杯咖啡支持我们,每一篇 [文档] 都经过我们实操,并非从网上一味的copy,期间花费了大量的心思,希望能够帮忙到您。
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇