说明:灾难恢复系列的文章是由 Robert Davis 写的,发布在SQLSoldier, 个人认为挺不错的,所以根据自己的理解,边测试边整理,并非直接翻译,如有不准确,欢迎指正。
本篇进入数据库灾难恢复第五篇,上一篇演示了修复简单的非聚集索引损坏,今天,我们将看一个稍复杂点儿的,那就是管理区分配页损坏,不过分配页无法修复,只能恢复整个数据库。
什么是管理区分配页?
管理区分配页是数据文件中特殊的页,用来跟踪和管理区分配,本篇将关注三种:
全局分配映射表 (GAM):记录已分配的区,对于一个数据文件,每4GB会有一个GAM页,它的ID总是为2,之后每511,232页出现一次。
Page ID = 2 or Page ID % 511232
共享全局分配映射表 (SGAM) :记录当前用作混合区且至少有一个未使用的页的区,每4GB会有一个SGAM页,它的ID总是为3,之后每511,232页出现一次。
Page ID = 3 or (Page ID – 1) % 511232
页可用空间 (PFS):记录每页的分配状态,是否已分配单个页以及每页的可用空间量,每64MB会有一个PFS页,它的ID总是为1,之后每8,088页出现一次。
Page ID = 1 or Page ID % 8088
如果PAGE id是1/2/3,那么很明显会知道他们是什么管理区分配页,如果PAGE ID很大,那么我们有两个办法来区分它们:
一个办法是采用SQL脚本计算:
Declare @PageID int; -- Enter page number -- e.g., 8088 = PFS page Set @PageID = 8088; Select Case When @PageID = 1 Or @PageID % 8088 = 0 Then 'Is PFS Page' When @PageID = 2 Or @PageID % 511232 = 0 Then 'Is GAM Page' When @PageID = 3 Or (@PageID - 1) % 511232 = 0 Then 'Is SGAM Page' Else 'Is Not PFS, GAM, or SGAM page' End
另一个办法是采用DBCC PAGE来看它的m_type值:
现在按照下面的步骤:
现在我们已经知道哪些是管理区分配页,接下来依然按三个步骤进行:
1.确定损坏(使用DBCC CHECKDB)
2.确定损坏的对象及对象类型(如索引页、分配页等)
3.确定适合的修复方法
确定损坏
首先,请先下载一个PFS损坏的数据库,然后运行DBCC CHECKDB:
DBCC CheckDB(PFSCorruption) With No_InfoMsgs, All_ErrorMsgs, TableResults;
由于返回太多我们不需要的列,为了更好的体现这里的演示效果,减去一些列,不过在实际做故障排除时,还是要用返回全部列,这里仅为了演示:
Declare @DBCC Table ( Error int, Level smallint, State tinyint, MessageText varchar(2500), RepairLevel varchar(30) null, Status tinyint, DbId int, DbFragId int, ObjectId int, IndexId int, PartitionId bigint, AllocUnitId bigint, RidDbId int, RidPruId int, [File] int, Page int, Slot int, RefDbId int, RefPruId int, RefFile int, RefPage int, RefSlot int, Allocation bigint) Insert Into @DBCC Exec sp_executesql N'DBCC CheckDB(PFSCorruption) With No_InfoMsgs, All_ErrorMsgs, TableResults;'; Select Level, State, MessageText, RepairLevel, ObjectId, IndexId, [File], Page, RefFile, RefPage From @DBCC;
结果:
确定损坏的对象
这一步我们需要确定真正的错误,可以看到有较高级别的错误号16,这是需要我们要仔细查的,另外State列为5表示一个未知的错误导致DBCC CHECKDB终止执行,另外这两行中不同的pageid(1:6)和(1:7)可能会误导你以为是他俩是损坏的页,但实际上是(1:1)中有这两个错误page值而已,所以需要关注的是RefFile和RefPage这两个列,而不是File和Page列。
从上面DBCC CHECKDB的结果,可以直接看出是PFS页面,所以不需要记算也不需要DBCC PAGE去判断,因为DBCC的结果是很明显的了。
采用适合的方法
在开头的时候我们已经说过管理区分配页不能被修复或还原,所以我们不得不做整个数据库的还原,那就需要检查备份的情况,尤其是事务日志备份到什么时间,然后开始做还原,如果没有备份,则需要将数据导到一个新建的数据库中。如果你能手动用一个十六进制的编辑器手动修复它(不是NB就是DS),那么最好先copy出一份来做这个操作。
总结
本篇主要还是在讲述如何确定具体的损坏对象,主要是确定管理区分配页GAM/SGAM/PFS页,不过遗憾的是它们都无法直接修复。
下载本篇示例的数据库及代码
SQL Server 灾难恢复31天之第7天:灾难恢复服务等级协议(数据恢复点目标和数据恢复时间点目标)
作者:nzperfect
出处:http://www.cnblogs.com/nzperfect/
引用或者转载本BLOG的文章请注明原作者和出处,并保留原文章中的版权信息。