LVM对LV提供的快照功能,只对LVM有效,但是个人认为,能用到LVM的地方大多是企业,而企业要是对数据真的很在意,推荐还是买一款具快照功能的存储设备,价格也不是很贵,主要是创建和恢复快照比较方便图形化下就可以操作,专业的设备做专业的事。
LVM快照原理
当一个snapshot创建的时候,仅拷贝原始卷里数据的元数据(meta-data)。创建的时候,并不会有数据的物理拷贝,因此snapshot的创建几乎是实时的,当原始卷上有写操作执行时,snapshot跟踪原始卷块的改变,这个时候原始卷上将要改变的数据在改变之前被拷贝到snapshot预留的空间里,因此这个原理的实现叫做写时复制(copy-on-write)。如果源卷的变化达到1GB这么大,快照卷就会消耗掉1G的容量来存放改变的数据。
创建snapshot的大小并不需要和原始卷一样大,其大小仅仅只需要考虑两个方面:从shapshot创建到释放这段时间内,估计块的改变量有多大;数据更新的频率。一旦 snapshot的空间记录满了原始卷改变的数据,那么这个snapshot立刻被释放,从而无法使用,从而导致这个snapshot无效,避免这种事情的发生,第一种解决办法是刚创建完快照之后,立即把快照区中的内容进行备份,这样就不用时刻考虑快照区会失效了,因为我们已经把他的数据备份走了。第二种解决办法是,如果快照卷的存储空间就要殆尽,我们可以使用lvextend来扩容快照卷,前提是所在的卷组必须有足够的剩余空间。同样我们也可以缩减快照所占用卷的大小,可以使用lvreduce。第三种简单粗暴的方法就是创建一个和原始lv一样大小的快照区,这样就不用担心数据变化量的因素了。
创建快照实际上也是创建了一个逻辑卷,只不过该卷的属性与普通逻辑卷的属性有些不一样。我们可以通过下图来理解快照数据卷(图中的实线框表示快照区域,虚线框表示文件系统):
左图为最初创建的快照数据卷状况,LVM 会预留一个区域 (比如左图的左侧三个 PE 区块) 作为数据存放处。 此时快照数据卷内并没有任何数据,而快照数据卷与源数据卷共享所有的 PE 数据, 因此你会看到快照数据卷的内容与源数据卷中的内容是一模一样的。 等到系统运行一阵子后,假设 A 区域的数据被更新了(上面右图所示),则更新前系统会将该区域的数据移动到快照数据卷中, 所以在右图的快照数据卷中被占用了一块 PE 成为 A,而其他 B 到 I 的区块则还是与源数据卷共享!
由於快照区与原本的 LV 共享很多 PE 区块,因此快照区与被快照的 LV 必须要在同一个 VG 上头,下面两点非常重要:
VG中需要预留存放快照本身的空间,不能全部被占满。
快照所在的 VG 必须与被备份的 LV 相同,否则创建快照会失败。
创建 LVM 快照
一,快照创建举例:
1、查看准备创建快照的LV的大小
-----------------------------------------------------
root@debian:~# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv0 vg0 -wi-a----- 2.00g #这里对lv0进行快照
lv1 vg0 -wi-a----- 1.00g
-----------------------------------------------------
2、查看准备创建快照的LV所在的VG是否有剩余空间
-----------------------------------------------------
root@debian:~# vgs
VG #PV #LV #SN Attr VSize VFree
vg0 1 2 0 wz--n- 5.00g 2.00g #vg0剩余容量
-----------------------------------------------------
3、创建快照,快照卷的名字为lv0snap1,大小为2G,源卷是否为挂在状态都可以创建快照
-----------------------------------------------------
root@debian:~# lvcreate -s -L 2G -n lv0snap1 /dev/vg0/lv0
Using default stripesize 64.00 KiB.
Volume group "vg0" has insufficient free space (511 extents): 512 required.
#2G创建提示VG0剩余空间不足,但是VG0显示剩余为2G,这是因为用G描述的单位比较大,当剩余空间不足时,不能你精确的描述
root@debian:~# lvcreate -s -l 200 -n lv0snap1 /dev/vg0/lv0 #通过PE数来创建
Using default stripesize 64.00 KiB.
Logical volume "lv0snap1" created.
-----------------------------------------------------
-s 关键选项,创建快照snap的意思
-l 后面跟快照包含多少个PE的数量
-L 后面跟快照大小的容量
-n 后面跟创建的快照的名字
命令最后记得加创建的快照的原始lv全名称
注意:其实快照就是一个特殊类型的数据卷,所以创建快照的命令和创建数据卷的命令相同,也是 lvcreate
4、查看创建的快照
-----------------------------------------------------
root@debian:~# lvdisplay /dev/vg0/lv0snap1
--- Logical volume ---
LV Path /dev/vg0/lv0snap1
LV Name lv0snap1
VG Name vg0
LV UUID PGKdU5-k7FQ-CfoG-3KqT-bOOY-C06r-OwWmFI
LV Write Access read/write
LV Creation host, time debian, 2019-09-22 16:30:03 +0800 #快照创建时间。这个很重要,因为快照将跟踪此时间之后的每个改变
LV snapshot status active destination for lv0 #该快照属于lv0逻辑卷
LV Status available #逻辑卷在线并可用
# open 0
LV Size 2.00 GiB #这个表示的是原卷的大小,就是lv0的大小,而不是快照卷的实际大小
Current LE 512
COW-table size 800.00 MiB #这个快照能够记录的最大容量,也是这个快照卷的实际大小,这里要特别注意
COW-table LE 200 #这个快照能够记录的最大容量,通过LE显示
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 254:4
root@debian:~# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv0 vg0 owi-aos--- 2.00g
lv0snap1 vg0 swi-a-s--- 800.00m lv0 0.00 #快照的实际容量
lv1 vg0 -wi-a----- 1.00g
-----------------------------------------------------
二、扩展快照卷
-----------------------------------------------------
root@debian:~# lvextend -l 300 /dev/vg0/lv0snap1 #通过lvextend命令扩展快照卷
Size of logical volume vg0/lv0snap1 changed from 800.00 MiB (200 extents) to 1.17 GiB (300 extents).
Logical volume vg0/lv0snap1 successfully resized.
root@debian:~# lvdisplay /dev/vg0/lv0snap1
--- Logical volume ---
LV Path /dev/vg0/lv0snap1
LV Name lv0snap1
VG Name vg0
LV UUID PGKdU5-k7FQ-CfoG-3KqT-bOOY-C06r-OwWmFI
LV Write Access read/write
LV Creation host, time debian, 2019-09-22 16:30:03 +0800
LV snapshot status active destination for lv0
LV Status available
# open 1
LV Size 2.00 GiB
Current LE 512
COW-table size 1.17 GiB #快照卷的容量已经增加
COW-table LE 300
Allocated to snapshot 0.01%
Snapshot chunk size 4.00 KiB
Segments 2
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 254:4
root@debian:~#
-----------------------------------------------------
三、对源卷的某个文件的内容改变,来测试快照是否有效
-----------------------------------------------------
root@debian:~# df -h #查看源卷的挂在点
文件系统 容量 已用 可用 已用% 挂载点
..........
/dev/mapper/vg0-lv0 2.0G 3.1M 1.9G 1% /mnt/lv0
root@debian:~# ls -l /mnt/lv0/ #查看源卷的内容
总用量 20
-rw-r--r-- 1 root root 16 9月 6 14:16 idid #mtime时间为9月6号14:16
drwx------ 2 root root 16384 9月 6 14:14 lost+found
root@debian:~#
root@debian:~# cat /mnt/lv0/idid #查看idid文件的
ewofh[ewihfqeo
root@debian:~# echo "12345" > /mnt/lv0/idid #更改文件的内容来测试快照是否有效
root@debian:~# cat /mnt/lv0/idid
12345 #文件内容已经更改
root@debian:~# touch /mnt/lv0/123 #创建一个新文件
-----------------------------------------------------
四、挂载镜像卷
-----------------------------------------------------
root@debian:~# mount -o ro /dev/vg0/lv0snap1 /mnt/lv0snap1/ #挂载镜像卷为只读
root@debian:~# df -hT
文件系统 类型 容量 已用 可用 已用% 挂载点
.........
/dev/mapper/vg0-lv0 ext4 2.0G 3.1M 1.9G 1% /mnt/lv0
/dev/mapper/vg0-lv0snap1 ext4 2.0G 3.1M 1.9G 1% /mnt/lv0snap1
root@debian:~# blkid /dev/vg0/lv0 #查看lv0的UUID
/dev/vg0/lv0: UUID="e852fce7-c6d7-4de5-9a60-aa6b2537469f" TYPE="ext4"
root@debian:~# blkid /dev/vg0/lv0snap1 #查看lv0快照的UUID
/dev/vg0/lv0snap1: UUID="e852fce7-c6d7-4de5-9a60-aa6b2537469f" TYPE="ext4"
root@debian:~# ls -l /mnt/lv0snap1/ #新创建的123文件没有出现
总用量 20
-rw-r--r-- 1 root root 16 9月 6 14:16 idid #mtime的时间还是以前的
drwx------ 2 root root 16384 9月 6 14:14 lost+found
root@debian:~#
root@debian:~# cat /mnt/lv0snap1/idid
ewofh[ewihfqeo #显示的还是以前的内容,说明快照成功
root@debian:~#
-----------------------------------------------------
注意:上面我们可以看到被挂在的快照卷和源卷的大小一样,这是因为快照卷的元数据和源卷的元数据一样,卷的UUID也是一样的,如果源卷的文件系统为XFS时候挂在快照卷还要添加”-o nouuid“的参数,让文件系统忽略相同的UUID造成的问题,因为XFS不允许相同的UUID文件系统挂载。
五、恢复快照,还原部分数据
如果我们明确的知道需要还原某个文件,可以向上面一样挂载快照数据卷,直接拷贝其中旧版本的文件即可,但是在用cp命令复制数据的时候加上-p参数这样就会保留源文件或目录的属性。这里就不举例了
六、恢复快照,还原整个数据卷上的数据
恢复的方法有下面几种:
1、挂载快照数据卷-->通过tar命令把快照中的所有数据导出到另外一个数据卷上,这个数据卷既不是源数据卷也不是快照数据卷-->卸载并用lvremove命令删除快照数据卷-->卸载源数据卷,格式化后重新挂载-->把备份的数据还原到源数据卷
2、上面的是用的打包压缩的方式进行备份还原,当然用cp命令的方式也一样,请注意mtime时间不要改变
3、使用dd或dump配备整个文件系统,在进行还原。xfs用xfsdump命令
七、上面的这些方法都需要占用另外的介质进行过度,快照卷容量小还行如果很大的话会很痛苦,我们可以通过 lvconvert 命令配合其 --merge 选项一把搞定整个数据卷的还原,也就是合并快照卷。下面演示该方法的主要步骤。
1、卸载源数据卷
合并快照的操作也需要卸载源数据卷,如果快照卷已经挂载也需要卸载
-----------------------------------------------------
root@debian:~# umount /dev/vg0/lv0
root@debian:~# umount /dev/vg0/lv0snap1
root@debian:~# df -h #查看是否都卸载
文件系统 容量 已用 可用 已用% 挂载点
udev 991M 0 991M 0% /dev
tmpfs 201M 3.5M 198M 2% /run
/dev/sda1 18G 3.2G 14G 19% /
tmpfs 1003M 0 1003M 0% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 1003M 0 1003M 0% /sys/fs/cgroup
tmpfs 201M 4.0K 201M 1% /run/user/112
tmpfs 201M 12K 201M 1% /run/user/1000
root@debian:~#
1、合并快照,也就是恢复快照
确认源数据卷和快照数据卷都没有被挂载后就可以执行合并快照的操作了,注意,合并快照的操作会自动删除快照数据卷
-----------------------------------------------------
root@debian:~# lvconvert --merge /dev/vg0/lv0snap1 #--merge参数后面接要恢复的快照卷全路径即可
Merging of volume vg0/lv0snap1 started.
lv0: Merged: 99.99%
lv0: Merged: 100.00% #恢复成功
root@debian:~# lvs #查看快照卷是否删除
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv0 vg0 -wi-a----- 2.00g #源数据就大小没有变化
lv1 vg0 -wi-a----- 1.00g
#快照卷已经删除
2、重新挂载源数据卷,查看是否恢复成功
root@debian:~# mount /dev/vg0/lv0 /mnt/lv0
root@debian:~# ls -l /mnt/lv0
总用量 20
-rw-r--r-- 1 root root 16 9月 6 14:16 idid #mtime的时间还是以前的
drwx------ 2 root root 16384 9月 6 14:14 lost+found
root@debian:~# cat /mnt/lv0/idid
ewofh[ewihfqeo #恢复成功
root@debian:~#