SQL Server实例恢复?

时间:2017-01-30 09:41:30

标签: sql-server sql-server-2008-r2

有人能告诉我实例崩溃后如何在sql server中进行实例恢复?

是否使用启动页面信息进行实例恢复?

在恢复期间如何重建之前的图像和之后的图像?

1 个答案:

答案 0 :(得分:1)

  

SQL Server实例恢复

在SQL Server中,日志缓冲区缓存保存与数据库缓冲区缓存中已更改数据页对应的T-Log记录。

更新某些数据时,会在Trasaction日志文件中记录日志记录,并且在事务日志中记录之前和之后的图像,并为每个事务生成唯一的LSN。当检查点发生时(注意LSN),SQL Server确保所有数据都发生变化,直到检查点LSN写入光盘。

当数据库突然关闭时,可能是由于系统突然崩溃;数据库处于不一致状态:表示所有正在进行的事务(已提交或未提交)未完成。它必须使数据库在打开之前处于一致状态。为了使数据库处于一致状态,SQL Server执行实例恢复。

  

实例恢复包括两个步骤:一个是前滚,另一个是向后滚动它基本上重新应用已提交,然后回滚未提交的事务。

<强> 1。前滚:

对数据库所做的更改将记录在数据库缓冲区缓存中,缓冲区缓存将写入数据文件中。同时,更改记录在日志缓冲区中,日志缓冲区将写入日志文件。仅当数据缓冲区高速缓存中有足够的数据时,SQL Server才会将数据从数据库缓冲区高速缓存写入数据文件。每次提交时,SQL Server都不必将数据缓冲区缓存写入数据文件。

当实例失败,然后将已提交的数据写入数据文件;当重新启动关联的数据库时,SQL Server使用记录在日志文件中的数据来恢复丢失的数据。此过程称为前滚或缓存恢复。 (这意味着SQL Server使用记录在T-log文件中的后映像。)

<强> 2。向后滚动:

当我们在数据库中进行任何更改时,旧图像(即图像之前)将被写入日志文件。稍后,当我们回滚事务时,它将用于回滚数据。 Database Writer进程在不同情况下将缓冲区缓存内容写入数据文件。因此可以将数据库缓冲区高速缓存中的未提交数据写入数据文件。 当实例失败并重新启动关联的数据库时,它会使用日志文件中记录的映像之前回滚数据文件中未提交的事务,以保持读取一致性。这称为向后滚动或事务恢复。

  

SQL Server实例恢复中执行的步骤简称如下:

实例恢复的目标是:

  • 将所有已提交的更改写入数据文件
  • 撤消数据文件中所有未提交的更改
  • 增加检查站号。到LSN,直到更改已写入数据文件。

在实例崩溃之前:

  • 一些已提交的更改位于日志文件中,但尚未写入数据文件
  • 一些未提交的更改已经进入数据文件
  • 一些未提交的更改位于日志缓冲区/缓存

实例崩溃后:

  • 日志缓冲区/缓存中的所有未提交的更改都将被删除
  • 读取日志文件以识别需要恢复的页面
  • 从数据文件中读取已识别的页面
  • 在前滚阶段,重做日志文件中的所有更改(已提交/未提交)都将应用于它们
  • 在回滚阶段,所有未提交的更改都将回滚
  • 检查点的LSN在数据文件/日志文件标题中更新。
  

是否使用启动页面信息进行实例恢复?

上述问题的答案是肯定的。 SQL Server确实使用引导页面信息进行恢复。

但首先让我们了解什么是引导页?

每个数据库都有一个页面,用于存储有关数据库本身的重要信息。它总是文件1中的第9页(PRIMARY文件组中的第一个文件)。

当检查点操作发生时,无论它是如何触发的(例如通过手动CHECKPOINT,来自数据库或差异备份,或自动),都会发生同一组操作:

  • 数据库的所有脏数据文件页面都写入磁盘(全部 自从磁盘或磁盘读取以来内存已更改的页面 自上次检查点以来,无论状态如何 做出改变的交易。
  • 在将页面写入磁盘之前,所有日志记录都包括在内 描述该页面更改的最新日志记录是 写入磁盘(是的,日志记录也可以缓存在内存中)。这个 保证恢复可以工作,称为预写日志记录。日志 记录按顺序写入日志,并记录日志记录 多个交易将散布在日志中。日志不能 有选择地写入磁盘,所以将脏页写入磁盘 只有一个影响它的日志记录可能意味着写更多 以前的日志记录也可以记录到磁盘上。
  • 检查点的 LSN记录在 dbi_checkptLSN 字段中的数据库引导页面标题

最后一个检查点的LSN记录在数据库引导页面中。这是恢复开始的地方,如果此页面不可访问,则无法以任何方式连接,打开或处理数据库 - 部分原因是它是知道数据库是否被彻底关闭的引导页面,部分是因为它是只记录最后一个检查点记录的LSN的地方。

要查看引导页面信息,您可以使用以下命令:

DBCC TRACEON (3604);  
go
dbcc page ('test_sparse',1,9,0)
go