为何要对数据库的还原过程进行“长篇大论”?



如果一个数据库还原的时间远超日常均值,眼看时间一分分过去,但还未结束,更严重的是,你不知道什么时候能结束,出了焦急等待,你可能会这么做:



  1. 还原假死了,我要停止这次还原,重新还原一次;
  2. 备份文件有问题,换个备份文件再试一次(尽管会有数据丢失);

然而你以为的解决方法并没有出现预期的效果,而浪费在这些方法上的时间让业务系统恢复变得更加遥不可及。



如果你熟知还原的过程,你就能跟踪还原的进度,而当你看到进度在变化时,让你至少能看到业务恢复的时间在一步步靠近。





数据库还原有3个阶段



阶段1:复制文件的阶段



在阶段1中,SQL Server将备份文件中的所有的数据、日志、索引拷贝到还原后的数据库文件中。



此时,你在数据库的日志文件里,可以看到数据库start的记录,同时该数据库会被标记为restoring。




select percent_complete,last_wait_type,* from sys.dm_exec_requests


阶段2:redo


SQL Server根据日志文件对已提交的事务进行redo,将数据库恢复到recovery point,但此时,日志文件中因存在未提交的事务需回滚,因此,此时数据库还处于不可用状态。


sys.dm_exec_requests视图中percent_complete字段,你会发现一直显示100%,这是正常的,因为redo的进度并不会在 sys.dm_exec_requests中显示。所以切记不要以为还原卡死了而结束还原。


阶段3:回滚


阶段3是还原的回滚阶段,


SQL Server对日志文件中未提交的事务进行回滚,从而保证数据的一致性。数据库只有在回滚完成后,才会变得可用。


如果备份文件的事务日志中存在大量未提交的事务,那回滚的过程就会很长,还原的时间可能远超日常的均值。


笔者曾经遇到这样的场景:数据库的备份文件中包含了一个执行了10天没有完的事务(死循环)的日志,当我在进行还原时,整整还原了2天,客户的业务系统也停了2天。


checkpoint执行时间的长短取决于内存中脏数据的大小,保守的估算方法是:假设内存的大小就是脏数据的大小,


checkpoint执行时间= 内存大小/数据文件(mdf)的写入速率


其中写入的速率可以在资源监视器(win2012及以上的系统)中可以详细看到。


当checkpint完成是时,在SQL Server的错误日志中可以看到还原完成的记录。此时数据库就可以正常使用了。


总结


看完了上述的还原的完整过程,当你再次碰到数据库还原的时间远超日常均值你就不会心慌了,起码你知道这是正常的还原过程,甚至你还能通过这个现象来判断该数据库很可能运行了非正常的SQL在序,需要进行治理。