通过MS SQL Server 2005中的损坏页码搜索损坏的对象

这些天之一,MS SQL Server数据库之一切换到Suspect,日志中出现错误消息:
Msg 7105,第22级,州立9,第14行
数据库ID 6,页面(1:386499),LOB数据类型节点的插槽0不存在。 这通常是由可以读取数据页上未提交的数据的事务引起的。 运行DBCC CHECKTABLE。

该数据库已转移到紧急状态并尝试执行DBCC CHECKDB,但是执行立即被中断:
Msg 8921,第16级,状态1,第13行
支票已终止。 收集事实时检测到故障。 可能tempdb空间不足或系统表不一致。 检查以前的错误。
消息7105,第22级,州立9,第13行
数据库ID 6,页面(1:386499),LOB数据类型节点的插槽0不存在。 这通常是由可以读取数据页上未提交的数据的事务引起的。 运行DBCC CHECKTABLE。

DBCC CHECKALLOC命令被中断,出现类似错误。 由于SQL Server版本为9.0.1399(即 RTM,无任何更新。

尝试使用TABLOCK提示并显式提高事务隔离级别并不会导致任何结果(tempdb的磁盘空间足够,而WITH WITH ESTIMATEONLY的DBCC CHECKALLOC失败,并出现相同的错误)。 我真的不想将SP迁移到数据库已损坏的服务器上,而问题出在什么特定对象上则完全无法理解。 此外,似乎DBCC CHECKDB消息与现实无关,因为msdb.dbo.suspect_pages中有一条记录,但是页码与DBCC CHECKDB打印的页码不同。

为了遵循DBCC CHECKDB指令并执行DBCC CHECKTABLE,您需要了解该表。 经过长时间的搜索, 发现了一条指令。
注意事项
抱歉,错误消息和代码中的表号不匹配。 我从日志中删除了错误,然后在另一个实时的测试环境中执行代码。

我们使用下面的算法来确定两个页面的object_id-从DBCC CHECKDB和嫌疑页面。 问题出在可疑页面的页面中

首先要做的是(在损坏的数据库的情况下)执行DBCC PAGE (database_id,file_id,page_id,printopt):

DBCC TRACEON (3604); DBCC PAGE(5, 1, 3242342, 0) DBCC TRACEOFF (3604); 

要么:

 DBCC PAGE(5, 1, 3242342, 0) WITH TABLERESULTS. 

如果您很幸运(或者您正在现场演出),那么您将看到Metadata:ObjectId字段,以及所需的object_id:



但是,如果您像我们一样不幸,则会看到以下内容:
元数据:=在离线数据库中不可用
如果元数据不可用,则不会丢失所有内容,在这种情况下,我们需要m_objId字段(AllocUnitId.idObj)。 如果m_objId = 255,则问题是,请关闭文章并查找其他内容(尝试编写所有可以编写的脚本并删除数据,使用“ recovery”参数盲目执行DBCC CHECKDB,等等)。
屏幕截图显示我的m_objId = 9931,即 可以继续。

现在,您需要进行一些计算以计算分配单位ID(有关分配单位的更多信息,请参见此处 ):
分配单元ID = m_objid * 65536 +(2 ^ 56)
在我们的情况下:
分配单位ID = 9931 * 65536 +(2 ^ 56)= 72057594688765952

因此,知道分配单位ID后,您可以在系统视图sys.allocation_units中看到我们拥有的内容

 SELECT * FROM sys.allocation_units WHERE allocation_unit_id = 72057594688765952 



在这里,如果类型= 1或3(IN_ROW_DATA,ROW_OVERFLOW_DATA),则容器container_id = sys.partitions.hobt_id列(“堆或B树ID”),即 您可以运行请求:

 SELECT * FROM sys.partitions WHERE hobt_id = 72057594661437440 



此处已经有正确的object_id和index_id。 现在,您可以查看sys.objects和sys.indexes中的内容,然后执行:

 SELECT OBJECT_NAME(object_id) 

幸运的是,无论是在实际情况还是在这里,在重组后所有非群集索引都得到确认(所有内容都恢复正常)(事实上,没有,但这是另一回事了)。

参考文献
如何使用DBCC PAGE
解决和修复SQL Server页面级损坏
什么是分配单位?
从页面ID查找表名
sys.allocation_units

Source: https://habr.com/ru/post/zh-CN430824/


All Articles