dbnetlib sqlserver不存在或拒绝访问_SQL Server数据库损坏和修复
常見錯(cuò)誤解讀
823錯(cuò)誤
錯(cuò)誤信息是:“在文件'%ls'中、偏移量為%#016I64x的位置執(zhí)行%S_MSG期間,操作系統(tǒng)已經(jīng)向SQL Server返回了錯(cuò)誤%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錯(cuò)誤代表SQL Server在向操作系統(tǒng)申請(qǐng)某個(gè)頁面讀寫時(shí)候遇到Windows讀取或?qū)懭胝?qǐng)求失敗,Windows返回的錯(cuò)誤代碼和相應(yīng)的文本會(huì)插入消息中。對(duì)于讀取操作,SQL Server在報(bào)出823錯(cuò)誤之前已經(jīng)重試讀取請(qǐng)求4次。
從錯(cuò)誤產(chǎn)生的機(jī)制可以看出,823錯(cuò)誤是發(fā)出一個(gè)頁面讀寫請(qǐng)求時(shí)發(fā)生的,和讀寫的內(nèi)容沒有關(guān)系,所以823錯(cuò)誤和SQL Server本身無關(guān)。通常是物理文件損壞導(dǎo)致此錯(cuò)誤,但也可能是設(shè)備驅(qū)動(dòng)程序?qū)е碌摹H绻硞€(gè)數(shù)據(jù)文件上反復(fù)出現(xiàn)823錯(cuò)誤,要不就是硬件設(shè)備出了問題,要不就是數(shù)據(jù)文件已經(jīng)發(fā)生了非常嚴(yán)重的損壞。這個(gè)錯(cuò)誤基本上意味著數(shù)據(jù)頁里的有效數(shù)據(jù)已經(jīng)丟失,一般DBCC CHECKDB很難修復(fù)。
824錯(cuò)誤
錯(cuò)誤信息是:”SQL Server檢測(cè)到基于一致性的邏輯I/O錯(cuò)誤%ls。該文件’%ls‘中、偏移量為 %#016I64x的位置對(duì)數(shù)據(jù)庫(kù)ID%d中的頁%S_PGID執(zhí)行%S_MSG期間,發(fā)生了該錯(cuò)誤。”
“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'.
此錯(cuò)誤表明Windows報(bào)告已從磁盤成功讀取頁面,但SQL Server檢測(cè)到頁面中存在邏輯錯(cuò)誤。
常見的錯(cuò)誤類型有以下幾種:
1、CheckSum
SQL Server可以在寫入每個(gè)頁面時(shí),根據(jù)頁面力度數(shù)據(jù)算出一個(gè)校驗(yàn)值,一同存儲(chǔ)到頁面里去。當(dāng)下次讀取頁面的時(shí)候,再根據(jù)讀到的頁面數(shù)據(jù),算出一個(gè)新的校驗(yàn)值。如果寫入和讀出的數(shù)據(jù)一樣,那么兩個(gè)校驗(yàn)值一定是相等的,而如果兩個(gè)校驗(yàn)值不相等,意味著上次SQL Server寫入的數(shù)據(jù)和這次讀出來的內(nèi)容一定不同,現(xiàn)在讀出來的數(shù)據(jù)有問題。通過這種方法,SQL Server能過發(fā)生數(shù)據(jù)頁面損壞。
2、Torn Page
殘缺頁面(Torn Page)保護(hù)其實(shí)是一種對(duì)電源故障導(dǎo)致的頁面損壞進(jìn)行檢測(cè)的方法。例如,意外電源故障可能導(dǎo)致一個(gè)頁面只有一部分被寫入了磁盤。在使用殘缺頁面保護(hù)時(shí),頁面的每個(gè)512字節(jié)扇區(qū)末尾會(huì)放置一個(gè)2位簽名(在將原來的2位復(fù)制到頁頭之后)。每次進(jìn)行寫操作時(shí),這個(gè)簽名在二進(jìn)制數(shù)01和10之間交替,這樣始終可以確定是否只有部分扇區(qū)寫到磁盤。如果稍后讀取頁面時(shí)發(fā)現(xiàn)某個(gè)位置的狀態(tài)不正確,則說明該頁面沒有被正確的寫入,因此檢測(cè)到問題頁面稱為殘缺頁面。相對(duì)于Checksum,殘缺頁面檢測(cè)使用的資源最少,但是它的算法太簡(jiǎn)單,無法檢測(cè)到磁盤硬件故障導(dǎo)致的所有錯(cuò)誤。
3、Short Transfer
讀到的數(shù)據(jù)長(zhǎng)度比預(yù)期的少。例如,一個(gè)讀取要求預(yù)期可以讀到8KB的數(shù)據(jù),可是實(shí)際只返回了4KB。這也意味著當(dāng)前讀到的頁面有損壞。
4、Bad Page Id
在讀到頁面后,SQL Server會(huì)比較頁面開頭存儲(chǔ)的頁面編號(hào)和自己請(qǐng)求的目標(biāo)編號(hào)。如果發(fā)現(xiàn)自己想要讀取的頁面是第200頁,而讀到的內(nèi)容里顯示它是第100頁,SQL Server會(huì)觸發(fā)824錯(cuò)誤。這種錯(cuò)誤經(jīng)常會(huì)因?yàn)镮/O的系統(tǒng)沒有正確的處理SQL Server請(qǐng)求,傳給SQL Server一個(gè)錯(cuò)誤的頁面,甚至是一個(gè)空頁面。
5、Restore Pending
在SQL Server的企業(yè)版里,用戶可以要求在做還原的時(shí)候跳過一些損壞的頁面(Continue After Error)。這些跳過的頁面被標(biāo)識(shí)成“Restore Pending”。如果有的用戶想去訪問它,就會(huì)遇到824錯(cuò)誤。
6、Stale Read
一些硬件系統(tǒng)經(jīng)常發(fā)生漏寫的現(xiàn)象(SQL Server要求將某個(gè)頁面寫入硬盤文件,I/O子系統(tǒng)報(bào)告寫入已經(jīng)完成,可是SQL Server下次讀取的時(shí)候,讀到的還是寫入前的內(nèi)容)。由于讀到的老版本頁面本身沒有什么問題,Checksum和Torn Page算法都不能檢查到錯(cuò)誤。對(duì)這一類問題,SQL Server也有對(duì)策。在打開SQL Server啟動(dòng)參數(shù)開關(guān)-T818以后,SQL Server會(huì)在內(nèi)存里維護(hù)一個(gè)哈希表,記錄所有做過寫入動(dòng)作頁面的最新LSN(Log Sequence Number)值。在下次讀出頁面的時(shí)候,會(huì)去比較這兩個(gè)值是否相等。由于LSN是個(gè)自動(dòng)增長(zhǎng)的唯一值,每個(gè)發(fā)生新修改的頁面,LSN的值會(huì)比原來的要大。如果讀到的LSN與內(nèi)存中存放的不一致,說明上次的寫入請(qǐng)求沒有真正完成。這時(shí)824錯(cuò)誤也會(huì)觸發(fā)。
824雖然是一個(gè)“邏輯錯(cuò)誤”、是SQL Server主動(dòng)發(fā)現(xiàn)的數(shù)據(jù)損壞,但是損壞的來源大都不是SQL Server自己。這里的錯(cuò)誤,主要是由于預(yù)期的寫入沒有完全完成導(dǎo)致的。824錯(cuò)誤的原因,基本上還是在I/O子系統(tǒng)。由于SQL Server的讀寫請(qǐng)求是發(fā)給Windows,再由Windows發(fā)給底層的磁盤系統(tǒng),所以問題有可能發(fā)生在Windows以下的每一層,例如磁盤驅(qū)動(dòng)器存在故障、磁盤估計(jì)存在問題、設(shè)備驅(qū)動(dòng)程序不正確等。可以負(fù)責(zé)任的說,SQL Server自己是不會(huì)導(dǎo)致824錯(cuò)誤的。
由于824錯(cuò)誤是發(fā)生在頁面這一級(jí)的邏輯錯(cuò)誤,很多時(shí)候DBCC CHECKDB能夠修復(fù)。這種修復(fù)也僅僅是邏輯上的,頁面里面存儲(chǔ)的數(shù)據(jù)在824錯(cuò)誤發(fā)生之前就已經(jīng)丟失,SQL Server無法將它們修復(fù)回來,所以824錯(cuò)誤基本也意味著部分?jǐn)?shù)據(jù)丟失。
605錯(cuò)誤
錯(cuò)誤信息是:“嘗試在數(shù)據(jù)庫(kù)%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也是一個(gè)非常有名的數(shù)據(jù)庫(kù)損壞錯(cuò)誤。此錯(cuò)誤通常表示指定數(shù)據(jù)庫(kù)中的頁面或分配已損壞。SQL Server會(huì)在根據(jù)頁鏈或使用索引分配映射(IAM)讀取屬于表的頁面時(shí),檢測(cè)到此損壞。分配給表的所有頁面必須屬于與該表相關(guān)聯(lián)的分配單元之一。如果頁眉中包含的分配單元ID不匹配與表相關(guān)聯(lián)的分配單元ID,將引發(fā)此異常。錯(cuò)誤消息中列出的第一個(gè)分配單元ID是頁眉中顯示的ID,而第二個(gè)分配單元值則是與表相關(guān)聯(lián)的ID。
嚴(yán)重級(jí)別為21表示可能存在數(shù)據(jù)損壞。造成的原因包括損壞的頁鏈、損壞的IAM或該對(duì)象的sys.objects目錄視圖中存在無效條目。這些錯(cuò)誤通常由硬件或磁盤設(shè)備驅(qū)動(dòng)程序故障而引起的。
嚴(yán)重級(jí)別為12表示可能存在暫時(shí)性錯(cuò)誤,即在緩存中出現(xiàn)錯(cuò)誤,但不表示對(duì)磁盤上的數(shù)據(jù)造成破壞。暫時(shí)性的605錯(cuò)誤可由以下條件引發(fā):
- 操作系統(tǒng)過早的通知SQL Server已完成某個(gè)I/O操作;盡管不存在實(shí)際的數(shù)據(jù)損
壞,但現(xiàn)實(shí)錯(cuò)誤消息。
- 運(yùn)行帶有優(yōu)化器提示NOLOCK的查詢,或?qū)⑹聞?wù)隔離級(jí)別設(shè)置為READ
UNCOMMITTED。當(dāng)使用NOLOCK或READ UNCOMMITTED的查詢嘗試讀取
被其他用戶移動(dòng)或更改的數(shù)據(jù)時(shí),將發(fā)生605錯(cuò)誤。如果驗(yàn)證是否為暫時(shí)性的
605錯(cuò)誤,可以稍后重新運(yùn)行該查詢。
通常,如果在數(shù)據(jù)訪問期間發(fā)生該錯(cuò)誤,但后續(xù)的DBCC CHECKDB操作在沒有出錯(cuò)的情況下完成,則605錯(cuò)誤可能是暫時(shí)的。
由于605錯(cuò)誤意味著一些頁面分配出了問題,所以也是一個(gè)非常嚴(yán)重的數(shù)據(jù)庫(kù)損壞。一般用DBCC CHECKDB很難修復(fù)。
其他錯(cuò)誤
在SQL Server內(nèi)部,除了文件頁面分配和每個(gè)頁面內(nèi)部格式以外,還有一些其他的約束規(guī)則。下面是一些常見的錯(cuò)誤例子。
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.
系統(tǒng)表上的聚集索引頁面上有損壞:
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.
某個(gè)字段的值不符合字段數(shù)據(jù)類型定義:
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.
元數(shù)據(jù)有損壞:
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.
遇到這些錯(cuò)誤,管理員需要用DBCC CHECKDB命令來檢查和修復(fù)。有些錯(cuò)誤是可以不丟數(shù)據(jù)就修復(fù)的,有些是要丟數(shù)據(jù)才能修復(fù)物理層面錯(cuò)誤的,有些是即使丟數(shù)據(jù)也沒辦法修復(fù)的。
SQL Server數(shù)據(jù)庫(kù)損壞修復(fù):DBCC CHECKDB
DBCC CHECKDB指令可以完成兩項(xiàng)任務(wù):
所以哪怕是一個(gè)正常運(yùn)行的數(shù)據(jù)庫(kù),也建議定期運(yùn)行這句指令,以確保沒有損壞發(fā)生。對(duì)于已經(jīng)發(fā)生訪問錯(cuò)誤的數(shù)據(jù)庫(kù),應(yīng)該第一時(shí)間運(yùn)行這句指令,了解損壞的范圍和程度。
DBCC CHECKDB在做什么
DBCC CHECKDB通過依次執(zhí)行下列操作檢查指定數(shù)據(jù)庫(kù)中所有對(duì)象的邏輯和物理完整性:
- 檢查一些關(guān)鍵的系統(tǒng)表。
- 對(duì)數(shù)據(jù)庫(kù)運(yùn)行DBCC CHECKALLOC。
- 對(duì)數(shù)據(jù)庫(kù)中的每個(gè)表和視圖運(yùn)行DBCC CHECKTABLE。
- 對(duì)數(shù)據(jù)庫(kù)運(yùn)行DBCC CHECKCATALOG。
- 驗(yàn)證數(shù)據(jù)庫(kù)中每個(gè)索引視圖的內(nèi)容。
- 驗(yàn)證數(shù)據(jù)庫(kù)中的Service Broker數(shù)據(jù)。
這意味著運(yùn)行了DBCC CHECKDB,就不必再單獨(dú)運(yùn)行DBCC CHECKALLOC、DBCC CHECKTABLE或DBCC CHECKCATALOG命令。也意味著單獨(dú)運(yùn)行DBCC CHECKALLOC、DBCC CHECKTABLE和DBCC CHECKCATALOG命令,雖然不能完全完成DBCC CHECKDB的所有功能,但是至少完成了大部分功能。
1、檢查一些關(guān)鍵的系統(tǒng)表
在檢查數(shù)據(jù)庫(kù)之前,SQL Server需要了解這個(gè)數(shù)據(jù)庫(kù)里到底存放了什么樣的數(shù)據(jù),也就是所謂數(shù)據(jù)庫(kù)的“元數(shù)據(jù)”(Metadata)。沒有這些信息,SQL Server無法知道自己將要去訪問什么樣的表格,也就沒辦法知道自己應(yīng)該怎么解釋將要讀到的記錄。
關(guān)鍵系統(tǒng)表有:
sysallocunits。
syshobts。
syshobtcolumnes。
sysrowsets。
sysrowsetcolumns。
對(duì)于普通用戶訪問,這些表都是不可見的,只有在DAC模式下的連接才能看到它們。它們的結(jié)果對(duì)普通用戶也是透明的。
這里的每一張系統(tǒng)表都有一個(gè)聚集索引。SQL Server會(huì)像做CHECKTABLE一樣,對(duì)這些系統(tǒng)表做一遍檢查,確保這些表格里的每一頁及頁面里的每一條數(shù)據(jù)都可以正確的讀出來。如果中間發(fā)現(xiàn)問題了,例如,發(fā)現(xiàn)某個(gè)頁面不能被正常訪問,SQL Server會(huì)報(bào)錯(cuò)。例如:
Server: Msg 8966, Level 16, State 1, Line 1
Could not read and latch page (1:33245) with latch type SH.Sysobjects failed.
對(duì)于小的數(shù)據(jù)庫(kù),這些存放元數(shù)據(jù)庫(kù)的系統(tǒng)表不會(huì)占用太多的頁面。如果發(fā)生硬件問題,損壞的概率比較小。對(duì)于一些有成千上萬對(duì)象的數(shù)據(jù)庫(kù),這些元數(shù)據(jù)系統(tǒng)表本身可能使用了很多頁面,發(fā)生損壞的概率也隨之增大。由于這些系統(tǒng)表正確讀取一切數(shù)據(jù)的根本,所以如果任意一張系統(tǒng)表上發(fā)生了損壞,DBCC CHECKDB會(huì)直接失敗,數(shù)據(jù)庫(kù)也無法做任何修復(fù)。此時(shí)修復(fù)數(shù)據(jù)庫(kù)的唯一方法是恢復(fù)數(shù)據(jù)庫(kù)備份。
總結(jié)
以上是生活随笔為你收集整理的dbnetlib sqlserver不存在或拒绝访问_SQL Server数据库损坏和修复的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: phpcms的phpcms_auth导致
- 下一篇: koa2 mysql增删改查_使用nod