Sql-Server

SQL Server 中的 DBCC 一致性錯誤

  • December 27, 2021

我在我們的生產 SQL Server 2014 中執行 DBCC CheckDB。它報告了一個一致性錯誤:

Failed:(-1073548784) Executing the query "DBCC CHECKDB(N'MYDB')  WITH NO_INF..." failed with the following error: 

"Table error: Object ID 629577392, index ID 1, partition ID 72057594387039319, alloc unit ID 72057594045596759 (type LOB data). The off-row data node at page (1:6009), slot 24, text ID 15754068079 is not referenced.

CHECKDB found 0 allocation errors and 1 consistency errors in table 'MYTABLE' (object ID 629577281).
CHECKDB found 0 allocation errors and 1 consistency errors in database 'MYDB'.

repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (MYDB).". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.

由於我們沒有該數據庫的良好備份,我們必須路由到以下場景。

我做了什麼來解決問題:

  1. 我將最近的備份文件從 Prod 恢復到 UAT 並再次執行 DBCC CheckDB 以複製錯誤。同樣的一致性錯誤又回來了。
  2. Ran DBCC CHECKTABLE (MYTABLE) = 相同的一致性錯誤顯示:
Table error: Object ID 629577392, index ID 1, partition ID 72057594387039319, alloc unit ID 72057594045596759 (type LOB data). 

The off-row data node at page (1:6009), slot 24, text ID 15754068079 is not referenced.
DBCC results for 'MYTABLE'.
There are 53635 rows in 2705 pages for object "MYTABLE".
CHECKTABLE found 0 allocation errors and 1 consistency errors in table 'MYTABLE' (object ID 629577281).
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKTABLE
  1. 然後執行以下步驟:

– 步驟 1 更改數據庫

$$ MYDB $$SET SINGLE_USER WITH ROLLBACK IMMEDIATE; – 步驟 2 DBCC CHECKDB(N'

$$ MYDB $$’, REPAIR_ALLOW_DATA_LOSS);

Msg 8964, Level 16, State 1, Line 3
Table error: Object ID 629577392, index ID 1, partition ID 72057594387039319, alloc unit ID 72057594045596759 (type LOB data). The off-row data node at page (1:6009), slot 24, text ID 15754068079 is not referenced.
       The error has been repaired.
There are 53635 rows in 2705 pages for object "MYTABLE".

– 步驟 3 DBCC CHECKDB ('

$$ MYDB $$’) —(重新執行以檢查任何其他錯誤 = 未報告錯誤) – 步驟 4 更改數據庫

$$ MYDB $$設置多使用者;—(將其設置回多使用者模式=使用者可以訪問數據庫) 我的問題/疑慮:

  1. 我怎麼知道哪些數據失去了?據我了解,似乎沒有任何數據失去,因為在修復之前該表有 53635 行。修復後它仍然有 53635 行。
  2. 將數據庫設置為單使用者模式時,我們是否需要為該確切站點安排停機時間/中斷?
  3. 在生產中進行修復後,需要注意哪些最佳實踐?

我怎麼知道哪些數據失去了?

那麼這真的很難找到 AFAIK,最好的方法是測試你的數據庫和應用程序功能。您說數據行相同,請同時檢查約束和業務規則。由於損壞僅限於一張表,並且您可以進行備份並進行恢復,我猜損壞並沒有那麼嚴重。在這種情況下,您可以在新恢復的數據庫上執行 checkdb repair,然後比較兩個數據庫中的表。好吧,這很難,但幾乎沒有其他方法。

將數據庫設置為單使用者模式時,我們是否需要為該確切站點安排停機時間/中斷?

是的,顧名思義,如果允許單個使用者,則需要啟動其他使用者,包括應用程序。數據庫的修復是離線操作,因此需要停機。

在生產中進行修復後,需要注意哪些最佳實踐?

在數據庫上再次執行 checkdb,如果它沒有指向任何錯誤,我猜你的修復是成功的。另請注意,Checkdb 無法修復某些問題。如果你想縮短這個因為數據庫很大,那麼你可以執行dbcc checkconstraint(). 完整的 checkdb 將包括 checkconstraint。

另請閱讀緊急模式修復如何工作?

看起來它是來自行外 LOB 列(例如varchar(max)or varbinary(max))的孤立數據,並且 DBCC 已將其刪除。沒有刪除整行。

鑑於它沒有被任何行引用,或者該行以某種方式失去了引用,您必須確定哪一行缺少數據;或者它應該被設置為 null 並且數據最終成為孤立的。


如文件所述,要使用修復選項,數據庫必須處於單使用者模式。因此必須安排停機時間。

但是,您可以使用DBCC CHECKTABLE WITH REPAIR_ALLOW_DATA_LOSS. 這將最大限度地減少停機時間。


**數據庫通常非常有彈性。**即使是意外關閉,通常也可以恢復到一致的狀態。

通常,數據庫不一致可能來自以下幾種情況之一:

  • 物理磁碟故障。為此,最好的解決方案是鏡像驅動器。
  • 作業系統問題,例如錯誤的驅動程序或防病毒軟體、實際的病毒/惡意軟體、其他作業系統錯誤。其中,有缺陷的司機最有可能。
  • 記憶體故障。對於 ECC 伺服器 RAM,這不太可能發生。
  • 在沒有斷電保護的驅動器上,意外斷電也可能導致它。確保您的驅動器具有 PLP。

定期調度DBCC對於監控損壞發生是必不可少的,伺服器不一定會自動注意到它。

此外,**良好的備份計劃是避免需要搞亂維修的最佳方式。**每晚進行一次完整備份,再加上每 10 或 15 分鐘一次的事務日誌備份,可以最大限度地減少數據失去。

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