最近网站出现了几次宕机,而且以前也出现过数据错误,导致手动恢复(比如库存数据,记错了,就要花几个小时重新计算)。现在有点时间,于是打算写一个数据库的备份与恢复的框架,正文我列举了一些思路,希望的到大家的意见。
数据备份策略包括:
全备份 (Full Backup)
增量备份 (Incremental Backup)
差分备份 (Differential Backup)
这个是参考文献,具体就不解释了,可以看:http://blog.csdn.net/newsainton/archive/2009/09/04/4519382.aspx
我不管oracle有多强大,sqlserver有多牛逼,ibm的DS8000有多稳定db2有多健全,我需要的是一个通吃的框架,不考虑数据库的具体形式,只要支持sql标准的,就能够实现备份与恢复。
现在市场上很多的备份系统都是使用了数据库本身提供的功能,所以大部分仅仅支持sqlserver, oracle,导致了被这些巨头牢牢把住吸血。
具体参考了众多的系统,我个人提出以下的个思路。
1. 备份的策略包括:入侵式、非入侵式。
所谓入侵式的备份策略,就是在代码级别生成数据日志,例如Insert一个表的使用,同时生成对应的Log,然后备份系统收集这些log。
所谓非入侵式的备份就是通过时间戳,选择在制定时间内发送变动的数据,然后汇总。
当然,全备份就没有什么策略而言,反正都是全部导数据。
一般来说,入侵式的效率最高,但是如果经典系统的架构设计比较恶心,那么使用这个备份框架就很麻烦了,要重构代码,把生成log的部分嵌入到数据库操作。
非入侵式就比较完善,但是需要数据库表结构符合一定的设计要求:就是必须有个能体现自然增长的字段,例如时间、主键等,如Createdate, ID。
这样非入侵式只要通过sql就能够查找时间段内变动的记录。
补充:由于我不是开发数据库的,我根本不知道某条记录什么时候插入、是否被修改过,因此这个信息一定要由用户提供,所以采用非入侵式就需要表结构配合了。
2. 保存格式
首选xml+打包。例如下面是我暂时设计的一个例子
<table tablename="TB_USER" timestamp="20091218333300723" type="FULLBACKUP">
<row rowindex="1">
<id>xxx</id>
<createdate>xxx</createdate>
</row>
</table>
然后根据当前备份时间,把所有备份的表全部打包在一个zip文件。
当然,在打包之前还要写入头文件,就是对这个包的内容的概述。这样以后恢复的时候,首先读取头文件,然后再恢复。
3. 保存地址
首选本地保存,这样速度最快。但是也是最笨,一旦服务器崩溃,磁盘坏了,那么哭也来不及。因此,
其次,我选择ftp或者web备份,说白了,就是把备份包上传到另外一台机器,实现异地灾备。
再次,我选择了EMAIL备份。现在一个email邮箱动不动就是几个g,足够备份一段时间了。
最后,就是光盘这些了,由于采用介质备份,需要人工参与,因此程序不能自动完成,就没什么好考虑的。(自己带个刻录机,从ftp上下就行了)
4. 恢复策略
每次恢复肯定从全备份开始,如果没有全备份,那么恢复是没有意义的。
然后如果存在差分备份,那么直接差分恢复、否则需要增量一个个慢慢恢复。恢复其实非常简单,两步
a)delete
b)insert
我不考虑有什么数据被修改了,有什么数据是插入的,反正我先把增量数据全部根据主键对原数据库做一次delete,把脏数据全部删除,然后再做一次inert,这样保证了准确的恢复到了当前时间戳。
5. 其他参考
由于现在我们的业务大部分是分布式环境下的,因此整套备份框架必须是分布式下使用的。仅仅一台机器做备份、恢复没有任何意义。所以在拓扑结构上,需要设计一个Center,他不会主动操作所有的peer,但是所有的peer需要主动的请求center当前的备份操作,然后再主动的提交备份文件。
这样的设计下,能够实现管理员集中控制,一旦出现了宕机,能够让center设置好应急方案,然后peer主动请示执行,实现分布式下的数据备份。
代码实现是微不足道的,就是些体力活。但是如果我想错了,那么代价更大。希望有经验的兄弟给点提示,看看有没有更好的思路。
插一句,如果要使用特定数据库提供的功能,那么就免了,是在太不通用了。我也知道oracle很强大,但是银子也很“强大”。