網站首頁 行業(yè)快訊 > 正文
數據庫損壞(SQL Server數據庫損壞、檢測以及簡單的修復辦法)
在一個理想的世界中,不會存在任何數據庫的損壞,就像我們不會將一些嚴重意外情況列入我們生活中的日常一樣,而一旦這類事情發(fā)生,一定會對我們的生活造成非常顯著的影響,在SQL Server中也同樣如此,或許幾年內您沒有遇見過數據庫中出現這類情況,而一旦遇見這類情況,往往伴隨著數據的丟失,宕機,嚴重甚至您本身的職業(yè)生涯也會受到影響。因此對于這類情況,我們需要了解數據庫損壞方面的知識,以便我們能夠事前準備,事后能夠處理。本篇文章會對數據庫損壞的原因、現象、事前和事后的一些處理方法以及簡單的修復方法進行探討。
數據庫為什么會損壞?在了解數據庫損壞之前,首先我們要了解SQL Server是如何將數據保存到數據文件(MDF、NDF等)。無論更新還是插入數據,數據都需要首先在內存中的Buffer Pool駐留,然后通過CheckPoint和Lazy Writer等過程將內存中的數據持久化到磁盤。在這個過程中,數據臟頁由內存寫入持久化的IO子系統(tǒng),在此期間,按照IO子系統(tǒng)的不同,數據可能經過這幾層:
Windows(寫數據一定調用的是WINDOWS API)
Windows底層的中間層(殺毒軟件,磁盤加密系統(tǒng))
網卡、路由器、交換機、光釬、網線等(如果IO子系統(tǒng)不是直連的話)
SAN控制器(如果使用了SAN)
RAID控制器(IO子系統(tǒng)做了RAID)
磁盤或SSD等持久化存儲器
因此,數據頁被寫入持久化存儲期間,可能經過上述列表中的幾項。在經歷上述過程中,硬件環(huán)境會受到很多方面的影響,比如說電壓是否穩(wěn)定、斷電、溫度過高或過低、潮濕程度等,而軟件方面,由于軟件都是人寫的,因此就可能存在BUG,這些都可能導致數據頁在傳輸過程中出現錯誤。
此外,影響磁盤的因素也包括電壓是否穩(wěn)定、灰塵等因素,這些也有可能引起磁盤壞道或整體損壞。
上面提到的所有因素都可以被歸結為IO子系統(tǒng)。因此,造成數據損壞的情況絕大部分是由IO子系統(tǒng)引起的,還有非常非常小的概率內存芯片也會導致數據頁損壞,但這部分情況微乎其微,因此不在本文的討論之列。
上面提到的這些導致數據損壞的原因都屬于天災,還有一些人禍。比如說通過編輯器等手動編輯數據文件、數據庫中還有需要Redo和Undo的事務時(也就是沒有Clean Shutdown)刪除了日志文件(通常會導致數據庫質疑)。
發(fā)現數據庫損壞在我們知道可能造成數據庫的損壞原因之后,接下來我們來看SQL Server是如何監(jiān)測數據庫頁損壞的。
在SQL Server的數據庫級別,可以設置頁保護類型,一共有三個選項:None,CheckSum,Torn_Page_Detection,如圖1所示:
圖頁保護的三種選項
關于這三種選項,首先,請無視None,請不要在任何場景下選擇該選項,該選項意味著SQL Server不對頁進行保護。
其次是TORN_PAGE_DETECTION,在SQL Server中,數據的最小單位是頁,每一頁是8K,但是對應磁盤上往往是16個512字節(jié)的扇區(qū),如果一個頁在寫入持久化存儲的過程中,只寫了一半的頁,這就是所謂的TORN_PAGE_DETECTION,SQL Server通過每個扇區(qū)提512字節(jié)中前2位作為元數據,總共16個扇區(qū)32位4字節(jié)的元數據(頁頭中標識為:m_tornBits),通過該元數據來檢測是否存在部分寫的TORN_PAGE,但該類型的頁驗證無法檢測出頁中的寫入錯誤,因此在SQL Server 2005及以上版本,盡量選擇CheckSum。
在SQL Server 2005及以上版本,引入了CheckSum,CheckSum可以理解為校驗和,當數據頁被寫入持久化存儲時,會根據頁的值計算出一個4字節(jié)的CheckSum存于頁頭(頁頭中標識同為:m_tornBits),和數據在同一頁中一起保存在數據庫中。當數據從IO子系統(tǒng)被讀取到內存中時,SQL Server會根據頁內的值再次計算CheckSum,用該重新計算的CheckSum和頁頭中存儲的CheckSum進行比對,如果比對失敗,則SQL Server就會認為該頁被損壞。
由CheckSum的過程可以看出,只有在頁被寫入SQL Server的過程中才會計算CheckSum,因此如果僅僅改變數據庫選項的話,則頁頭中的該元數據并不會隨之改變。
與IO相關的三種錯誤
通過上述CheckSum的原理可以看出,SQL Server可以檢測出頁損壞,此時,具體的表現形式可能為下述三種錯誤的一種:
823錯誤,也就是所謂的硬IO錯誤,可以理解為SQL Server希望讀取頁,而Windows告訴SQL Server,無法讀取到該頁。
824錯誤,也就是所謂的軟IO錯誤,可以理解為SQL Server已經讀取到該頁,但通過計算CheckSum等值發(fā)現不匹配,因此SQL Server認為該頁已經被損壞。
825錯誤,也就是所謂Retry錯誤。
其中, 上述823和824錯誤都是錯誤等級為24的嚴重錯誤,因此會被記錄在Windows應用程序日志和SQL Server的錯誤日志中,而引起該錯誤的頁會被記錄在msdb.dbo.suspect_pages中。SQL Server錯誤日志中也會記錄到出錯頁的編號,如圖2所示。
圖824錯誤在SQL Server錯誤記錄中的描述
因此,如果我們存在完善的備份的話,我們可以通過備份進行頁還原(在此再次強調一下對于DBA來說,有”備”無患),一個簡單的頁還原代碼如代碼清單1所示。
USE[master]
RESTOREDATABASE[Corrupt_DB]PAGE='1:155'
FROMDISK=N'C:\xxx.bak'
WITHFILE=1,NORECOVERY,NOUNLOAD,STATS=5
代碼清單一個簡單的頁還原代碼,從備份中還原文件ID1中的第155頁
記得我們前面說的,在讀取頁計算校驗和時出錯,這既可能是被寫入持久化存儲的頁本身出錯,也可能是在頁被讀取的過程中出錯,此時SQL Server會嘗試從IO子系統(tǒng)中再次讀取該頁,最多可能是4次嘗試,如果在4次嘗試過程中校驗和通過,則會是825錯誤,否則是824錯誤。這里要注意,與823和824錯誤不同的是,825錯誤是一個等級僅為10的信息。
因此,由于有固定的錯誤編號,因此可以在SQL Server Agent中對823和824設置警報。
備份CheckSum
上述頁CheckSum只有在頁被使用時才會被校驗頁的正確性。在備份數據庫時,可以指定CheckSum選項來使得備份讀取的頁也計算校驗和,從而保證了被備份的數據庫是沒有損壞的。在圖3的備份選項我們可以注意到這兩條:
圖CheckSum和Continue_After_Error選項
如果啟用了CheckSum,當備份過程中發(fā)現了頁校驗和錯誤時,就會終止備份,而啟用了Continue_After_Error選項的話,在檢測到校驗和錯誤時,仍然繼續(xù)從而使得備份成功。
備份如果啟用了CheckSum選項,除去檢測每一頁的校驗和之外,還會在備份完成后,對整個備份計算校驗和并存儲于備份頭中。
此外,對于備份,我們還可以通過Restore Verifyonly with CheckSum來驗證備份,來保證備份的數據沒有被損壞。
DBCC CheckDB前面提到SQL Server發(fā)現錯誤的方法有兩種,分別為在讀取頁時和在備份時(本質上也是讀取頁)。但如果我們希望對于數據一致性的檢查更加的激進,那我們應該定期使用CheckDB來檢查數據的一致性,而不至于在生產時間數據被讀取時才能發(fā)現錯誤。
CheckDB命令會對整個數據庫做所有的一致性檢查。當檢查對象是Master數據庫時,CheckDB還會檢查ResourceDB。
CheckDB最簡單的用法如代碼清單2所示,在當前數據庫上下文中直接執(zhí)行CheckDB,將會檢查當前數據庫中所有的一切。
DBCCCHECKDB
代碼清單CheckDB最簡單的用法
CheckDB命令在企業(yè)版中會使用多線程來進行,會對整個數據庫進行一致性檢查,在該過程中,使用了內建數據庫快照的方式進行,因此不會造成阻塞,但CheckDB會消耗大量的CPU、內存和IO。因此CheckDB要選擇在維護窗口時間或是系統(tǒng)閑時進行。
默認情況下,CheckDB命令會將輸出所有的信息,但通常我們并不關心這些信息,而是只關心錯誤信息,因此實際中通常給DBCC指定不顯式信息的參數,如代碼清單3所示。
DBCCCHECKDBWITHNO_INFOMSGS;
代碼清單CheckDB通常搭配No_InfoMsgs參數
實際上,CheckDB是一套命令的匯總,CheckDB會依次檢查下述內容:
初次檢查系統(tǒng)表
分配單元檢查(DBCC CHECKALLOC)
完整檢查系統(tǒng)表
對所有表進行一致性邏輯檢查(DBCC CHECKTABLE)
元數據檢查(DBCC CHECKCATALOG)
SSB檢查
索引視圖、XML索引等檢查
首先,當發(fā)現系統(tǒng)表損壞時,只能通過備份進行恢復(這也是為什么備份除TempDB之外的系統(tǒng)表非常重要)。其次,在一個大數據庫中,做一次CheckDB時間會非常長,維護窗口時間或系統(tǒng)閑時的時間可能無法Cover這段時間,那么我們可以將CheckDB的任務分散到CHECKALLOC、DBCC CHECKTABLE、DBCC CHECKCATALOG這三個命令中。
更多關于CheckDB的詳細信息,請參閱:http://technet.microsoft.com/en-us/library/ms17606aspx。
數據庫損壞的修復數據庫損壞最行之有效的辦法就是存在冗余數據,使用冗余數據進行恢復。所謂的冗余數據包括熱備、冷備、和暖備。
使用鏡像或可用性組作為熱備,當檢測到錯誤時,可以自動進行頁修復(鏡像要求2008以上,可用性組是2012的功能)。鏡像當主體服務器遭遇824錯誤時,會向鏡像服務器發(fā)送請求,將損壞的頁由鏡像復制到主體解決該問題。對于可用性組,如果數據頁是在主副本上發(fā)現的,則主副本將會向所有輔助副本發(fā)送廣播,并由第一個響應的輔助副本的頁來修復頁錯誤,如果錯誤出現在只讀輔助副本,則會向主副本請求對應的頁來修復錯誤。在這里有一點值得注意的是,無論是哪一種高可用性技術,都不會將頁錯誤散播到冗余數據中,因為SQL Server中所有的高可用性技術都是基于日志,而不是數據頁。
其次是使用暖備或冷備來還原頁,我已經在代碼清單1中給出了詳細的代碼,這里就不細說了。
如果沒有合適的備份存在,如果損壞的數據頁是存在于非聚集索引上,那么你很幸運,只需要將索引禁用后重建即可。
如果存在基準的完整備份,并且日志鏈沒有斷裂(包括差異備份可以Cover日志缺失的部分),則可以通過備份尾端日之后還原數據庫來進行修復。
最后,如果基礎工作做的并不好,您可能就需要通過損失數據的方式來換回數據庫的一致性,我們可以通過DBCC CheckDB命令的REPAIR_ALLOW_DATA_LOSS來修復數據庫。使用該方法可能導致數據損失,也可能不會導致數據損失,但大部分情況都會通過刪除數據來修復一致性。使用REPAIR_ALLOW_DATA_LOSS需要將數據庫設置為單用戶模式,這意味著宕機時間。
無論是哪種情況修復數據庫,都要考慮是否滿足SLA,如果出現了問題之后,發(fā)現無論用哪種方式都無法滿足SLA的話,那只能檢討之前的準備工作并祈禱你不會因此丟了工作。
版權說明: 本文由用戶上傳,如有侵權請聯系刪除!
猜你喜歡:
- 2022-09-20 男人惡心是什么病的前兆(惡心是什么病的前兆)
- 2022-09-20 山東財經大學東方學院考研率怎么樣(山東財經大學考研率是多少)
- 2022-09-20 廣西最早的大學叫什么大學(在桂林設立的廣西最早的大學是哪所大學)
- 2022-09-20 小兒肺炎有5個常見癥狀嗎(小兒肺炎有5個常見癥狀)
- 2022-09-20 m是哪個服裝品牌的標志(標志為M的衣服是什么牌子的)
- 2022-09-20 什么叫正比例什么叫反比例舉例說明(什么叫反比例,舉個例子說明,)
- 2022-09-20 一包煙要多少根煙絲(一包煙要多少根)
- 2022-09-20 男人吃櫻桃對身體有什么好處(男人吃櫻桃有什么好處)
最新文章:
- 2023-07-02 怎樣挑選新鮮的豬肝?(怎么挑選新鮮豬肝 挑選新鮮豬肝的小技巧)
- 2023-07-02 木地板都有哪些種類(木地板的種類有哪些)
- 2023-07-02 白蠟木家具的優(yōu)缺點(松木家具的優(yōu)缺點)
- 2023-07-02 怎么清洗窗簾布上的污垢(怎么清洗窗簾)
- 2023-07-02 世界上最可愛的小倉鼠的樣子(可愛小倉鼠的種類)
- 2023-07-02 小貓拉不出來屎怎么辦(小貓拉不出屎怎么辦)
- 2023-07-02 新飛小冰箱耗電量一天多少度(小冰箱耗電量一天多少度)
- 2023-07-02 公司注銷工業(yè)房產怎么辦手續(xù)(公司注銷工業(yè)房產怎么辦)
- 2023-07-02 鳳凰層到底好還是不好(鳳凰層是哪一層)
- 2023-07-02 馬桶寬度空間留多少(馬桶兩邊的空間大小是多少)
- 2023-07-02 如何訓練貓咪小便(如何訓練貓大小便)
- 2023-07-02 衛(wèi)生間吊頂防潮層做法圖集(衛(wèi)生間吊頂方法是什么)
- 2023-07-02 狗狗為什么總是流口水怎么辦(狗狗為什么愛流口水)
- 2023-07-02 臥室窗戶漏水由誰負責維修(臥室窗戶漏風怎么辦)
- 2023-07-02 世界名貓大全(世界名貓你知道幾種)
- 2023-07-02 applewatchseries7和6對比(apple watch series 7和6的區(qū)別)