遇到麻烦 - SQL 数据库损坏

Los*_*SQL 3 sql-server errors

最近我们无法做任何事情,因为我们的 SQL 数据库似乎有些损坏。他们告诉我们,损坏已经存在一年多了,因此没有干净的备份可供恢复。

他们表示不会碰它,因为他们只会从良好的备份中恢复。

当我运行数据库检查时,出现下面列出的错误。

消息 8944,第 16 层,状态 26,第 1 行

表错误:对象 ID 1309576141,索引 ID 1,分区 ID 4372442057594119651328,分配单元 ID 34720157594136100864(类型行内数据),页 (1:1516648),第 9 行。测试 (((DataRecHdr*) m_pRec)->r_tagB = = 0) 失败。值为 64 和 0。

消息 8944,第 16 层,状态 26,第 1 行

表错误:对象 ID 46456432,索引 ID 1,分区 ID 72057594119651328,分配单元 ID 346346100864(类型行内数据),页 (1:1516648),第 9 行。测试 (((DataRecHdr*) m_pRec)->r_tagB = = 0) 失败。值为 64 和 0。

消息 8928,16 级,状态 1,第 1 行

对象 ID 309576141,索引 ID 1,分区 ID 72057594119651328,分配单元 ID 72057594136100864(类型行内数据):无法处理页面 (1:1516648)。有关详细信息,请参阅其他错误。

消息 8976,16 级,状态 1,第 1 行

表错误:对象 ID 309576141,索引 ID 1,分区 ID 72057594119651328,分配单元 ID 72057594136100864(类型行内数据)。扫描中未看到页面 (1:1516648),尽管其父页面 (1:1526647) 和上一页 (1:1515967) 引用了该页面。检查以前的任何错误。

消息 8978,16 级,状态 1,第 1 行

表错误:对象 ID 309576141,索引 ID 1,分区 ID 72057594119651328,分配单元 ID 72057594136100864(类型行内数据)。页面 (1:1517757) 缺少上一页 (1:1516648) 的引用。可能是链条连接问题。

我不知道这是什么,我只知道这是我运行 DBCC CheckDB 的输出。

它指出唯一的修复选项是“数据丢失”,我不知道该部分有多少数据,因为我在这方面完全是新手,而且我还没有找到任何技术人员会接触到这一点。

CHECKDB 在数据库“PSChiro”中发现 0 个分配错误和 5 个一致性错误。Repair_allow_data_loss 是 DBCC CHECKDB (PSChiro) 发现的错误的最低修复级别。DBCC 执行完成。如果 DBCC 打印错误消息,请联系您的系统管理员。

完成时间:2022-11-15T23:30:45.7791319-05:00

此时我迷失了,只想重新站起来并运行。欢迎大家提出意见。

Sha*_*nky 5

您肯定处于困境,因为您的数据库已损坏,索引 ID 1(聚集索引)也已损坏。删除并重新创建表上的索引没有帮助。就像 @Jonathan Fite 建议从提到的对象 ID 中找出该表并查看该表包含的内容。可以建议的一种可能的解决方案是

  1. 使用数据库导入导出向导编写新数据库结构的脚本。如果由于对象损坏而失败,请忽略该表并选择其余其他表。

  2. 运行脚本创建数据库只需确保数据文件物理名称不同,否则会出现错误

  3. 现在使用SSDT 工具将数据从损坏的数据库移动到新数据库。不要导入损坏的表,这个Object ID 309576141

  4. 查看您可以传输多少数据。你能做得更好的极限是。

  5. 现在尝试从损坏的表中移动数据,看看能走多远。

  6. 现在您有了新的数据库,其中几乎包含所有精细的.data。

  7. 在新创建的数据库上运行dbcc checkdb,这应该是干净的。

  8. 现在运行DBCC CHECKDB ('db_name', REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS; 。让该进程运行,看看这是否可以修复您的损坏。

  9. 您现在至少拥有一个包含有效数据的数据库。此过程将尽可能保存最大数据。

  10. 最重要的是找出腐败的根源。可能您的存储设备(连接到 PC 的磁盘)已损坏。确保你解决了这个问题。

编辑:

通过 Skype 联系了 OP,下面是我所做的

  1. 数据库是可访问的,并且一张表中存在损坏。但是应用程序模型抛出错误,因此应用程序几乎关闭。
  2. OP 有备份,但实际上不知道腐败何时开始,因此进行了restore verifyonly大量备份。
  3. 发现备份很好并已恢复,然后再次运行 checkdb ,令我恐惧的是,损坏仍然存在。
  4. 这是很有可能的,因为 verifyonly 检查是有限的。
  5. 识别出已损坏的表。6.运行 checkdb 并且repair_allow_data_loss它起作用了。checkdb 修复了那里的小损坏。

警告他有关 的影响后checkdb with repair_allow_data_loss,他可以接受数据丢失,因为备份已损坏,而且他几乎不知道损坏何时开始。还强调了至少每周运行一次 checkdb 的重要性。

事实证明,checkdb 修复几乎没有数据丢失,从旧的 1 个月备份恢复 OTOH 可能会导致更多数据丢失。

  • 很好的总结,但我觉得这里缺少一个建议:如果数据传输不成功(即步骤 3),请查看该表上存在哪些非聚集索引。尝试运行仅扫描这些 NCI 的查询并将该数据放入临时表中,以防您可以使用该信息来重建无法从任何辅助 NCI 中提取的列。我之前曾多次这样做过,发现关键字段拥有 100% 的数据比运行“repair_allow_data_loss”语句后丢失整个表的 20% 更好。有时你很幸运,NCI 无所不能。 (2认同)