Sql-Server

執行 DBCC Checktable 時出錯(表名,repair_allow_data_loss)

  • January 10, 2022

我執行 DBCC CheckDB 並在數據庫中遇到了一些一致性錯誤。為了恢復所有數據,我已將數據庫中的所有數據導出到一個新數據庫中,一個表除外。當我嘗試將該表中的所有數據複製到新數據庫時,我收到一條錯誤消息

“目前命令發生嚴重錯誤。如果有結果,應丟棄。”

所以我在表上執行 DBCC CheckTable(tablename) 以確保這是導致問題的表。它給出了與 CheckDB 相同的一致性錯誤。

一旦我執行 CheckTable,它就告訴我我能做的最低限度是使用 repair_allow_data_loss 執行。我將數據庫設置為 SINGLE_USER 模式,然後執行 DBCC CheckTable(tablename, repair_allow_data_loss) 命令,現在出現此錯誤

未處理修復語句。數據庫中的一個或多個文件是只讀的,必須使其可寫才能執行修復。

我檢查以確保文件和文件組都是可寫的並且它們都是可寫的,所以我不確定是什麼導致了問題。

我嘗試進行備份並將其恢復到另一台伺服器,我嘗試製作數據庫的新副本,我嘗試將文件設為只讀,然後再次使它們可寫。這些東西都不起作用,並且都產生了關於文件只讀的相同錯誤。

有人對我還可以嘗試什麼有任何想法嗎?

作為參考,我正在執行 SQL Server 2014 SP2。

編輯:這裡有使用 WITH NO_INFOMSGS, ALL_ERRORMSGS 的輸出

  • 消息 8952,級別 16,狀態 1,第 1 行表錯誤:表 ‘sys.sysschobjs’ (ID 34)。索引“nc1”(ID 2)中的索引行與任何數據行都不匹配。可能的額外或無效密鑰:
  • 消息 8956,級別 16,狀態 1,行 1 索引行 (1:18806:22),其值 (nsclass = 0 和 nsid = 1 和名稱 = ’tmp324504_734167628_1’ 和 id = 385811436) 指向由 (id) 標識的數據行= 385811436)。
  • CHECKDB 在表“sys.sysschobjs”(對象 ID 34)中發現 0 個分配錯誤和 1 個一致性錯誤。
  • 消息 8944,級別 16,狀態 12,第 1 行表錯誤:對象 ID 1993058136,索引 ID 1,分區 ID 72057684034650112,分配單元 ID 71906736119218176(LOB 數據類型),頁面 (1:28439),第 0 行。測試(ColumnOffsets < = (nextRec - pRec)) 失敗。值為 32512 和 8037。
  • 消息 8944,級別 16,狀態 12,第 1 行表錯誤:對象 ID 1993058136,索引 ID 1,分區 ID 72057684034650112,分配單元 ID 71906736119218176(LOB 數據類型),頁面 (1:28439),第 0 行。測試(ColumnOffsets < = (nextRec - pRec)) 失敗。值為 32512 和 8037。
  • 消息 8965,級別 16,狀態 1,行 1 表錯誤:對象 ID 1993058136,索引 ID 1,分區 ID 72057684034650112,分配單元 ID 71906736119218176(類型 LOB 數據)。頁 (1:28439)、槽 0、文本 ID 69999198208 處的行外數據節點被頁 (1:27785)、槽 0 引用,但在掃描中未看到。
  • 消息 8928,級別 16,狀態 1,行 1 對象 ID 1993058136,索引 ID 1,分區 ID 72057684034650112,分配單元 ID 71906736119218176(LOB 數據類型):無法處理頁面 (1:28439)。有關詳細資訊,請參閱其他錯誤。
  • 消息 8929,級別 16,狀態 1,行 1 對象 ID 1993058136,索引 ID 1,分區 ID 72057684034650112,分配單元 ID 72057693155753984(行內數據類型):在 ID 為 69999198208 的行外數據中發現的錯誤由數據記錄擁有按 RID = (1:869011:3)
  • CHECKDB 在數據庫“DataCorruption”中發現 0 個分配錯誤和 6 個一致性錯誤。repair_allow_data_loss 是 DBCC CHECKDB (DataCorruption) 發現的錯誤的最低修復級別。

從評論中,我看到您將其縮小到一個損壞的行。您可以通過十六進制編輯器獲取該行中的基礎數據(或至少大部分數據)。Paul Randal 有關於如何以這種方式破解打開的 MDF 文件的很好的資訊,這裡也是 Kendra Little 的一篇文章。

https://littlekendra.com/2011/01/24/corrupthexeditor/

這篇文章是關於如何使用十六進制編輯器來破壞數據庫的,但是您已經掌握了它,所以請查看下面的步驟“這是我們一直在等待的時刻:刪除該頁面”。

以這種方式提取資訊對數據庫不健康,因此請確保您使用的是備份!

根據數據,您通常可以看到足以拼湊損壞的值。

首先,確定您無法獲得的最後一行的價值。很有可能,它真的沒那麼重要,所以你可以停下來,因為你已經把其他每一行都排除在外了。

如果這很重要,請繼續工作,但要了解沒有良好的損壞前備份的損壞數據意味著數據失去!!!

如果它抱怨文件和/或文件組是只讀的,並且您已經檢查了 SQL 中的文件和文件組,甚至來回更改它們……這些更改是否適用於每個文件和每個文件組?再試一次; 如果您嘗試設置一個 READ_ONLY 但它失敗了,那就是一個線索。還要查看作業系統文件系統級別 - 實際的 MDF 或 NDF 是只讀的嗎?SQL Server 是否完全控制目錄和文件?

也許它是財務數據,並且可以通過對賬過程恢復,因為所有數字都必須平衡。

也許該行或其中的大部分可以通過其他數據重新創建,知道該數據的業務規則嗎?

該表是否是仍然可用的任何導出、輸出文件、報告、提取等的一部分?如果是這樣,您可能能夠從這些輸出源中找到該行的部分或全部。

您當然可以使用十六進制編輯器,如果您的數據未加密,請嘗試找到該特定表的正確 8k 頁,然後仔細查看以嘗試找到受影響行的數據;看看你能找到什麼,但這充其量只是猜測,不應該依賴 - 你正在查看實際上已損壞的數據……或者這不是首先正確的數據。

引用自:https://dba.stackexchange.com/questions/194500