Linux LVM快照的建立和恢复(附带实例)
LVM 还有一个常用功能,就是 LVM 快照。
我们可以把 LVM 快照理解为虚拟机的快照,二者的共同点在于都把当前状态保存下来,如果发生了修改,可以恢复快照中的数据,就能保证数据不丢失。
当我们给原始 LV 建立一个快照时,快照区中只写入被快照 LV 的“元数据”。元数据是 LVM 的必备数据,主要记录 VG 相关数据、LV 相关数据等,如下图所示。

图 1 快照卷使用前
当 LV 中有文件被修改时,LV 和快照卷会发生变化,如下图所示:

图 2 快照卷使用后
图 1 表示创建快照后的情况,快照区不会真实地复制被快照 LV 中的数据,只是记录了被快照 LV 的元数据。此时快照区的 PE 是空白的,快照区共享了被快照 LV 中的 PE。因此,会看到快照区与被快照 LV 的大小一致,存储的数据也完全相同。
图 2 表示当 LV 中的数据被修改时,被快照 LV 在数据写入前,会先把原始数据在快照区中进行保存。如图 2 中所示,在 A 文件被修改成 A(New)之前,会先将 A 文件备份至快照区的 PE 中,然后被快照 LV 中的数据才会更新为 A(New),无论被快照 LV 中的数据如何变化,快照中保存的都是快照创建时的数据。
需要注意的是,快照也是有大小限制的。如果被快照 LV 中的数据变化量小于快照区能保存的数据量,那么快照正常生效。但是,如果被快照 LV 中的数据变化量大于快照区能保存的数据量,那么快照区会失效。为了解决这个问题,建议尽可能将快照区的空间大小和被快照 LV 的空间大小设置得相同。
/etc/issue 是系统中默认存在的登录信息提示文件,当前用于测试快照卷效果。
接下来创建 LVM 快照,依然使用 lvcreate 命令,具体如下:
在创建快照之前,我们需要查看 myvg 卷组中的剩余可用空间:
我们给 mylv 逻辑卷创建一个 2GB 的快照空间。快照卷名为 mysna,命令如下:
创建完成,进行查看:
在快照创建完成后,同样要在挂载之后才能正常使用,命令如下:
挂载之后,查询被快照 LV 和快照卷的空间使用情况:
我们先给被快照 LV 中的某个文件增加数据:
在字符串写入 issue 文件后,旧的 issue 文件才被真正地保存到快照卷(mysna)中,写入字符串后的新 issue 文件被保存到被快照 LV(mylv)中。此时,如果想要进行数据恢复,那么只要将快照卷中的旧 issue 文件还原,覆盖被快照 LV 中的新 issue 文件即可。
为了便于理解,我们用示意图来解释快照卷的文件保存和数据恢复过程,在镜像卷创建后,如下图所示:

图 3 快照卷未使用
修改 mylv 分区中的 issue 文件,如下图所示:

图 4 逻辑卷修改文件
修改后,mylv 分区中原有的旧 issue 文件被保存到 mysna 快照卷中,如下图所示:

图 5 快照区变化
接下来我们会看到,出现在 /dev/myvg/mylv 中的是修改后的新文件,出现在 /dev/myvg/mysna 中的是修改前的旧文件,如下图所示。

图 6 使用快照区恢复
此时,如果想要进行数据恢复,就只要使用 /dev/myvg/mysna 中的旧文件覆盖 /dev/myvg/mylv 中的新文件即可。
在实际工作中,分区不可能只有一个文件,并且通常也无法确定用户会修改分区中的哪个文件,如果修改了大量的文件,就需要快照分区具有足够的空间来保存所有被修改文件的旧文件。只有把快照区创建得和被快照 LV 一样大,才不用考虑快照失效问题,真正利用快照来保护数据。
我们可以把 LVM 快照理解为虚拟机的快照,二者的共同点在于都把当前状态保存下来,如果发生了修改,可以恢复快照中的数据,就能保证数据不丢失。
LVM快照原理
在 LVM 中,要想创建快照,需要注意:快照区和被快照的 LV 必须处于同一个 VG 中,因为快照区与被快照的 LV 有很多物理扩展(PE)是通用的。这种情况是怎么造成的呢?我们需要解释一下 LVM 快照的原理。当我们给原始 LV 建立一个快照时,快照区中只写入被快照 LV 的“元数据”。元数据是 LVM 的必备数据,主要记录 VG 相关数据、LV 相关数据等,如下图所示。

图 1 快照卷使用前
当 LV 中有文件被修改时,LV 和快照卷会发生变化,如下图所示:

图 2 快照卷使用后
图 1 表示创建快照后的情况,快照区不会真实地复制被快照 LV 中的数据,只是记录了被快照 LV 的元数据。此时快照区的 PE 是空白的,快照区共享了被快照 LV 中的 PE。因此,会看到快照区与被快照 LV 的大小一致,存储的数据也完全相同。
图 2 表示当 LV 中的数据被修改时,被快照 LV 在数据写入前,会先把原始数据在快照区中进行保存。如图 2 中所示,在 A 文件被修改成 A(New)之前,会先将 A 文件备份至快照区的 PE 中,然后被快照 LV 中的数据才会更新为 A(New),无论被快照 LV 中的数据如何变化,快照中保存的都是快照创建时的数据。
需要注意的是,快照也是有大小限制的。如果被快照 LV 中的数据变化量小于快照区能保存的数据量,那么快照正常生效。但是,如果被快照 LV 中的数据变化量大于快照区能保存的数据量,那么快照区会失效。为了解决这个问题,建议尽可能将快照区的空间大小和被快照 LV 的空间大小设置得相同。
建立LVM快照
在创建 LVM 快照之前,我们先创建逻辑卷并向被快照 LV 中写入一些测试数据,具体如下:[root@localhost ~]# lvcreate myvg -n mylv -L 10G Logical volume "mylv" created. #因为之前的操作中删除了 LV,所以再次创建 LV [root@localhost ~]# mkfs.xfs /dev/myvg/mylv #格式化 [root@localhost ~]# mount /dev/myvg/mylv /disk1/ #挂载到/disk1/目录 [root@localhost ~]# cp /etc/issue /disk1/ [root@localhost ~]# cat /disk1/issue \S Kernel \r on an \m #向 LV 中写入一些测试文件
/etc/issue 是系统中默认存在的登录信息提示文件,当前用于测试快照卷效果。
接下来创建 LVM 快照,依然使用 lvcreate 命令,具体如下:
[root@localhost ~]# lvcreate [选项] [-n 快照名] 逻辑卷名选项:
- -s:建立快照,snapshot 的意思;
- -L 容量:指定快照大小,单位为 MB、GB、TB 等;
- -l 个数:按照 PE 个数指定快照大小,如果使用就需要换算容量,过于复杂;
- -n 快照名:指定快照的设备文件名。
在创建快照之前,我们需要查看 myvg 卷组中的剩余可用空间:
[root@localhost ~]# vgdisplay myvg #查看 VG 详细信息 --- Volume group --- VG Name myvg System ID Format lvm2 Metadata Areas 3 Metadata Sequence No 6 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 1 Max PV 0 Cur PV 3 Act PV 3 VG Size <39.99 GiB PE Size 4.00 MiB Total PE 10237 Alloc PE / Size 2560 / 10.00 GiB Free PE / Size 7677 / <29.99 GiB #myvg 共有近 40GB 的空间,划分 mylv 使用了 10GB,剩余接近 30GB 空间 VG UUID z5a9E2 - a9vc - 4qPt - heKd - HPlx - w97T - wBlWA1
我们给 mylv 逻辑卷创建一个 2GB 的快照空间。快照卷名为 mysna,命令如下:
[root@localhost ~]# lvcreate -s -L 2G -n mysna /dev/myvg/mylv Logical volume "mysna" created. #给/dev/myvg/mylv 逻辑卷创建一个 2GB 的快照卷,名为 mysna
创建完成,进行查看:
[root@localhost ~]# lvdisplay /dev/myvg/mysna #查看镜像卷详细信息 --- Logical volume --- LV Path /dev/myvg/mysna LV Name mysna VG Name myvg LV UUID wzJal a - tTK - CycN - NE5i - hQ01 - kdsM - 2kFOee LV Write Access read/write LV Creation host, time localhost.localdomain, 2023 - 08 - 24 16:36:31 + 0800 LV snapshot status active destination for mylv LV Status available # open 0 LV Size 10.00 GiB ←LV 大小 Current LE 2560 COW - table size 2.00 GiB ←快照大小 COW - table LE 512 Allocated to snapshot 0.00% ←快照卷占用百分比 Snapshot chunk size 4.00 KiB Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:5
在快照创建完成后,同样要在挂载之后才能正常使用,命令如下:
[root@localhost ~]# mkdir /mysna/ #创建挂载点 [root@localhost ~]# mount -o nouuid /dev/myvg/mysna /mysna/ #挂载快照分区注意,在挂载快照分区的时候,需要使用“-o nouuid”选项,因为快照区和被快照 LV 的 UUID 相同,系统中默认不允许相同 UUID 的分区重复挂载。
挂载之后,查询被快照 LV 和快照卷的空间使用情况:
[root@localhost ~]# df -hT /disk1/ /mysna/ Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/myvg - mylv xfs 10G 104M 9.9G 2% /disk1 /dev/mapper/myvg - mysna xfs 10G 104M 9.9G 2% /mysna #被快照 LV 和快照卷磁盘占用空间一致 [root@localhost ~]# ls -li /disk1/ total 4 -rw - r--r--. 1 root root 23 Aug 24 16:58 issue [root@localhost ~]# ls -li /mysna/ total 4 -rw - r--r--. 1 root root 23 Aug 24 16:58 issue #被快照 LV 和快照卷数据相同、属性相同
使用LVM快照恢复数据
我们来测试一下如何使用 LVM 快照恢复数据。如果被快照 LV 中的数据发生变化,那么无论是数据增加还是数据减少,都可以通过快照区的数据进行恢复。我们先给被快照 LV 中的某个文件增加数据:
[root@localhost ~]# echo "Linux_HB" >> /disk1/issue #使用 echo 的方式随便追加字符串,写入/disk1/issue 文件 [root@localhost ~]# cat /disk1/issue \S Kernel \r on an \m Linux_HB #字符串 Linux_HB 出现在/disk1/issue 文件中,写入成功 [root@localhost ~]# cat /mysna/issue \S Kernel \r on an \m #查看快照卷中的 issue 文件,issue 是修改前的状态 [root@localhost ~]# ls -l /disk1/issue -rw - r--r--. 1 root root 27 Aug 24 17:12 /disk1/issue [root@localhost ~]# ls -l /mysna/issue -rw - r--r--. 1 root root 23 Aug 24 16:58 /mysna/issue #分别查看被快照 LV 和快照卷文件的详细信息通过分别对被快照 LV 的 issue 文件和快照卷的 issue 文件进行查看可以发现,在字符串写入后,2 个文件的时间信息明显不同。逻辑卷中的 issue 是写入文件字符串的时间,快照卷中的 issue 保持了文件原有时间。
在字符串写入 issue 文件后,旧的 issue 文件才被真正地保存到快照卷(mysna)中,写入字符串后的新 issue 文件被保存到被快照 LV(mylv)中。此时,如果想要进行数据恢复,那么只要将快照卷中的旧 issue 文件还原,覆盖被快照 LV 中的新 issue 文件即可。
为了便于理解,我们用示意图来解释快照卷的文件保存和数据恢复过程,在镜像卷创建后,如下图所示:

图 3 快照卷未使用
修改 mylv 分区中的 issue 文件,如下图所示:

图 4 逻辑卷修改文件
修改后,mylv 分区中原有的旧 issue 文件被保存到 mysna 快照卷中,如下图所示:

图 5 快照区变化
接下来我们会看到,出现在 /dev/myvg/mylv 中的是修改后的新文件,出现在 /dev/myvg/mysna 中的是修改前的旧文件,如下图所示。

图 6 使用快照区恢复
此时,如果想要进行数据恢复,就只要使用 /dev/myvg/mysna 中的旧文件覆盖 /dev/myvg/mylv 中的新文件即可。
在实际工作中,分区不可能只有一个文件,并且通常也无法确定用户会修改分区中的哪个文件,如果修改了大量的文件,就需要快照分区具有足够的空间来保存所有被修改文件的旧文件。只有把快照区创建得和被快照 LV 一样大,才不用考虑快照失效问题,真正利用快照来保护数据。