常用Linux命令使用技巧:LVM快照Snapshot备份

快照(snapshot)是LVM所提供的一个非常有用的特性。它的原理是复制 Origin 原始卷的元数据(metadata)来创建一个逻辑卷,并没有复制物理卷上的任何数据, 因此它的创建过程是实时瞬间完成的。快照是特殊类型的逻辑卷,它含有创建时刻所指定的原始逻辑卷的完整数据,您可以操作快照而无需担心数据的变更令备份失效。


LVM 快照利用一种称为“写时复制(COW - Copy-On-Write)”的技术来跟踪和维持其数据的一致性。它的原理比较简单,就是跟踪原始卷上块的改变, 在这些数据被改变之前将其复制到快照自己的预留空间里(顾名思义称为写时复制)。 当对快照进行读取的时候,被修改的数据从快照的预留空间中读取,未修改的数据则重定向到原始卷上去读取,因此在快照的文件系统与设备之间多了一层COW设备。

利用快照您可以冻结一个正在使用中的逻辑卷,然后制作一份冻结时刻的备份,由于这个备份是具有一致性的,因此非常的适合于用来备份实时系统。例如,您的运行中的数据库可能即使在备份时刻也是不允许暂停服务的,那么就可以考虑使用LVM的快照模式,然后再针对此快照来进行文件系统级别或者块设备级别的数据备份。

# lsmod | grep dm; #使用snapshot需要内核模块dm-snapshot;
# modprobe dm-snapshot; #如有需要,必须先加载此模块;

# lvs; # 先查看一下目前LV的大小;
------------------------------------------------------------------------------
  LV       VG         Attr   LSize Origin Snap%  Move Log Copy%  Convert
  LogVol00 VolGroup00 -wi-ao 6.88G                                    
  LogVol01 VolGroup00 -wi-ao 1.00G                                    
  LogVol02 VolGroup00 -wi-ao 4.00G                                    
  LogVol03 VolGroup00 -wi-ao 5.00G                  
------------------------------------------------------------------------------
说明:此实验目标是备份逻辑卷LogVol02,逻辑卷LogVol03挂载于/backup用来存储备份文件;

理论上,您所建立的快照卷的大小应该是原始卷的1.1倍大小,但鉴于创建快照的目的多是为临时备份数据,因此实际使用时可视您的备份速度和数据变更的频繁程度来决定快照卷的大小。例如,您预计完成一个完整备份大概需要1个小时,而在这个时间之内数据变更的大小不会超过100M,那么您就可以安全地创建100M大小的快照卷。

# vgs; # 看看卷组VG够不够空间创建快照;
------------------------------------------------------------------------------
  VG         #PV #LV #SN Attr   VSize  VFree
  VolGroup00   3   4   0 wz--n- 23.81G 7.94G
------------------------------------------------------------------------------
如上所示,目前卷组VolGroup00还有大概8G的空间,足以建立快照;

开始建立逻辑卷VolGroup00/LogVol02的快照(注意这里取1.1倍大小空间):

# lvcreate -L4.4G -s -n LogVol02s VolGroup00/LogVol02;
------------------------------------------------------------------------------
  Rounding up size to full physical extent 4.41 GB
  Logical volume "LogVol02s" created
------------------------------------------------------------------------------

# lvs; # 看看刚创建的快照;
------------------------------------------------------------------------------
  LV        VG         Attr   LSize Origin   Snap%  Move Log Copy%  Convert
  LogVol00  VolGroup00 -wi-ao 6.88G                                      
  LogVol01  VolGroup00 -wi-ao 1.00G                                      
  LogVol02  VolGroup00 owi-ao 4.00G                                      
  LogVol02s VolGroup00 swi-a- 4.41G LogVol02   0.02                      
  LogVol03  VolGroup00 -wi-ao 5.00G                                
------------------------------------------------------------------------------

# lvscan; # 看看刚创建的快照;
------------------------------------------------------------------------------
  ACTIVE            '/dev/VolGroup00/LogVol00' [6.88 GB] inherit
  ACTIVE            '/dev/VolGroup00/LogVol01' [1.00 GB] inherit
  ACTIVE   Original '/dev/VolGroup00/LogVol02' [4.00 GB] inherit
  ACTIVE            '/dev/VolGroup00/LogVol03' [5.00 GB] inherit
  ACTIVE   Snapshot '/dev/VolGroup00/LogVol02s' [4.41 GB] inherit
------------------------------------------------------------------------------

# /bin/ls -1 -d /dev/mapper/VolGroup00-LogVol02s*
------------------------------------------------------------------------------
/dev/mapper/VolGroup00-LogVol02s
/dev/mapper/VolGroup00-LogVol02s-cow
------------------------------------------------------------------------------

快照卷无需做格式化等步骤,可以直接对快照卷进行挂载,卸载等操作,而且操作完成之后,就应该立即删除快照,以减轻系统的I/O负担。 快照不会自动更新,长久保留是没有意义的。

针对快照进行块设备的备份:
# dd if=/dev/VolGroup00/LogVol02s of=/backup/LogVol02.dd; # 用dd命令进行块备份;

针对快照进行文件系统的备份:
# mkdir /mnt/LogVol02s;
# mount /dev/VolGroup00/LogVol02s /mnt/LogVol02s; # 快照可直接挂载;
# tar -zcvpf /tmp/backup.tar.gz /mnt/LogVol02s/*; # 用tar命令进行文件备份;
# lvremove /dev/VolGroup00/LogVol02s; # 备份完成后删除快照;

通常创建快照卷的主要目的是做备份用途,可以写一个简单的备份脚本来自动创建快照,然后挂载进行备份,备份完成后又自动卸载和删除。因为快照的创建速度非常快,所以使用快照来操作备份作业不仅可以解决一致性问题, 而且可以减少备份时间。

请参考如下代码:

# vi snapshot_backup.sh; #建立备份脚本;
------------------------------------------------------------------------------
#!/bin/bash

today=`date "+%Y%m%d"`;
lvcreate -L1G -s -n LogVol02s /dev/VolGroup00/LogVol02;
mount /dev/VolGroup00/LogVol02s /disk/VolGroup00/LogVol02s;
tar -zcvf /tmp/snapshot_backup_$today.tar.gz /disk/VolGroup00/LogVol02s/*;
umount /dev/VolGroup00/LogVol02s;
lvremove -f /dev/VolGroup00/LogVol02s;
------------------------------------------------------------------------------
chmod 755 snapshot_backup.sh; #设置运行权限;

可以将此备份脚本设置成每天定时运行,就可当成是一个完整备份的方案。

顺便提一些,如要从dd的备份中恢复,反过来操作即可。

例如,先用dd命令摧毁逻辑卷LogVol02中的数据,以便进行恢复测试:
# dd if=/dev/zero of=/dev/VolGroup00/LogVol02 bs=512 count=1024;

这时尝试挂载逻辑卷LogVol02将会失败:
# mount /dev/mapper/VolGroup00-LogVol02 /opt;

如下命令将 dd 备份文件直接写入LogVol02逻辑卷,即可恢复数据:
# dd if=/backup/LogVol02.dd of=/dev/VolGroup00/LogVol02;

再尝试挂载所恢复的逻辑卷LogVol02,成功挂载后再检查数据:
# mount /dev/mapper/VolGroup00-LogVol02 /opt;