还原页 (SQL Server)
SQL Server 2014
页面还原的目的是还原一个或多个损坏的页,而不还原整个数据库。通常,要进行还原的页已经由于在访问该页时遇到错误而标记为“可疑”。
何时适合页面还原?
页面还原用于修复隔离出来的损坏页。 还原和恢复少量页面的速度可能比还原一个文件更快,因此减少了还原操作中处于脱机状态的数据量。然而,如果文件中要还原的不只是少量页面,则通常还原整个文件更为有效。 例如,如果某个设备上的大量页都指出此设备有未解决的故障;不妨考虑还原该文件(可以还原到另一位置)并修复该设备。
此外,并非所有的页面错误都需要还原。缓存数据(例如辅助索引)中可能出现的问题可以通过重新计算这些数据来解决。 例如,如果数据库管理员删除一个辅助索引,然后再重新生成一个辅助索引,则损坏的数据虽然已修复,但并没有在suspect_pages 表中反映出这一情况。
限制和局限
- 页面还原适用于使用完整或大容量日志恢复模式的 SQL Server 数据库。 只有读/写文件组支持页面还原。
- 仅可以还原数据库页。 页面还原不能用于还原下列内容:
- 事务日志
- 分配页:全局分配映射 (GAM) 页、共享全局分配映射 (SGAM) 页和页可用空间 (PFS) 页。
- 所有数据文件的页 0(文件引导页)
- 页 1:9(数据库引导页)
- 全文目录
- 仅可以还原数据库页。 页面还原不能用于还原下列内容:
- 事务日志
- 分配页:全局分配映射 (GAM) 页、共享全局分配映射 (SGAM) 页和页可用空间 (PFS) 页。
- 所有数据文件的页 0(文件引导页)
- 页 1:9(数据库引导页)
- 全文目录
- 对于使用大容量日志恢复模式的数据库,页面还原还有下列附加条件:
- 对大容量日志数据而言,在文件组或页数据处于脱机状态时进行备份是有问题的,因为日志中不记录脱机数据。 任何脱机页都可能导致无法备份日志。 在这种情况下,则应考虑使用 DBCC REPAIR,因为此方式导致的数据丢失少于还原到最近备份引起的数据丢失。
- 如果大容量日志数据库的日志备份遇到错误页,除非指定了 WITH CONTINUE_AFTER_ERROR,否则将失败。
- 通常,页面还原不能与大容量日志恢复模式配合使用。
执行页面还原的最佳做法是将数据库设置为完整恢复模式,并尝试进行一次日志备份。 如果可以进行日志备份,则可以继续进行页面还原。 如果日志备份失败,则您将不得不丢失上一个日志备份之后的工作,或必须尝试运行 DBCC(必须使用 REPAIR_ALLOW_DATA_LOSS 选项)。
建议
- 页面还原方案:
脱机页面还原
SQL Server 的所有版本都支持在数据库脱机时还原页面。在脱机还原页过程中,还原损坏的页时数据库处于脱机状态。 还原顺序结束时,数据库将联机。
联机页面还原
SQL Server Enterprise Edition 支持联机页面还原,但它们在数据库当前处于脱机状态时将使用脱机还原。 在大多数情况下,可以在数据库(包括页面要还原到的文件组)保持联机状态时还原损坏的页。在主文件组处于联机状态时,即使有一个或多个辅助文件组处于脱机状态,页面还原也通常联机执行。 但有时候,损坏的页可能需要脱机还原。 例如,某些重要的页发生损坏可能会使数据库无法启动。
注意 |
如果损坏的页存储了重要的数据库元数据,则在联机页面还原尝试过程中对元数据的必需的更新可能失败。 在此情况下,您可以执行脱机页面还原,但首先,您必须创建一个结尾日志备份(通过使用 RESTORE WITH NORECOVERY 备份事务日志)。 |
- 页面还原利用了改进的页级错误报告(包含页校验和)和跟踪。 通过校验和或残缺写操作检测为已损坏的页(“损坏页”)可以通过页还原操作进行还原。 仅还原显式指定的页。 每个指定页都被来自指定数据备份的页的副本替换。
在您还原随后的日志备份时,它们将仅适用于包含要还原的至少一页的数据库文件。 必须将不中断的日志备份链应用于最后一次完整或差异还原,以便让包含该页的文件组前进到当前的日志文件。与文件还原中一样,每次传递日志重做,前滚集都会前进一步。 为了成功还原页,已还原的页必须恢复到与数据库一致的状态。
使用 SQL Server Management Studio
从SQL Server 2014 开始,SQL Server Management Studio 支持页面还原。
还原页
- 连接到相应的 SQL Server 数据库引擎实例,在对象资源管理器中,单击服务器名称以展开服务器树。
- 展开“数据库”。 根据具体的数据库,选择一个用户数据库,或展开“系统数据库”并选择一个系统数据库。
- 右键单击该数据库,指向“任务”,再指向“还原”,然后单击“页”,这将打开“还原页”对话框。
还原
此部分执行的功能与还原数据库(常规页)上的“还原到”的功能相同。
数据库
指定要还原的数据库。 您可以输入新的数据库,也可以从下拉列表中选择现有的数据库。 该列表包含了服务器上除系统数据库 master 和 tempdb 之外的所有数据库。
注意 |
若要还原带有密码保护的备份,必须使用 RESTORE 语句。 |
结尾日志备份
在“备份设备”中输入或选择一个文件名,将在其中存储数据库的结尾日志备份。
备份集
此部分显示参与还原的备份集。
标头 | 值 |
名称 | 备份集的名称。 |
组件 | 备份的组件:“数据库”、“文件”或“<空白>”(对于事务日志)。 |
类型 | 执行的备份类型:“完整”、“差异”或“事务日志”。 |
服务器 | 执行备份操作的数据库引擎实例的名称。 |
数据库 | 备份操作中涉及的数据库的名称。 |
位置 | 备份集在卷中的位置。 |
第一个 LSN | 备份集中第一个事务的日志序列号 (LSN)。 对于文件备份为空。 |
最后一个 LSN | 备份集中最后一个事务的日志序列号 (LSN)。 对于文件备份为空。 |
检查点 LSN | 创建备份时最新检查点的日志序列号 (LSN)。 |
完整 LSN | 最近的完整数据库备份的日志序列号 (LSN)。 |
开始日期 | 备份操作开始的日期和时间,按客户端的区域设置显示。 |
完成日期 | 备份操作完成的日期和时间,按客户端的区域设置显示。 |
大小 | 备份集的大小(字节)。 |
用户名 | 执行备份操作的用户的名称。 |
过期 | 备份集的过期日期和时间。 |
单击“验证”以检查执行页还原操作所需的备份文件的完整性。
- 若要标识已损坏的页,则在“数据库”框中选择了正确的数据库的情况下,单击“检查数据库页”。 此操作将运行较长时间。
注意 |
若要还原未损坏的特定页,请单击“添加”,然后输入要还原的页的“文件 ID”和“页 ID”。 |
- 页网格用于标识要还原的页。 最初,此网格将从 suspect_pages 系统表填充。 若要从该网格添加或删除页,请单击“添加”或“删除”。
- “备份集”网格将列出默认还原计划中的备份集。 或者,单击“验证”可验证备份是否可读取以及备份集是否完整而无需还原。
页
- 若要还原在页网格中列出的页,请单击“确定”。
若要在 RESTORE DATABASE 语句中指定一页,需要知道该页所在文件的文件 ID 和该页的页 ID。 所需语法如下:
RESTORE DATABASE <database_name>
PAGE = '<file: page> [ ,... n ] ' [ ,... n ]
FROM <backup_device> [ ,... n ]
WITH NORECOVERY
还原页
- 获取要还原的损坏页的页 ID。 校验和或残缺写错误将返回页 ID,并提供指定页所需的信息。
- 从包含页的完整数据库备份、文件备份或文件组备份开始进行页面还原。 在 RESTORE DATABASE 语句中,使用 PAGE 子句列出所有要还原的页的页 ID。
- 应用最近的差异。
- 应用后续日志备份。
- 创建新的数据库日志备份,使其包含已还原页的最终 LSN,即最后还原的页脱机的时间点。 设置为顺序中首先还原的最终 LSN 是重做目标 LSN。 包含该页的文件的联机前滚可以在重做目标 LSN 处停止。 若要了解文件的当前重做目标 LSN,请查看 sys.master_files 的 redo_target_lsn 列。
- 还原新的日志备份。 应用这个新的日志备份后,就完成了页面还原,可以开始使用页了。
注意 |
此顺序与文件还原顺序类似。 事实上,页面还原和文件还原都可以在相同的顺序中执行。 |
示例 (Transact-SQL)
以下示例使用 NORECOVERY 还原文件 B 的四个损坏页。 随后,将使用 NORECOVERY 应用两个日志备份,然后是结尾日志备份(使用 RECOVERY 还原)。此示例执行联机还原。 此示例中,文件 B 的文件 ID 为 1,损坏的页的页 ID 分别为 57、202、916 和 1016。
Transact-SQL
RESTORE DATABASE <database> PAGE='1:57,1:202, 1:916, 1:1016'
FROM<file_backup_of_file_B>
WITHNORECOVERY;
RESTORE LOG <database> FROM<log_backup>
WITHNORECOVERY;
RESTORE LOG <database> FROM<log_backup>
WITHNORECOVERY;
BACKUP LOG <database> TO<new_log_backup>;
RESTORE LOG <database> FROM <new_log_backup>WITH RECOVERY;
GO