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

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

关于Oracle的实例恢复参考之前的博文:http://www.cnblogs.com/leohahah/p/6973600.html

同时其他可参考的链接有:https://www.sqlskills.com/blogs/paul/how-do-checkpoints-work-and-what-gets-logged/

https://technet.microsoft.com/en-us/library/ms191455(v=sql.105).aspx

首先看一下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一定已经被提前写入到disk啦)
  • 一些未提交的事务,其日志还留在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,3)
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

检查点LSN被记录在boot page中,这是实例恢复的起点,如果这个page无法被访问,那么数据库就不能被附加,打开,或者做其他任何操作。检查点LSN只会被记录在bootpage中,因此这是一个对于实例恢复来说不可或缺的页。

对于SQL Server中检查点的解释:

当检查点发生时,无论这个检查点是如何触发的(手动执行检查点命令,或者数据库执行差异备份,或者数据库自动生成的检查点),数据库都会做以下操作:

  • 所有的脏块都被写入磁盘,无论事务是否已提交。
  • 在这些脏块被写入磁盘之前,所有关于这些脏块更改的事务日志也要被从log buffer中写入到磁盘,这样可以确保实例恢复的有效性和有序性,这个操作被称作write-ahead logging(日志先写),日志被写入硬盘的操作是严格按时间序列化的,不可能以事务为单位来离散的写入到磁盘,因此某个脏块的写入磁盘操作,可能引发log buffer中一些之前的、与本脏块无关的事务日志也被写入磁盘。但这是有好处的,事务日志总是被越早写入磁盘越好。
  • 检查点的LSN会被记录到数据库boot page中的dbi_checkptLSN区域。
 

这里可以复习一些Oracle的检查点机制,也是CKPT进程触发DBWR写脏块,同时如果要写的脏块的scn大于LGWR的scn,DBWR也会触发LGWR把要写的脏块的相关log buffer写入redo文件中,与SQL Server日志先写的机制相似。

SQL Server的实例恢复解析的更多相关文章

  1. SQL Server数据库有三种恢复模式:简单恢复模式、完整恢复模式和大容量日志恢复模式

    SQL Server数据库有三种恢复模式:简单恢复模式.完整恢复模式和大容量日志恢复模式: 1.Simple 简单恢复模式, Simple模式的旧称叫”Checkpoint with truncate ...

  2. 【故障公告】阿里云 RDS SQL Server 数据库实例 CPU 100% 引发全站故障

    非常抱歉,今天 8:48 开始,我们使用的阿里云 RDS SQL Server 数据库实例突然出现 CPU 100%  问题,引发全站故障,由此给您带来麻烦,请您谅解. 发现故障后立即进行主备切换,和 ...

  3. SQL Server 多实例下的复制

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 搭建步骤(Procedure) 注意事项(Attention) 二.背景(Contexts) ...

  4. SQL Server 连接问题案例解析(1)

    SQL Server 连接问题案例解析(1) 转载自:http://blogs.msdn.com/b/apgcdsd/archive/2015/04/27/sql.aspx?CommentPosted ...

  5. 当SQL Server的实例位于集群的特定节点时,数据库无法远程访问

    搭建好了一个集群环境,发现当SQL Server的实例位于集群的其中一个节点时,数据库无法远程访问,报如下错误.但在另一个 节点时,数据库访问正常. 标题: 连接到服务器 -------------- ...

  6. Step7:SQL Server 多实例下的复制

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 搭建步骤(Procedure) 注意事项(Attention) 二.背景(Contexts) ...

  7. [SQL Server]数据库的恢复

    数据库恢复是和数据库备份相对应的操作,它是将数据库备份重新加载到系统中的过程.数据库恢复可以创建备份完成时数据库中存在的相关文件,但是备份以后的所有数据库修改都将丢失. SQL Server进行数据库 ...

  8. SQL Server数据库实例名与服务器名不一致的解决办法

    SQL Server数据库实例名与服务器名不一致的解决办法 --EXEC sp_addlinkedserver --   @server = 'PSHGQ' --GO --select * from  ...

  9. SQL Server 命名实例更改端口进行发布订阅

    原文:SQL Server 命名实例更改端口进行发布订阅 两台数据库服务器,都没有加入域,都安装多实例,端口也不一样了.现在使用命名实例进行复制,折腾了好久,才发现解决方法. 服务器A:myserve ...

随机推荐

  1. MVC学习之路【小补充】

    1]:在js中使用ViewBag  需要添加“”,否则程序报错,无法正常运行 .例如:正确格式 var ss = "@ViewBag.ts"

  2. npm install 失败

    总结列表: 1. There is already an open DataReader associated with this Connection which must be closed fi ...

  3. sql server 查询时会锁表吗?

    sql server在执行查询语句时会锁表.在锁表期间禁止增删改操作. 如果不想锁表,那就再表名或别名后面加上WITH(NOLOCK) 如下所示:

  4. 一个smtp发送错误

    错误返回: Error: need EHLO and AUTH first ! 原因:服务器是smtp.exmail.qq.com,邮箱账号是企业新申请的邮箱账号,邮箱密码需要重新修改. 解决办法:修 ...

  5. 【转】hibernate 延迟加载

    Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载.hibernate 通过这种延迟加载来降低系统的内存开销,从而保证 Hiberna ...

  6. MongoDB日期类型查询

    一.前言 MongoDB 里面的日期类型是没有时区概念的,默认存储的是 ISODate("2018-04-02T13:19:16.418Z") 这种格式的零时区时间,比北京时间晚了 ...

  7. mysql不能保存中文

    进入mysql文件夹,新建(修改) my.ini 文件, 修改编码 内容如下: [mysql] default-character-set=utf8

  8. 类修饰符为abstract与final

    类修饰符为abstract:这个类可以被继承,因此可以通过子类来产生实例. 类修饰符为final:这个类不能被继承. 类修饰符不能同时为abstract.final:编译器会提示: 非法的修饰符组合: ...

  9. angular ng-repeat radio取值

  10. [工具配置]使用requirejs模块化开发多页面一个入口js的使用方式

    描述 知道requirejs的都知道,每一个页面需要进行模块化开发都得有一个入口js文件进行模块配置.但是现在就有一个很尴尬的问题,如果页面很多的话,那么这个data-main对应的入口文件就会很多. ...