dbnetlib sqlserver不存在或拒绝访问_SQL Server数据库损坏和修复
常見錯誤解讀
823錯誤
錯誤信息是:“在文件'%ls'中、偏移量為%#016I64x的位置執行%S_MSG期間,操作系統已經向SQL Server返回了錯誤%ls。”
“The operating systemreturned error %ls to SQL Server during a %S_MSGat offset %#016I64x in file '%ls'.”
例如:
Msg 823, Level 24, State 3, Line 1
The operating system returned error 5(Access is denied.) to SQLServer during a write at offset 0x0000000000e000 in file 'FilePathFileName'.
823錯誤代表SQL Server在向操作系統申請某個頁面讀寫時候遇到Windows讀取或寫入請求失敗,Windows返回的錯誤代碼和相應的文本會插入消息中。對于讀取操作,SQL Server在報出823錯誤之前已經重試讀取請求4次。
從錯誤產生的機制可以看出,823錯誤是發出一個頁面讀寫請求時發生的,和讀寫的內容沒有關系,所以823錯誤和SQL Server本身無關。通常是物理文件損壞導致此錯誤,但也可能是設備驅動程序導致的。如果某個數據文件上反復出現823錯誤,要不就是硬件設備出了問題,要不就是數據文件已經發生了非常嚴重的損壞。這個錯誤基本上意味著數據頁里的有效數據已經丟失,一般DBCC CHECKDB很難修復。
824錯誤
錯誤信息是:”SQL Server檢測到基于一致性的邏輯I/O錯誤%ls。該文件’%ls‘中、偏移量為 %#016I64x的位置對數據庫ID%d中的頁%S_PGID執行%S_MSG期間,發生了該錯誤。”
“SQL Server detecteda logical consistency-based I/O error: %ls. It occurred during a %S_MSG of page %S_PGIDin database ID %d at offset %#016I64x in file '%ls'.”
例如:
SQL Server detected a logical consistency-based I/O error: tornpage (expected signature: 0x0; actual signature: 0x4e0372a8). It occurredduring a read of page (1:0) in database ID 13 at offset 0000000000000000 infile 'S:Microsoft SQL ServerMSSQL.1MSSQLDatawww71_global_Data.mdf'.
此錯誤表明Windows報告已從磁盤成功讀取頁面,但SQL Server檢測到頁面中存在邏輯錯誤。
常見的錯誤類型有以下幾種:
1、CheckSum
SQL Server可以在寫入每個頁面時,根據頁面力度數據算出一個校驗值,一同存儲到頁面里去。當下次讀取頁面的時候,再根據讀到的頁面數據,算出一個新的校驗值。如果寫入和讀出的數據一樣,那么兩個校驗值一定是相等的,而如果兩個校驗值不相等,意味著上次SQL Server寫入的數據和這次讀出來的內容一定不同,現在讀出來的數據有問題。通過這種方法,SQL Server能過發生數據頁面損壞。
2、Torn Page
殘缺頁面(Torn Page)保護其實是一種對電源故障導致的頁面損壞進行檢測的方法。例如,意外電源故障可能導致一個頁面只有一部分被寫入了磁盤。在使用殘缺頁面保護時,頁面的每個512字節扇區末尾會放置一個2位簽名(在將原來的2位復制到頁頭之后)。每次進行寫操作時,這個簽名在二進制數01和10之間交替,這樣始終可以確定是否只有部分扇區寫到磁盤。如果稍后讀取頁面時發現某個位置的狀態不正確,則說明該頁面沒有被正確的寫入,因此檢測到問題頁面稱為殘缺頁面。相對于Checksum,殘缺頁面檢測使用的資源最少,但是它的算法太簡單,無法檢測到磁盤硬件故障導致的所有錯誤。
3、Short Transfer
讀到的數據長度比預期的少。例如,一個讀取要求預期可以讀到8KB的數據,可是實際只返回了4KB。這也意味著當前讀到的頁面有損壞。
4、Bad Page Id
在讀到頁面后,SQL Server會比較頁面開頭存儲的頁面編號和自己請求的目標編號。如果發現自己想要讀取的頁面是第200頁,而讀到的內容里顯示它是第100頁,SQL Server會觸發824錯誤。這種錯誤經常會因為I/O的系統沒有正確的處理SQL Server請求,傳給SQL Server一個錯誤的頁面,甚至是一個空頁面。
5、Restore Pending
在SQL Server的企業版里,用戶可以要求在做還原的時候跳過一些損壞的頁面(Continue After Error)。這些跳過的頁面被標識成“Restore Pending”。如果有的用戶想去訪問它,就會遇到824錯誤。
6、Stale Read
一些硬件系統經常發生漏寫的現象(SQL Server要求將某個頁面寫入硬盤文件,I/O子系統報告寫入已經完成,可是SQL Server下次讀取的時候,讀到的還是寫入前的內容)。由于讀到的老版本頁面本身沒有什么問題,Checksum和Torn Page算法都不能檢查到錯誤。對這一類問題,SQL Server也有對策。在打開SQL Server啟動參數開關-T818以后,SQL Server會在內存里維護一個哈希表,記錄所有做過寫入動作頁面的最新LSN(Log Sequence Number)值。在下次讀出頁面的時候,會去比較這兩個值是否相等。由于LSN是個自動增長的唯一值,每個發生新修改的頁面,LSN的值會比原來的要大。如果讀到的LSN與內存中存放的不一致,說明上次的寫入請求沒有真正完成。這時824錯誤也會觸發。
824雖然是一個“邏輯錯誤”、是SQL Server主動發現的數據損壞,但是損壞的來源大都不是SQL Server自己。這里的錯誤,主要是由于預期的寫入沒有完全完成導致的。824錯誤的原因,基本上還是在I/O子系統。由于SQL Server的讀寫請求是發給Windows,再由Windows發給底層的磁盤系統,所以問題有可能發生在Windows以下的每一層,例如磁盤驅動器存在故障、磁盤估計存在問題、設備驅動程序不正確等。可以負責任的說,SQL Server自己是不會導致824錯誤的。
由于824錯誤是發生在頁面這一級的邏輯錯誤,很多時候DBCC CHECKDB能夠修復。這種修復也僅僅是邏輯上的,頁面里面存儲的數據在824錯誤發生之前就已經丟失,SQL Server無法將它們修復回來,所以824錯誤基本也意味著部分數據丟失。
605錯誤
錯誤信息是:“嘗試在數據庫%d中提取邏輯頁%S_PGID失敗。該邏輯頁屬于分配單元%I64d,而非%I64d。”
“Attempt to fetchlogical page %S_PGIDin database %d failed. It belongs to allocation unit %I64d not to %I64d.”
例如:
Attempt to fetch logical page (1:584) in database 2 failed. Itbelongs to allocation unit 445237904015360 not to 72057594060079104.
605也是一個非常有名的數據庫損壞錯誤。此錯誤通常表示指定數據庫中的頁面或分配已損壞。SQL Server會在根據頁鏈或使用索引分配映射(IAM)讀取屬于表的頁面時,檢測到此損壞。分配給表的所有頁面必須屬于與該表相關聯的分配單元之一。如果頁眉中包含的分配單元ID不匹配與表相關聯的分配單元ID,將引發此異常。錯誤消息中列出的第一個分配單元ID是頁眉中顯示的ID,而第二個分配單元值則是與表相關聯的ID。
嚴重級別為21表示可能存在數據損壞。造成的原因包括損壞的頁鏈、損壞的IAM或該對象的sys.objects目錄視圖中存在無效條目。這些錯誤通常由硬件或磁盤設備驅動程序故障而引起的。
嚴重級別為12表示可能存在暫時性錯誤,即在緩存中出現錯誤,但不表示對磁盤上的數據造成破壞。暫時性的605錯誤可由以下條件引發:
- 操作系統過早的通知SQL Server已完成某個I/O操作;盡管不存在實際的數據損
壞,但現實錯誤消息。
- 運行帶有優化器提示NOLOCK的查詢,或將事務隔離級別設置為READ
UNCOMMITTED。當使用NOLOCK或READ UNCOMMITTED的查詢嘗試讀取
被其他用戶移動或更改的數據時,將發生605錯誤。如果驗證是否為暫時性的
605錯誤,可以稍后重新運行該查詢。
通常,如果在數據訪問期間發生該錯誤,但后續的DBCC CHECKDB操作在沒有出錯的情況下完成,則605錯誤可能是暫時的。
由于605錯誤意味著一些頁面分配出了問題,所以也是一個非常嚴重的數據庫損壞。一般用DBCC CHECKDB很難修復。
其他錯誤
在SQL Server內部,除了文件頁面分配和每個頁面內部格式以外,還有一些其他的約束規則。下面是一些常見的錯誤例子。
PFS頁面投有損壞:
Msg 8946, Level 16, State 12, Line 1Table error: Allocation page(1:13280496) has
invalid PFS_PAGEpage header values.Type is 0. Check type, alloc unit ID and page
ID on the page.
系統表上的聚集索引頁面上有損壞:
Server: Msg 8966, Level 16, State 1, Line 1 Could not read andlatch page (1:18645)
with latch type SH. sysindexes failed.
Msg 7985, Level 16, State 2, Server SUNART, Line 1System tablepre-checks: Object
ID 4. Could not read and latch page (1:51) withlatch type SH. Checkstatement
terminated due to unrepairable error.
某個字段的值不符合字段數據類型定義:
Msg 2570, Level 16, State 3, Line 1Page (1:152), slot 0 in objectID 2073058421,
index ID 0, partition ID 72057594038321152, alloc unit ID72057594042318848 (type
"In-row data"). Column "c1" value is out ofrange for data type "datetime". Update
column to a legal value.
元數據有損壞:
Msg 3854, Level 16, State 1, Line 2Attribute (referenced_major_id=2089058478)of
row (class=0,object_id=2105058535,column_id=0,referenced_major_id=2089058478,referenced_
minor_id=0)in sys.sql_dependencies has amatching row (object_id=2089058478)in
sys.objects (type=SN) that is invalid.
遇到這些錯誤,管理員需要用DBCC CHECKDB命令來檢查和修復。有些錯誤是可以不丟數據就修復的,有些是要丟數據才能修復物理層面錯誤的,有些是即使丟數據也沒辦法修復的。
SQL Server數據庫損壞修復:DBCC CHECKDB
DBCC CHECKDB指令可以完成兩項任務:
所以哪怕是一個正常運行的數據庫,也建議定期運行這句指令,以確保沒有損壞發生。對于已經發生訪問錯誤的數據庫,應該第一時間運行這句指令,了解損壞的范圍和程度。
DBCC CHECKDB在做什么
DBCC CHECKDB通過依次執行下列操作檢查指定數據庫中所有對象的邏輯和物理完整性:
- 檢查一些關鍵的系統表。
- 對數據庫運行DBCC CHECKALLOC。
- 對數據庫中的每個表和視圖運行DBCC CHECKTABLE。
- 對數據庫運行DBCC CHECKCATALOG。
- 驗證數據庫中每個索引視圖的內容。
- 驗證數據庫中的Service Broker數據。
這意味著運行了DBCC CHECKDB,就不必再單獨運行DBCC CHECKALLOC、DBCC CHECKTABLE或DBCC CHECKCATALOG命令。也意味著單獨運行DBCC CHECKALLOC、DBCC CHECKTABLE和DBCC CHECKCATALOG命令,雖然不能完全完成DBCC CHECKDB的所有功能,但是至少完成了大部分功能。
1、檢查一些關鍵的系統表
在檢查數據庫之前,SQL Server需要了解這個數據庫里到底存放了什么樣的數據,也就是所謂數據庫的“元數據”(Metadata)。沒有這些信息,SQL Server無法知道自己將要去訪問什么樣的表格,也就沒辦法知道自己應該怎么解釋將要讀到的記錄。
關鍵系統表有:
sysallocunits。
syshobts。
syshobtcolumnes。
sysrowsets。
sysrowsetcolumns。
對于普通用戶訪問,這些表都是不可見的,只有在DAC模式下的連接才能看到它們。它們的結果對普通用戶也是透明的。
這里的每一張系統表都有一個聚集索引。SQL Server會像做CHECKTABLE一樣,對這些系統表做一遍檢查,確保這些表格里的每一頁及頁面里的每一條數據都可以正確的讀出來。如果中間發現問題了,例如,發現某個頁面不能被正常訪問,SQL Server會報錯。例如:
Server: Msg 8966, Level 16, State 1, Line 1
Could not read and latch page (1:33245) with latch type SH.Sysobjects failed.
對于小的數據庫,這些存放元數據庫的系統表不會占用太多的頁面。如果發生硬件問題,損壞的概率比較小。對于一些有成千上萬對象的數據庫,這些元數據系統表本身可能使用了很多頁面,發生損壞的概率也隨之增大。由于這些系統表正確讀取一切數據的根本,所以如果任意一張系統表上發生了損壞,DBCC CHECKDB會直接失敗,數據庫也無法做任何修復。此時修復數據庫的唯一方法是恢復數據庫備份。
總結
以上是生活随笔為你收集整理的dbnetlib sqlserver不存在或拒绝访问_SQL Server数据库损坏和修复的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: phpcms的phpcms_auth导致
- 下一篇: koa2 mysql增删改查_使用nod