使用文件系统snapshot做数据库归档备份

May 12th, 2011 no comment

昨天下午的技术讨论会上说到了数据库的按时间点的进行实时备份和归档,当时的讨论都是基于日志如何来做。

这个问题需要做到以下几点:

  • 因备份而引起的中断数据库服务的时间尽可能短;
  • 能够迅速的让数据库使用备份的数据rollback;
  • 归档的备份数据能在专门的备份机统一保存,方便本机失效后的处理;
  • 如果可能,归档备份的数据能做到增量备份,以节省备份机的磁盘空间,同时方便快速传输。

从数据库本身解决这个问题,可能受困于已有的数据库设计和代码,不非常容易。换个思路,可以基于fs的snapshot来做。

在*nix系统下功能最强的snapshot首推zfs,本身支持文件系统快照,支持增量备份,并内置了zfs send工具能直接把备份快照、或增量备份快照发送到另外一台物理机器上(也必须是zfs)。但必须使用FreeBSD 8以上或者是 OpenSolaris。但是由于公司的机器都是GNU/Linux的,退而求其次选择LVM。

在家里的E8200 + Debian 6.0.0 i386系统上做了测试,首先是使用lvm创建分区,创建了一个名为main的60GB大小的Volume Group,同时在里面建立了一个名为main0的10GB的Logical Volume挂载“/”,并格式化为ext3。

拷入6GB的数据文件,然后创建snapshot:
# lvcreate -s -L 7G -n snap-`date +%Y%m%d%H` /dev/main/main0
这一步消耗时间只有0.5s左右,而且测试了拷入20GB的数据文件,snapshot时间基本无变化,详细看截图:

然后在/dev/main/下新加入了snap-`date +%Y%m%d%H` LVM逻辑卷,可以挂载此snapshot分区:
# mount /dev/main/snap-`date +%Y%m%d%H` ~/backup

随后就可以tar成gzip包,然后rsync集中保存了。

删除snapshot:
# umount -f ~/backup# lvremove /dev/main/snap-`date +%Y%m%d%H`

对于数据库的操作来说,拿MySQL举例:

# mysql –uroot –p -h localhost
mysql> flush tables with read lock;
mysql>flush logs;
mysql>system lvcreate -s -L 7G -n snap-mysql-`date +%Y%m%d%H` /dev/main/mysqldb;
mysql>unlock tables;
mysql>quit;

就是先flush数据和日志,锁表,创建snapshot,解锁,这时就已经恢复服务。如果flush的速度够快,整个中断服务的时间在1s左右。

完毕后,即在/dev/main/snap-mysql-`date +%Y%m%d%H`下创建了一个LVM逻辑卷,如果使用,可以随时mount,然后修改mysql的数据路径,即能非常快的使用那时的数据,切换肯定也能在1s之内完成。

接下来要做的就简单了,可以mount上,然后慢慢的tar包,上传到统一备份机。

PS,今天有一位同事指出在lvm下做过snapshot后,磁盘的IO性能影响很大,这个我需要测试一下了。