Sql-Server

備份檢測到損壞,但 CHECKDB 沒有

  • July 13, 2018

我有一個數據庫,當我執行備份命令時

BACKUP DATABASE [MyDatabase] TO     
DISK =  'G:\Backup\MyDatabase_01_01_2018.bak'   
WITH    NOFORMAT, NOSKIP, COMPRESSION, INIT, BUFFERCOUNT = 100

我收到錯誤消息

消息 3043,級別 16,狀態 1,第 8 行

備份“MyDatabase”在文件“F:\Data\MyDatabase_1.ndf”的頁面 (1:745345) 上檢測到錯誤。

消息 3013,級別 16,狀態 1,第 8 行

備份數據庫異常終止。

我執行了一個完整的 CHECKDB,但它返回乾淨。我確實注意到頁面驗證選項已設置為 NONE(不是我做的),所以我將其更改為 CHECKSUM 並重建數據庫中的所有索引以使其寫入所有頁面並生成校驗和。在此之後,備份仍然失敗並且 checkdb 仍然顯示乾淨(所以沒有變化)。

DBCC CHECKDB('MyDatabase') WITH NO_INFOMSGS, ALL_ERRORMSGS,
DATA_PURITY, EXTENDED_LOGICAL_CHECKS;

從 SQL 日誌:

xxx 執行的 DBCC CHECKDB (MyDatabase) WITH all_errormsgs, no_infomsgs, data_purity 發現 0 個錯誤並修復 0 個錯誤。經過時間:0 小時 21 分 46 秒。內部數據庫快照具有拆分點 LSN = 000ab776:0000112f:0001 和第一個 LSN = 000ab776:0000112d:0001。

我執行了 DBCC PAGE,但它出錯(甚至似乎一開始都沒有返回正確的頁面)。我可以使用列印選項 2 執行它並返回,但老實說我不知道我在那裡尋找什麼。

DBCC PAGE ('MyDatabase',1,745345,3)
頁:(3:513793)

緩衝:


BUF @0x00000003811F8280

bpage = 0x00000000F2D70000 bhash = 0x0000000000000000 bpageno = (1:745345)
bdbid = 5 breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 44283 bstat = 0x809
部落格 = 0x5adb215a bnext = 0x0000000000000000 

頁眉:


頁面@0x00000000F2D70000

m_pageId = (3:513793) m_headerVersion = 1 m_type = 2
m_typeFlagBits = 0x4 m_level = 0 m_flagBits = 0x0
m_objId (AllocUnitId.idObj) = 1075937538 m_indexId (AllocUnitId.idInd) = 2
元數據:AllocUnitId = 633462595911680 元數據:PartitionId = 0
元數據:IndexId = -1 元數據:ObjectId = 0 m_prevPage = (3:513795)
m_nextPage = (3:513820) pminlen = 17 m_slotCnt = 426
m_freeCnt = 2 m_freeData = 7338 m_reservedCnt = 0
m_lsn = (608841:643611:411) m_xactReserved = 0 m_xdesId = (0:0)
m_ghostRecCnt = 0 m_tornBits = 0 DB 片段 ID = 1

分配狀態

GAM (1: 511232) = 已分配 SGAM (1: 511233) = 未分配 
PFS (1:744096) = 0x40 已分配 0_PCT_FULL DIFF (1:511238) = 未更改
ML (1:511239) = NOT MIN_LOGGED 

消息 2514,級別 16,狀態 8,第 20 行

發生 DBCC PAGE 錯誤:頁面元數據無效 - 無法轉儲樣式 3。

有什麼想法我可以嘗試下一步嗎?伺服器版本是

select @@version
Microsoft SQL Server 2014 (SP2-CU11) (KB4077063) - 12.0.5579.0 (X64)
2018 年 2 月 21 日 12:19:47
版權所有 (c) 微軟公司
Windows NT 6.3(內部版本 9600:)(管理程序)上的開發人員版(64 位)

DB 的兼容級別為 100 (SQL 2008)。

這個答案取自 Paul Randal 撰寫的 SQLskills.com 時事通訊的一期,關於“一個數據庫會因頁面校驗和錯誤而導致備份失敗,但通過了DBCC CHECKDB”。

唯一可能發生這種情況的情況是,當一個擴展數據塊是混合擴展數據塊(擴展數據塊中的 8 個頁面可以分配給潛在的 8 個不同的分配單元——請參見此處並且某些頁面被錯誤地標記為由相關 PFS 頁面分配時。

發生這種情況時,DBCC CHECKDB將不會嘗試讀取這些頁面,因為它會從分配單元的 IAM 頁面(其中第一個列出從混合範圍分配的頁面)派生要讀取的頁面。這種情況是DBCC CHECKDB的腐敗檢測邏輯中的一個缺口。

$$ Because $$ DBCC CHECKDB無法檢測到損壞,因此無法進行修復以修復它們。因此,使用DBCC WRITEPAGE,我直接在 PFS 頁面中計算了錯誤分配頁面的分配狀態所需的更改,並且成功了! DBCC CHECKDB 這是一種極為罕見的情況——失敗但備份會成功的情況更為常見。

在我看來,Paul 的解決方案遠遠超出了您所做的導出和導入數據的範圍,所以我認為您做了正確的事情。

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