修复数据库中不一致的页面


8

我们有一个SQL 2000 DB。服务器因RAID阵列故障而崩溃。现在,当我们运行DBCC CHECKDB时,我们得到一个错误,即9页中有27个一致性错误。

在这些页面上运行DBCC PAGE时,会得到以下信息:

Msg 8939, Level 16, State 106, Line 1
Table error: Object ID 1397580017, index ID 2, page (1:8404521). Test (m_freeCnt == freeCnt) failed. Values are 2 and 19.
Msg 8939, Level 16, State 108, Line 1
Table error: Object ID 1397580017, index ID 2, page (1:8404521). Test (emptySlotCnt == 0) failed. Values are 1 and 0.

由于指示的索引是非聚集索引,并且由包含2列的唯一constarint创建,因此我们尝试删除并重新创建索引。这导致以下错误:

CREATE UNIQUE INDEX terminated because a duplicate key was found for index ID 2. Most significant primary key is '3280'. 
The statement has been terminated. 

但是跑步

Select var_id,result_on
from tests
group by var_id,result_on
having count(*)>1

返回0行。

这是我们计划要做的事情:

  • 还原数据库的服务器前崩溃副本并运行DBCC CHECKDB
  • 如果恢复干净,则再次恢复而无法恢复
  • 应用所有后续的TLOG备份
  • 停止生产应用程序,进行尾日志备份并将其也应用
  • 删除产品数据库并重命名新恢复的数据库以使其成为产品
  • 启动产品应用

有人可以用这种方法打孔吗?也许,建议其他方法?我们需要的是最少的停机时间。

SQL 2000 DB大小94 GB具有损坏页面的表具有4.6亿多行数据

谢谢您的帮助。

拉吉


1
我喜欢你的方法。我感觉合理。也许将损坏的数据库
放在

另外,当情况稳定下来时,请计划您的2008或2008升级:-)
user24161'2

(即2005或2008升级)
user24161 2010年

+1具有有效且非常合适的恢复计划
Andrew

Answers:


2

您的恢复解决方案是继续进行教科书的方式。假设您有适当的备份,并且可以备份损坏的数据库的事务日志,那么您的策略就是要实施的教科书。

但是,在继续之前,您是否考虑过仅重新创建受影响的表的可能性?

有时,您可以通过执行以下操作来创建受影响表的精确副本:

select *
into NewTableFromOld
from DamagedTable

然后只需使用新的删除/交换损坏的表,记住要添加适当的约束和索引。


感谢您的回复。您的方法看起来不错,但考虑到该表具有4.61亿行数据,那么当我执行选择*时,对生产会有什么影响?那会不会获得锁定并提高性能?

如果您使用with(nolock)查询提示号,则不会。但是,您可能希望验证复制副本时源表和目标表之间没有任何变化。尽管您没有阻止应用程序进行更改,但是无论如何在表构建期间都需要这样做。这样的操作将有磁盘性能开销。
约翰·桑索

我个人将首先尝试这种方法,您可以使用nolock选项进行测试,还可以检查所需的时间。如果它能正常工作,那么我将在再次执行该操作时将数据库置于单用户模式,以确保在进程运行时不会发生任何更改。如果可行,在这种方法下的停机时间将大大缩短。
baldy 2010年

如果要执行此操作,建议您首先创建表(通过脚本化原始表)。然后使用“ INSERT INTO newTable SELECT”和“ SELECT INTO”。使用“ SELECT INTO”可能会遇到性能问题。
SQL3D 2011年

0

我会尝试将数据首先扩展到文件中,然后再将其重新存储到新表中。SELECT INTO不适合该数量的记录...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.