使用 bcp 导出数据以处理损坏的数据

spi*_*iky 1 sql-server bcp corruption sql-server-2014

DBCC CHECKDB在 SQL Server 2014 上已损坏行的表上运行时遇到一致性错误。在前 30,000 行(总计 140 万(140 万)行)之后,我遇到了损坏错误。

我想尝试bcp将数据取出,直到损坏为止。我想跳过损坏的行。我想bcp在损坏范围之后并尽量减少数据丢失。

我该怎么做?请详细说明。

另请参阅我之前的问题:在 SQL Server 2014 中的几个表上运行 CHECKDB 的一致性错误

Bre*_*zar 6

首先,这是我关于如何解决腐败问题的清单。这是一个大问题 - 比我在这里可以涵盖的范围大 - 但基于这个声音,我认为你没有涵盖一些基础知识(比如尝试从备份中恢复,或者确保你甚至有备份.)

当您开始收到损坏错误时,每次访问存储时,您都可能使问题变得更糟。例如,我处理了一个损坏的存储阵列,我们读取的数据越多,它损坏的就越多。(我读了一张桌子,它很好,然后十五分钟后,它也被冲洗了。)就像一个鬼屋,你需要尽快离开那个存储设备,并在其他地方解决你的恢复工作.

一旦您在另一个存储设备上,如果您可以将损坏隔离到单个表(这不太可能,但您暗示您已经这样做了),那么:

  • 在 CHECKDB 的输出中,确定哪些索引受到影响(您可以通过索引 ID 看到 - 0 是堆,1 是聚集索引,2 及更高是非聚集索引)
  • 如果您在索引 0/1 中有损坏,那么对于加分,请分别从每个索引中复制数据。您可能能够为聚集索引中损坏的行取回某些列。(如果您在多个非聚集索引之间发生损坏,您可能能够从某些非聚集索引中获取所有行,但不能从其他非聚集索引中获取。)
  • 如果您可以确定哪些页面受到影响,那么您需要设计 WHERE 子句来处理损坏的页面。(SQL Server 不会优雅地跳过损坏的页面 - 由您来设计查询以在它遇到损坏之前停止。)

例如,考虑按姓氏和名字组织的电话簿。如果您知道包含 Ozar, Brent 的页面已损坏,那么您可能必须选择不超过我姓氏的用户,但在此之前停止 - 然后对姓氏高于我的用户运行第二次查询。

不过,诀窍在于:腐败将席卷整个桌子。您将要做大量的工作,试图绕过不同的损坏页面。

这并不容易,这就是我编写清单的原因 - 以及为什么它不尝试解决这一部分。你说的是腐败盛行时的几天,甚至几周的工作。