因为很多的快照技术都是在存储设备上(如基于磁盘阵列的、基于NAS的),所以很多快照方法都接触不到,本文主要是介绍我接触到COW和ROW两种快照原理的使用。
环境
LVM快照和ECS打快照环境:
阿里云ECS:
Intel Xeon(Cascade Lake) Platinum 8269
4c16g
系统盘 40g ext4
LVM卷
500g的SSD云盘 两个分区
500g的SSD云盘 整块磁盘
Centos 7.6
内核:3.10.0-957.21.3.el7.x86_64
一、LVM逻辑卷快照的使用
LVM快照的原理是COW(copy on write),下面以迁移MongoDB为例(命令都是来自MongoDB官方文档)。
注意:
- 从MongoDB3.2开始,不再需要数据文件和journal log在同一个卷上,但是为了得到一致性备份,LVM备份期间数据库需要处于锁定状态。
如果数据文件和journal log是在同一个卷上,则不需要锁定。 - 确保创建快照的时候预留的空间足够后续的写入空间。
1.1 基础环境
[root@test:/data1]#df -Ph
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 4.1G 34G 11% /
devtmpfs 7.7G 0 7.7G 0% /dev
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 7.7G 656K 7.7G 1% /run
tmpfs 7.7G 0 7.7G 0% /sys/fs/cgroup
tmpfs 1.6G 0 1.6G 0% /run/user/0
/dev/mapper/vgmongo-mongodb40000 984G 607G 331G 65% /data1
1.2 创建快照
创建快照是很简单,使用lvcreate带的选项即可,原理就是clone了一份元数据,所以是很快的。
[root@test:/data1]#lvcreate --size 100G --snapshot --name mdb-snap01 /dev/vgmongo/mongodb40000
Volume group "vgmongo" has insufficient free space (253 extents): 25600 required.
需要vg卷上更大的空间
扩容后:
[root@test:/data1]#lvcreate --size 100G --snapshot --name mdb-snap01 /dev/vgmongo/mongodb40000
Logical volume "mdb-snap01" created.
注意:
1. --size指定的大小不是快照的大小,也不反映磁盘数据大小,而是打快照后数据的增长,主要是考虑将快照归档这段时间的数据增长。如果快照空间不足,则此快照将不可用。
1.3归档快照
快照创建完成后,需要将快照数据复制到单独的存储中。
如果挂载了快照,需要先卸载:umount /dev/vg0/mdb-snap01
归档:
[root@test:/data1]#dd if=/dev/vgmongo/mdb-snap01 | gzip > mdb-snap01.gz
莫名报错:
[root@test:/data1]#dd if=/dev/vgmongo/mdb-snap01 | gzip > mdb-snap01.gz
dd: error reading ‘/dev/vgmongo/mdb-snap01’: Input/output error
316780152+0 records in
316780152+0 records out
162191437824 bytes (162 GB) copied, 5515.32 s, 29.4 MB/s
将要备份的逻辑卷里的数据删除到只剩下10G,重新打快照,再进行归档快照:
但是还是失败,这时候看看快照大小:
10个g的数据归档快照的时候有50g,不知道为啥
将逻辑卷里的数据全部删除,再进行打快照:
在进行之前,磁盘情况:
[root@iZbp1af5jdjve7wpjbgeumZ:/data1]#df -Ph
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 4.1G 34G 11% /
devtmpfs 7.7G 0 7.7G 0% /dev
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 7.7G 648K 7.7G 1% /run
tmpfs 7.7G 0 7.7G 0% /sys/fs/cgroup
tmpfs 1.6G 0 1.6G 0% /run/user/0
/dev/mapper/vgmongo-mongodb40000 886G 75M 843G 1% /data1
执行创建命令:
[root@iZbp1af5jdjve7wpjbgeumZ:/data1]#lvcreate --size 20G --snapshot --name mdb-snap02 /dev/vgmongo/mongodb40000
Logical volume "mdb-snap02" created.
再次失败:
[root@iZbp1af5jdjve7wpjbgeumZ:/data1]#dd if=/dev/vgmongo/mdb-snap02 | gzip > mdb-snap02.gz
dd: error reading ‘/dev/vgmongo/mdb-snap02’: Input/output error
49127072+0 records in
49127072+0 records out
25153060864 bytes (25 GB) copied, 859.103 s, 29.3 MB/s
这次里面什么文件都没有:
[root@iZbp1af5jdjve7wpjbgeumZ:/data1]#du -sh *
4.0K a.txt
21G mdb-snap02.gz
打快照的情况:
[root@iZbp1af5jdjve7wpjbgeumZ:/dev/mapper]#ll -ht
total 0
lrwxrwxrwx 1 root root 7 Aug 30 20:15 vgmongo-mongodb40000 -> ../dm-0
lrwxrwxrwx 1 root root 7 Aug 30 19:42 vgmongo-mdb--snap02 -> ../dm-5
lrwxrwxrwx 1 root root 7 Aug 30 19:42 vgmongo-mdb--snap01 -> ../dm-3
lrwxrwxrwx 1 root root 7 Aug 30 19:42 vgmongo-mongodb40000-real -> ../dm-1
lrwxrwxrwx 1 root root 7 Aug 30 19:42 vgmongo-mdb--snap01-cow -> ../dm-2
lrwxrwxrwx 1 root root 7 Aug 30 19:42 vgmongo-mdb--snap02-cow -> ../dm-4
1.4 重新使用虚拟机打快照
怀疑可以是ECS做了LVM后再打快照可能会有问题,毕竟其本身就带有快照和镜像服务,下面使用自己的虚拟机来进行创建和归档快照。
环境:
2c1g
系统盘 50g LVM
LVM卷
20g 整块磁盘
20g 整块磁盘
Centos 7.6
内核:3.10.0-957.el7.x86_64
[root@vm21:/data1]#df -Ph
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 47G 1.8G 46G 4% /
devtmpfs 475M 0 475M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.7M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/sda1 1014M 135M 880M 14% /boot
tmpfs 98M 0 98M 0% /run/user/0
/dev/mapper/vgmongo-mongodb40000 30G 45M 28G 1% /data1
目录下只有一个文档,创建快照:
[root@vm21:/data1]#lvcreate --size 1G --snapshot --name mdb-snap01 /dev/vgmongo/mongodb40000
Logical volume "mdb-snap01" created.
到其他路径下去归档快照:
可以发现的是,是copy的全部的数据32GB:
[root@vm21:/]#dd if=/dev/vgmongo/mdb-snap01 | gzip > mdb-snap01.gz
62914560+0 records in
62914560+0 records out
32212254720 bytes (32 GB) copied, 366.044 s, 88.0 MB/s
归档快照大小是:
[root@vm21:/]#du -sh mdb-snap01.gz
30M mdb-snap01.gz
1.5 恢复快照
创建一个新的lv卷:要求lv卷必须比原来的数据卷的空间大。
[root@vm4 ~]#lvcreate -L 40G -n lv0 vg0
Logical volume "lv0" created.
将归档传输到新环境:
[root@vm21:/]#rsync -r mdb-snap01.gz 192.168.1.14:/
解压并进行恢复:
恢复出来的数据大小就是原来的磁盘数据大小:
[root@vm4 /]#gzip -d -c mdb-snap01.gz | dd of=/dev/vg0/lv0
62914560+0 records in
62914560+0 records out
32212254720 bytes (32 GB) copied, 641.815 s, 50.2 MB/s
挂载,就可以查看到数据了:
[root@vm4 /]#mount /dev/vg0/lv0 /data1
[root@vm4 /]#cd /data1
[root@vm4 /data1]#ls
a.txt lost+found
1.6 其他
1.6.1 直接归档恢复不压缩
umount /dev/vg0/mdb-snap01
lvcreate --size 1G --name mdb-new vg0
dd if=/dev/vg0/mdb-snap01 of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb
1.6.2 直接归档到远程
umount /dev/vg0/mdb-snap01
dd if=/dev/vg0/mdb-snap01 | ssh username@example.com gzip > /opt/backup/mdb-snap01.gz
或者
dd if==/dev/vgvmhost/vir_w23_x86_56_d | ssh kvm08 "dd of=/opt/images/vir_w23_x86_56_d.img "
lvcreate --size 1G --name mdb-new vg0
ssh username@example.com gzip -d -c /opt/backup/mdb-snap01.gz | dd of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb
二、阿里云ECS快照的使用
阿里云的ECS提供的快照功能,我也不清楚是在什么层级实现的,只知道原理是ROW(redirect on write),这里以上面挂了三块数据盘做成LVM的ECS为例,看如何使用快照进行迁移数据。
2.1 打镜像
镜像可以认为是整个服务器的一个副本,因为涉及到多块盘,所以为了得到一个一致性的快照,需要使用ECS的镜像功能。
至于镜像的更多知识,如怎么打镜像,怎么使用镜像迁移,这个以后再写。
当然,如果只是对数据盘打快照,该磁盘可以在创建实例的时候根据该数据盘创建磁盘。
根据图片知道,打镜像也是先打快照,然后再生成镜像。
2.2 快照的信息
创建镜像后大概一分钟数据量:2883155
初始大概每块盘100G的数据的时候,给数据盘打快照需要3个小时;
第二次10:30开始打镜像:这时候写了600多G的数据
12:00时候信息如下:一块磁盘已经写满了,一块磁盘还有100G的空间
打完镜像后看快照的数据量:
2.3 使用镜像启动实例
使用镜像启动新实例:
2.4 挂载启动
删除lock文件,否则会导致错误
rm -f mongod.lock
这点在mongodb的官方文档也有说到。
三、总结
**3.1 使用ECS进行LVM快照备份会有一些问题,原因未知。快照备份出来的是有过更改的块,但是恢复的时候需要磁盘不小于进行备份的磁盘大小(不管是LVM快照还是ECS的快照备份)。
3.2 用ECS对多块盘打快照要先打镜像,这样可以得到一致性的快照,使用也比较方便,可以跨账号共享。**
参考:
https://docs.mongodb.com/manual/tutorial/backup-with-filesystem-snapshots/