簡介
在一個理想的世界中,不會存在任何數據庫的損壞,就像我們不會將一些嚴重意外情況列入我們生活中的日常一樣, 而一旦這類事情發生,一定會對我們的生活造成非常顯著的影響,在SQL Server中也同樣如此,或許幾年內您沒有遇見 過數據庫中出現這類情況,而一旦遇見這類情況,往往伴隨著數據的丟失,宕機,嚴重甚至您本身的職業生涯也會受到 影響。因此對於這類情況,我們需要了解數據庫損壞方面的知識,以便我們能夠事前准備,事後能夠處理。本篇文章會 對數據庫損壞的原因、現象、事前和事後的一些處理方法以及簡單的修復方法進行探討。
數據庫為什麼會損壞?
在了解數據庫損壞之前,首先我們要了解SQL Server是如何將數據保存到數據文件(MDF、NDF等)。無論更新還是插 入數據,數據都需要首先在內存中的Buffer Pool駐留,然後通過CheckPoint和Lazy Writer等過程將內存中的數據持久 化到磁盤。在這個過程中,數據髒頁由內存寫入持久化的IO子系統,在此期間,按照IO子系統的不同,數據可能經過這 幾層:
Windows(寫數據一定調用的是WINDOWS API)
Windows底層的中間層(殺毒軟件,磁盤加密系統)
網卡、路由器、交換機、光釬、網線等(如果IO子系統不是直連的話)
SAN控制器(如果使用了SAN)
RAID控制器(IO子系統做了RAID)
磁盤或SSD等持久化存儲器
因此,數據頁被寫入持久化存儲期間,可能經過上述列表中的幾項。在經歷上述過程中,硬件環境會受到很多方面的 影響,比如說電壓是否穩定、斷電、溫度過高或過低、潮濕程度等,而軟件方面,由於軟件都是人寫的,因此就可能存 在BUG,這些都可能導致數據頁在傳輸過程中出現錯誤。
此外,影響磁盤的因素也包括電壓是否穩定、灰塵等因素,這些也有可能引起磁盤壞道或整體損壞。
上面提到的所有因素都可以被歸結為IO子系統。因此,造成數據損壞的情況絕大部分是由IO子系統引起的,還有非常 非常小的概率內存芯片也會導致數據頁損壞,但這部分情況微乎其微,因此不在本文的討論之列。
上面提到的這些導致數據損壞的原因都屬於天災,還有一些人禍。比如說通過編輯器等手動編輯數據文件、數據庫中 還有需要Redo和Undo的事務時(也就是沒有Clean Shutdown)刪除了日志文件(通常會導致數據庫質疑)。
發現數據庫損壞
在我們知道可能造成數據庫的損壞原因之後,接下來我們來看SQL Server是如何監測數據庫頁損壞的。
在SQL Server的數據庫級別,可以設置頁保護類型,一共有三個選項:None,CheckSum,Torn_Page_Detection,如 圖1所示:
圖1.頁保護的三種選項