說明:災難恢複系列的文章是由 Robert Davis 寫的,發布在SQLSoldier, 個人認為挺不錯的,所以根據自己的理解,邊測試邊整理,並非直接翻譯,如有不準確,歡迎指正。
本篇進入資料庫災難恢複第五篇,上一篇示範了修複簡單的非叢集索引損壞,今天,我們將看一個稍複雜點兒的,那就是管理區分配頁損壞,不過分配頁無法修複,只能恢複整個資料庫。
什麼是管理區分配頁?
管理區分配頁是資料檔案中特殊的頁,用來跟蹤和管理區分配,本篇將關注三種:
全域分配映射表 (GAM):記錄已指派的區,對於一個資料檔案,每4GB會有一個GAM頁,它的ID總是為2,之後每511,232頁出現一次。
Page ID = 2 or Page ID % 511232
共用全域分配映射表 (SGAM) :記錄當前用作混合區且至少有一個未使用的頁的區,每4GB會有一個SGAM頁,它的ID總是為3,之後每511,232頁出現一次。
Page ID = 3 or (Page ID – 1) % 511232
頁可用空間 (PFS):記錄每頁的分配狀態,是否已指派單個頁以及每頁的可用空間量,每64MB會有一個PFS頁,它的ID總是為1,之後每8,088頁出現一次。
Page ID = 1 or Page ID % 8088
如果PAGE id是1/2/3,那麼很明顯會知道他們是什麼管理區分配頁,如果PAGE ID很大,那麼我們有兩個辦法來區分它們:
一個辦法是採用SQL指令碼計算:
Declare @PageID int;-- Enter page number-- e.g., 8088 = PFS pageSet @PageID = 8088;Select Case When @PageID = 1 Or @PageID % 8088 = 0 Then 'Is PFS Page' When @PageID = 2 Or @PageID % 511232 = 0 Then 'Is GAM Page' When @PageID = 3 Or (@PageID - 1) % 511232 = 0 Then 'Is SGAM Page' Else 'Is Not PFS, GAM, or SGAM page' End
另一個辦法是採用DBCC PAGE來看它的m_type值:
現在按照下面的步驟:
現在我們已經知道哪些是管理區分配頁,接下來依然按三個步驟進行:
1.確定損壞(使用DBCC CHECKDB)
2.確定損壞的對象及物件類型(如索引頁、分配頁等)
3.確定適合的修複方法
確定損壞
首先,請先下載一個PFS損壞的資料庫,然後運行DBCC CHECKDB:
DBCC CheckDB(PFSCorruption) With No_InfoMsgs, All_ErrorMsgs, TableResults;
由於返回太多我們不需要的列,為了更好的體現這裡的示範效果,減去一些列,不過在實際做故障排除時,還是要用返回全部列,這裡僅為了示範:
Declare @DBCC Table ( Error int, Level smallint, State tinyint, MessageText varchar(2500), RepairLevel varchar(30) null, Status tinyint, DbId int, DbFragId int, ObjectId int, IndexId int, PartitionId bigint, AllocUnitId bigint, RidDbId int, RidPruId int, [File] int, Page int, Slot int, RefDbId int, RefPruId int, RefFile int, RefPage int, RefSlot int, Allocation bigint)Insert Into @DBCCExec sp_executesql N'DBCC CheckDB(PFSCorruption) With No_InfoMsgs, All_ErrorMsgs, TableResults;';Select Level, State, MessageText, RepairLevel, ObjectId, IndexId, [File], Page, RefFile, RefPageFrom @DBCC;
結果:
確定損壞的對象
這一步我們需要確定真正的錯誤,可以看到有較進階別的錯誤號碼16,這是需要我們要仔細查的,另外State列為5表示一個未知的錯誤導致DBCC CHECKDB終止執行,另外這兩行中不同的pageid(1:6)和(1:7)可能會誤導你以為是他倆是損壞的頁,但實際上是(1:1)中有這兩個錯誤page值而已,所以需要關注的是RefFile和RefPage這兩個列,而不是File和Page列。
從上面DBCC CHECKDB的結果,可以直接看出是PFS頁面,所以不需要記算也不需要DBCC PAGE去判斷,因為DBCC的結果是很明顯的了。
採用適合的方法
在開頭的時候我們已經說過管理區分配頁不能被修複或還原,所以我們不得不做整個資料庫的還原,那就需要檢查備份的情況,尤其是交易記錄備份到什麼時間,然後開始做還原,如果沒有備份,則需要將資料導到一個建立的資料庫中。如果你能手動用一個十六進位的編輯器手動修複它(不是NB就是DS),那麼最好先copy出一份來做這個操作。
總結
本篇主要還是在講述如何確定具體的損壞對象,主要是確定管理區分配頁GAM/SGAM/PFS頁,不過遺憾的是它們都無法直接修複。
下載本篇樣本的資料庫及代碼
SQL Server 災難恢複31天之第7天:災難恢複服務等級協議(資料復原點目標和資料恢復點目標)