時間:2015-06-28 00:00:00 來源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評論(1)
在管理數(shù)據(jù)庫時很容易出現(xiàn)問題,但是出現(xiàn)數(shù)據(jù)庫頁損壞或校驗錯誤時該如何解決,這也是大家需要了解的重要內(nèi)容。
最近一直在進一步學習數(shù)據(jù)庫故障的處理方面的知識,做為一個數(shù)據(jù)庫維護人員,我即期望遇到所有的數(shù)據(jù)庫出錯的案例,以增加自己的經(jīng)驗,但同時又擔心遇到這樣或那樣無法處理的數(shù)據(jù)庫故障而導致數(shù)據(jù)丟失。
前幾天看到一個文章,是說一個網(wǎng)站管理員在招聘DBA時,提出一個問題:"如果在SQL Server 日志里發(fā)現(xiàn)一個頁損壞或是校驗和錯誤應(yīng)該如何處理?"網(wǎng)站管理員描述,大概有90%的應(yīng)聘者都會采用一個方案,用DBCC CHECKDB加上其中的一個修復選項,但其中也基本沒有人能具體解釋DBCC CHECKDB修復的過程或是工作原理及能修復到什么程度。
借助聯(lián)機文檔以及個人的一些理解和經(jīng)歷,解釋一下如何面對這個問題:"當數(shù)據(jù)庫頁損壞或校驗和出錯時如何處理?"
首先,需要先了解DBCC CHECKDB,聯(lián)機文檔url:
http://technet.microsoft.com/zh-cn/library/ms176064.aspx
通過聯(lián)機文檔,可以得知有REPAIR_ALLOW_DATA_LOSS | REPAIR_FAST | REPAIR_REBUILD三個修復選項,而提供實際功能的只有REPAIR_ALLOW_DATA_LOSS和REPAIR_REBUILD兩個,其 中REPAIR_ALLOW_DATA_LOSS 嘗試修復報告的所有錯誤,這些修復可能會導致一些數(shù)據(jù)丟失;而且REPAIR_REBUILD執(zhí)行不會丟失數(shù)據(jù)的修復,包括快速修復(如修復非聚集索引中 缺少的行)以及更耗時的修復(如重新生成索引);可見REPAIR_REBUILD是我們期望的。
當你從SQL Server log里或是在程序查詢數(shù)據(jù)庫或是定期通過DBCC CHECKDB為數(shù)據(jù)庫做體檢的時候,出現(xiàn)了頁損壞或校驗和出錯信息時,如:
---------------------------------------------------------------------------------------------------------------------------------? M8928sg , Level 16, State 1, Line 1? Object ID 2088535921, index ID 0, partition ID 72345201021503994, alloc unit ID 72345201051571606 (type In-row data): Page (1:94299) could not be processed.See other errors for details.? Msg 8939, Level 16, State 98, Line 1? Table error: Object ID 2088535921, index ID 0, partition ID 72345201021503994, alloc unit ID 72345201051571606 (type In-row data), page (1:94299). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed.? CHECKDB found 0 allocation errors and 2 consistency errors in table 'yourtable' (object ID 2088535921).? CHECKDB found 0 allocation errors and 2 consistency errors in database 'yourdb'.? repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (yourdb).? --------------------------------------------------------------------------------------------------------------------------------- 現(xiàn)在我們應(yīng)該如何做?
? 1.通過上面的提示,告訴我們:對象 2088535921出錯,它是一個表,頁面為1:94299
? 2.接下來,我們判斷損壞的頁在堆上還是聚集索引還是非聚集索引,sql server方法為:
dbcc traceon (3604, -1)? go? dbcc page('yourdb', 1, 94299, 3)? go 在輸出的結(jié)果里(會報錯,但可以看到頁頭信息),可以看到
Metadata: IndexId = n
如果n是0而表示是堆,1表示是聚集索引,>1是表示非聚集索引
ps:其實從提示信息的Object ID 2088535921, index ID 0 ,也可以簡單判斷是堆.
? 3.根據(jù)上面的第2步,我們知道這個頁面是堆,這對我們來講,不是好消息,因為如果是>1,我們可以刪除該非聚集索引,再重建索引,不會丟失數(shù)據(jù),而0或1則是元數(shù)據(jù)受損,這意味著有丟失元數(shù)據(jù)的可能性。
那么如何僅僅修復這個數(shù)據(jù)頁呢,這里我們假設(shè)該庫是full模式,并且有良好的備份策略,有全備和日志備份。
那么我們可以進行頁面級還原操作,步驟如下:
a.首先進行一次日志備份,如果你不放心,還可以再做一個全備;
backup log yourdb to disk='D:\DBBak\yourdb_a.trn'
b.通過完整備份來恢復該page. (yourdb.bak是一個全備。);
restore database yourdb page= '1:94299' from disk='D:\DBBak\yourdb.bak' with norecovery
c.恢復這個全備之后的差異(假設(shè)有差異yourdb.dif),如果沒有差異備,直接到d步驟;
restore database yourdb from disk='d:\DBBak\yourdb.dif'with norecovery
d.恢復之后的log備份,可能有多個(假設(shè)為yourdb_1.trn,yourdb_2.trn);
restore log yourdb from disk='d:\DBBak\yourdb_1.trn' with norecovery? restore log yourdb from disk='d:\DBBak\yourdb_2.trn' with norecovery? restore log yourdb from disk='d:\DBBak\yourdb_a.trn' with norecovery e.做一個最新的日志備;
backup log yourdb to disk='D:\DBBak\yourdb_e.trn' f.還原最后的(e步驟)日志備份;
restore log yourdb from disk='d:\DBBak\yourdb_e.trn' with recovery g.結(jié)束
? 4.經(jīng)過步驟三之后,我們再來檢查一下該表是否還有錯,從提示信息Object ID 2088535921里,我們查出表名tbname;
tbname: select object_name(2088535921) 然后 dbcc checktable('yourtable')檢測,如果沒有報錯,則表示修復完成
? 5.最后,對整個庫再做一次dbcc checkdb檢查;
ps:需要注意的是,sql server 的page級恢復在企業(yè)版和開發(fā)版中,支持聯(lián)機恢復page數(shù)據(jù),在標準版只能脫機修復;
在dbcc checkdb修復選項里,用repair_rebuild修復數(shù)據(jù),聯(lián)機文檔稱是不丟失數(shù)據(jù),但在某些環(huán)境下可能也會丟失數(shù)據(jù),不過,我沒遇到過:)
用repair_allow_data_loss選項時,聯(lián)機文檔稱可能會丟失數(shù)據(jù),而對于堆或聚集索引的頁損壞,sql server 會釋放該頁面,造成數(shù)據(jù)的丟失,但repair_allow_data_loss選項有兩種情況是不會丟失數(shù)據(jù),一種是非聚集索引上的頁錯誤,另外是lob頁數(shù)據(jù)錯誤。
數(shù)據(jù)庫頁損壞總結(jié):
一定要有良好的數(shù)據(jù)庫備份策略,備份重于一切;
要有異機備份,并且時時同步該備份文件;
當數(shù)據(jù)庫出現(xiàn)故障時,不要過于心急,冷靜分析一下錯誤;
如果不能確定如何做,可以借助google,如果你的錯誤信息里中文的,請翻譯成英文后再google,這樣搜到解決方案的可能性更大;
做修復時,一定要再備一次數(shù)據(jù)庫;
dbcc checkdb的repair_allow_data_loss選項永遠是最后的選擇。
結(jié)束,如有錯誤,請指正。
關(guān)鍵詞標簽:數(shù)據(jù)庫
相關(guān)閱讀
熱門文章 淺談JSP JDBC來連接SQL Server 2005的方法 SqlServer2005對現(xiàn)有數(shù)據(jù)進行分區(qū)具體步驟 sql server系統(tǒng)表損壞的解決方法 MS-SQL2005服務(wù)器登錄名、角色、數(shù)據(jù)庫用戶、角色、架構(gòu)的關(guān)系
人氣排行 配置和注冊O(shè)DBC數(shù)據(jù)源-odbc數(shù)據(jù)源配置教程 如何遠程備份(還原)SQL2000數(shù)據(jù)庫 SQL2000數(shù)據(jù)庫遠程導入(導出)數(shù)據(jù) SQL2000和SQL2005數(shù)據(jù)庫服務(wù)端口查看或修改 修改Sql Server唯一約束教程 SQL Server 2005降級到2000的正確操作步驟 sql server系統(tǒng)表損壞的解決方法 淺談JSP JDBC來連接SQL Server 2005的方法