SQL Server的实例恢复解析

Oracle一样,SQL Server在非一致性关闭的时候也会进行实例恢复(Instance Recovery),本文根据stack overflow的文章介绍一些SQL Server实例恢复的知识。

原文链接:https://stackoverflow.com/questions/41932735/sql-server-instance-recovery

关于Oracle的实例恢复参考之前的网址:

首先看一下SQL Server中事务日志的作用:

在SQL Server数据库中,事务日志用于记录事务在Buffer Cache中的做的页更改。

当我们更新一些数据时,数据库会把相关数据页的前镜像和后镜像都记录在事务日志中,并为每个事务生成一个唯一的LSN(log seq number),在检查点发生时SQL Server确保检查点LSN之前的脏块被全部写入到磁盘。因此SQL Server的事务日志兼有redo和undo的作用。

但是,如果我们的数据库被强制关闭或者服务器异常掉电重启,数据库就将处于非一致性的状态(没业务的库除外),这意味检查点之后的所有事务(无论是提交还是未提交的),都出现了异常,提交的事务可能脏块未被写入磁盘,未提交的长事务可能有一部分脏块已经被写入到磁盘,数据库必须处于一致状态才能被正常打开,因此此时必须进行实例恢复

SQL Server的实例恢复分两个阶段:

1.前滚

此阶段只处理已提交的事务,根据boot page中记录的检查点和事务日志的记载,SQL Server重构检查点之后的内存脏块并按正常机制提交已提交事务的脏块。

对未提交事务的脏块暂时不做操作。

2.回滚

此阶段处理未提交的事务,SQL Server根据事务日志中记载的更改块前镜像,去覆盖硬盘上那些未提交事务涉及的数据块。

总结一下:

1)实例恢复的目的:

将所有已提交事务的脏块写入磁盘。

回滚未提交的事务。

将检查点推进至已被写入磁盘的事务LSN。

2)实例崩溃之前:

一些已提交的事务被事务日志记录,但是脏块未被写入到磁盘

一些未提交的长事务中的脏块已经被写入到磁盘

一些未提交的事务,其日志还留在log buffer中未被写入到磁盘中的事务日志文件。

3)实例恢复阶段:

Log buffer中所有未提交事务的日志在掉电时全部被清空。(已提交事务的日志默认被写入了磁盘事务日志文件)

从boot page中识别出上一个检查点,作为实例恢复的起点。

在前滚阶段,SQL Server根据事务日志的记录对所有脏块进行重现。(无论是提交还是未提交的事务)然后将已提交事务的脏块写入磁盘,对未提交事务的脏块暂不作操作。

在回滚阶段,SQL Server根据事务日志中记载的前镜像对所有未提交的事务进行回滚。

更新boot page中的检查点LSN和事务日志中的LSN。

在以上的介绍中我们提到了boot page,那么什么是boot page呢?

每个数据库都会有一个记录数据库重要信息的页,只有一页一般是 PRIMARY filegroup的第9个页。我们可以使用如下命令查看这一页的信息:

DBCC TRACEON (3604);

go

DBCC PAGE ('test',1,9,0)

go

关于DBCC PAGE的用法这里解释一下:

dbcc page ( {'dbname' | dbid}, filenum, pagenum [, printopt={0|1|2|3} ])

The printopt parameter has the following meanings:

0 - print just the page header

1 - page header plus per-row hex dumps and a dump of the page slot array (unless its a page that doesn't have one, like allocation bitmaps)

2 - page header plus whole page hex dump

3 - page header plus detailed per-row interpretation

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/fed273178759d39a5b2d43231f43f84d.html