日期:2011-11-23  浏览次数:20944 次

大家好,很长时间没写东西了,最近在浩方干星际,真是输的连妈都不认,算了,还是回来搞数据库有前途一点,起码在这里我还能勉强找到那么点自信!!!
做备份就像买保险一样,你可以不做,每天提心吊胆的过日子,你也可以做,让系统运行的通常无阻,有顽强的再生能力,同时大家也会忽略你的存在,总是要出下乱子,然后你再来扮演下救世主,这样大家才会知道你的存在是有价值的,你的工资应该是×××的,所以个人感觉做备份是件不大讨好的事!!!
MICROSOFT SQL SERVER的备份机制比SYBASE的真是强大的好多,首先sybase不支持数据库的部分恢复,SQL SERVER的文件与文件组备份很好的实现了这一点,sybase对于错误删除记录的操作显得有点力不从心,因为load tran不支持指定时间点或命名事务,sybase也不存在恢复模型,这样对于不同企业间恢复机制的确定没有一个直观的尺度.我会在下面的文字中逐个说明SQL SERVER的这些优点(也许是下篇文章)

恢复模型:
SQL SERVER有3个恢复模型,简单恢复,完全恢复和大容量日志恢复,每个模型各有自己的特点,也适用于不同的企业备份需求,模型之间可以相互切换,这也是个比较容易出问题的地方

简单恢复:
就像其名字一样,这种恢复模型是最简单的,他只支持数据库完整备份和差异备份,另外对于节省日志文件空间也有很好的支持,因为在检查点处会自动截断日志,所以日志文件几乎不会增长,但提交较大的事务时情况令当别论,由于备份能力有限,其风险指数也是很高的,如果数据库损坏,只能恢复到上次完整备份或最后一次差异备份,对于后面的事务处理就无能为力了,准确一点应该是非活动的事务日志都被删除了
   
大容量日志恢复:
这个模型很像后面将提到的完全恢复,但还是有很多不同,他支持数据库完整,差异和日志备份,对于诸如SELECT INTO,BULK INSERT,BCP等操作大容量的日志操作提供了性能上的优化,在完全恢复模式下,日志会记录上述操作的具体细节,而本模式中只会在日志中记载有这么一回事,具体细节忽略不计,这样存储速度就有很大提高,也节约了日志空间,问题也就出现了,由于日志记录中包含有忽略细节的最小日志更改,所以大容量恢复模型不支持具体时间点的恢复,也就是说不能在restore log中指定stopat子句,下面是操作和出错信息

/*大容量日志恢复模型
restore database chj733 from disk = 'e:\chj733_dat.bck' with norecovery
go
restore log chj733 from disk = 'e:\chj733_log.bck' with file = 1,stopat = '2004-11-09 15:06:04.810',recovery
go
已处理 2016 页,这些页属于数据库 'chj733' 的文件 'chj733'(位于文件 1 上)。
已处理 1 页,这些页属于数据库 'chj733' 的文件 'chj733_log'(位于文件 1 上)。
RESTORE DATABASE 操作成功地处理了 2017 页,花费了 3.687 秒(4.479 MB/秒)。
服务器: 消息 4327,级别 16,状态 1,行 1
此备份集中的日志包含最小日志记录更改。禁止进行时点恢复。RESTORE 将前滚到日志的结尾,而不恢复数据库。
已处理 7152 页,这些页属于数据库 'chj733' 的文件 'chj733'(位于文件 1 上)。
已处理 1736 页,这些页属于数据库 'chj733' 的文件 'chj733_log'(位于文件 1 上)。
RESTORE LOG 操作成功地处理了 8888 页,花费了 6.668 秒(10.919 MB/秒)。
*/
同时在大容量日志模式下备份事务日志需要访问数据文件,而很多灾难发生后基本上数据文件就没法访问了,所以采用这种模式时你的防着这一点,很有可能你会丢失自上次事务备份以后所有的数据,一般可以在准备进行大量数据装载或建立比较庞大的索引时将模型切换到大容量日志方式,操作完成后在切换回完全模式。

完全恢复:
这种模式风险是最小的,联机帮助上宣称这种模式可以将数据库恢复到任何即时点,理论上可以将数据丢失的可能性减至0(事实上并非如此),上述两个模型中打NO的在这里基本上可以打YES,他支持所有的备份和恢复方式,支持指定即时点,日志对BCP等大数据装载操作有详细记载,等等,这些特性也引发了一些问题,日志文件开销较大,需要频繁转存日志

恢复模型就讲到这,大家可以试着用BCP加载一些数据看看,在各个模式下观察下日志文件的大小变化是不是符合上面的说法,做之前最好先压缩下日志文件,如果日志文件里面有足够的空间,你加载的数据份量又不够的话,你会看不到文件的变化的,省得到时候又来骂我在这里胡说八道!!!

备份类型:
先抛开文件备份,SQL SERVER有3种备份类型,完整备份,差异备份,日志备份,你必须先明白每种备份从哪里开始,从哪里结束,他里面的内容是什么

完整备份是数据库的一个完整拷贝,包括事务日志,数据库中的所有对象,等等

差异备份从上次完整备份之后开始,创建所有修改页的拷贝,注意,他是从上次完整备份后开始的,所以应用差异备份时只需最后的一次备份,而不是逐个应用所有的差异备份,当然你有这个闲功夫,也可以这么干

日志备份是备份上次日志备份后所有的事务记录,记住,不是上次完整备份。在应用事务日志备份时将前滚所有的事务记录,并且这些记录应该是连续的,另外也会回滚没有COMMIT的日志记录
   
这些老掉牙的话应该好好的理解,最起码在面试的时候应该很流利的背出来,下面看一个比较常见的错误。

问题1:
/*
服务器: 消息 4305,级别 16,状态 1,行 2
此备份集中的日志开始于 LSN 641000000005900001,该 LSN 太晚,无法应用到数据 库。包含 LSN 641000000005600001 的较早的日志备份可以还原。
服务器: 消息 3013,级别 16,状态 1,行 2
RESTORE LOG 操作异常终止。
*/
相信这个信息只要是做过备份的人都知道,在应用完整备份+日志备份恢复数据库时提示只能应用数据库备份,而日志备份由于LSN太早或太晚无法应用,这是怎么回事阿???LSN表示事务日志记录的唯一序号,SQL SERVER会记录对数据库的每次操作,这些操作总有个先来后到的,LSN就是系统发给他们的顺序号,日志备份恢复时要求所有的备份集叠加时能生成一个连续的LSN链,这个就是问题所在(如果对上述日志概念不了解的话可以阅读精华区SQL日志概念这一篇,或是看BOL)。查看下备份文件就可以知道答案
restore headeronly from disk = 'e:\chj733_dat.bck'  ――数据库备份
restore headeronly from disk = 'e:\chj733_log.bck'  ――日志备份
结果(我只列出了比较有用的几项)
―――――――――――――――――――――――――――――――――――――
Position              FirstLsn                   LastLsn
  1           641000000005400001        641000000005600001   ――数据备份
  1           641000000005900001        641000000006100001   ――日志备份
―――――――――――――――――――――――――――――――――――――
position表示这个设备中备份集的位置,不是可以在一个设备里多次备份的吗?每备份一次就生