有關資料庫一致性的問題

by adonisy 4. 八月 2020 15:42

作 者:楊先民
審 稿:張智凱

本期將要探討的是一個很不常見的主題,稱為資料庫的一致性,這個問題偶爾會發生,而且時常的困擾著我們,希望大家在看完本期之後,能夠

更加了解該如何去面對以及解決。

資料庫涉及很多IO。當您有大量的IO時,就必然會遭受損壞的風險。防止資料庫損壞的主要防禦方法是對資料庫進行定期備份,並定期測試是否可以還原這些備份。

但是,您需要注意資料庫是否損壞,SQL Server提供了一些工具,可用於檢查資料庫的一致性以及在沒有備份的情況下解決一致性問題。

本期將介紹檢查和修復一致性問題的選項。

一致性的錯誤

一致性錯誤可能會在用戶資料庫或系統資料庫中發生,從而使得資料表、資料庫甚至整台 SQL Server處於不能連線的狀態。

一致性錯誤的發生可能有多種原因,包括硬體故障和資料庫引擎問題。以下各段將討論了可能發生的錯誤類型,如何檢測這些錯誤以及如果系統資料庫損壞了該怎麼辦。

了解一致性的錯誤

可能會發生不同的資料庫一致性錯誤。這些會導致查詢失敗或 session斷開連接,以及將訊息寫入SQL Server 錯誤日誌中。以下的小段將會詳細介紹最常見的錯誤。

605錯誤

605錯誤可能指向兩個問題之一,具體取決於錯誤的嚴重程度。如果嚴重性為12級,則資料表是 dirty read。dirty read是使用“read uncommitted”級別或NOLOCK查詢提示時發生的事務異常。

當事務讀取資料庫中不存在的行(由於另一個事項被取消)時,就會發生這種情況。事務異常將在之後討論。若要解決此問題,請重新運行查詢直到成功為止,或者重寫查詢

以避免使用“read uncommitted”或NOLOCK查詢提示。

605錯誤可能表示一個更嚴重的問題,但是通常它代表硬體的故障。如果嚴重級別為21,則該頁面可能已損壞,或者可能從操作系統提供了錯誤的頁面。如果是這種情況,則您需要從備份中還原或使用DBCC CHECKDB來解決此問題。 (之後會稍後提到DBCC CHECKDB。)

除此之外,你應該讓Windows管理員和儲存裝置的團隊檢查可能的硬體或是磁碟等級的問題。

823錯誤

當SQL Server嘗試執行IO操作並且它用於執行此操作的 Windows API向資料庫引擎返回錯誤時,將發生823錯誤。 823錯誤幾乎總是與硬體或驅動程序問題相關。

如果發生823錯誤,則應使用DBCC CHECKDB來檢查其餘資料庫以及駐留在同一卷上的任何其他資料庫的一致性。您應該與您的儲存團隊聯繫,以解決儲存問題。您的Windows管理員還應該檢查Windows事件日誌中是否有相關的錯誤消息。最後,您應該從備份中還原資料庫,或者使用DBCC CHECKDB來“解決”該問題。

824錯誤

如果對Windows API的調用成功,但是返回的資料存在邏輯一致性問題,則將生成824錯誤。就像823錯誤一樣,824錯誤通常表示儲存子系統存在問題。如果生成了824錯誤,則應遵循與生成823錯誤時相同的操作過程。

5180錯誤

發現無效的文件ID時,發生5180錯誤。文件ID儲存在頁面指針以及每個文件開頭的系統頁面中。此錯誤通常是由頁面內的指針損壞引起的,但也可能表示資料庫引擎存在問題。

如果遇到此錯誤,則應從備份中還原或運行DBCC CHECKDB來修復該錯誤。

7105錯誤

當資料表中的行引用了不存在的LOB(大物件塊)結構時,會發生7105錯誤。這可能是由於以與605嚴重性12錯誤相同的方式進行的 dirty read而發生的,也可能是由於頁面損壞導致的。

損壞可以在指向LOB結構的資料分頁中,也可以在LOB結構本身的頁中。如果遇到7105錯誤,則應運行DBCC CHECKDB來檢查錯誤。如果找不到任何內容,則可能是錯誤讀取導致的錯誤。

但是,如果發現錯誤,請從備份還原資料庫或使用DBCC CHECKDB修復問題。

檢測一致性錯誤

SQL Server提供了一些機制來驗證頁面從磁碟讀取和寫入磁碟時的完整性。它還提供了損壞頁面的日誌,可幫助您確定已發生錯誤的類型,發生錯誤的次數以及已損壞頁面的當前狀態。

這些功能將會在之後的適當時機介紹。

Page Verify Option

一個稱為頁面驗證的資料庫級選項確定 SQL Server如何檢查IO子系統在將頁面讀寫到磁盤時導致的頁面損壞。可以將其配置為CHECKSUM,這是默認選項TORN_PAGE_DETECTION或NONE。

推薦的頁面驗證設置為CHECKSUM。選擇此選項後,每次寫入頁面時,都會針對整個頁面創建一個CHECKSUM值並將其保存在頁面標題中。 CHECKSUM值是一個散列總和,

該散列總和是運行散列函數所依據的值的確定性和唯一性。當將頁面讀入緩衝區高速記憶體並將其與原始值進行比較時,將重新計算該值。如果指定了TORN_PAGE_DETECTION,

則每當將頁面寫入磁盤時,頁面的每個512字節扇區的前2個字節都會寫入頁面的標題。隨後將頁面讀入記憶體時,將檢查這些值以確保它們相同。這裡的缺陷是顯而易見的。

頁面極有可能被破壞,並且這種破壞不會引起注意,因為它不在檢查的字節之內。 TORN_PAGE_DETECTION是SQL Server的不推薦使用的功能,這意味著它將在以後的版本中不可用。

您應該避免使用它。如果“頁面驗證”設置為NONE,則SQL Server不會執行任何頁面驗證。這不是一個好習慣。

如果所有資料庫都已在 SQL Server 2019實例中創建,則默認情況下它們都配置為使用CHECKSUM。但是,如果您已經從SQL Server的早期版本中搬移了資料庫,則可以將它們配置為使用TORN_PAGE_DETECTION。您可以使用下面的指令進行檢查:

SELECT name ,page_verify_option_desc FROM sys.databases ;

如果顯示的結果為 None的話,則可以進行修改(如下圖):

 

至於要如何的修正資料庫的一致性問,我們之後會再討論。

Tags:

SQL Server資料庫 | 楊先民Adonis Young

不允許評論

NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List