久久青草精品A片狠狠,日韩欧美视频一区二区,亚洲国码AV日韩,国产精品黄在

幫助中心 >  技術(shù)知識庫 >  數(shù)據(jù)庫 >  相關(guān)技術(shù)支持 >  SQL Server數(shù)據(jù)庫啟動過程(用戶數(shù)據(jù)庫加載過程常見問題)第三部分

SQL Server數(shù)據(jù)庫啟動過程(用戶數(shù)據(jù)庫加載過程常見問題)第三部分

2016-10-07 08:22:17 10430

在經(jīng)歷了上面的文件級別錯(cuò)誤后,在數(shù)據(jù)庫啟動的過程,還經(jīng)常出現(xiàn)的是數(shù)據(jù)頁級別的錯(cuò)誤,相對于上面的文件錯(cuò)誤級別,在數(shù)據(jù)頁中造成的錯(cuò)誤粒度更小,并且基本不會反映到數(shù)據(jù)庫級別,也就是說在出現(xiàn)數(shù)據(jù)頁級別的錯(cuò)誤時(shí)候,該數(shù)據(jù)時(shí)可以正常訪問的,只是在訪問有錯(cuò)誤的數(shù)據(jù)頁的時(shí)候才會報(bào)錯(cuò),在我們遇到這種錯(cuò)誤的時(shí)候該如何解決呢?

下面我們依次來分析,首先我們來制作一個(gè)經(jīng)典的824錯(cuò)誤,以下部分內(nèi)容牽扯到數(shù)據(jù)庫部分基礎(chǔ),限于篇幅,我們不做詳細(xì)介紹:

<1>首先我們在我們的測試庫中新建一個(gè)表,我們將該表新建成一行為一個(gè)數(shù)據(jù)頁的方式,也就是說一行數(shù)據(jù)庫在數(shù)據(jù)庫中就能承載一個(gè)數(shù)據(jù)頁

復(fù)制代碼

USE CnblogsTestDB
GO
CREATE TABLE [dbo].[TestPage]
(
    [a] [int] NULL,
    [b] [nvarchar](3900) NULL
) ON [PRIMARY]

復(fù)制代碼

腳本很簡單,一張表,兩列,一列int類型,一列nvarchar(3900),一行數(shù)據(jù)的存儲空間為:3900*2(nvarchar(3900))字節(jié)+4(int)+96字節(jié)(頁頭)+36字節(jié)(行偏移)=7932字節(jié),我們知道一個(gè)數(shù)據(jù)頁存儲的信息為8K=8192字節(jié),包括其它消耗所以該表一行數(shù)據(jù)如果填充完,一行數(shù)據(jù)將近乎占據(jù)一個(gè)數(shù)據(jù)頁。

我們來添加三行數(shù)據(jù),然后查看頁信息:

復(fù)制代碼

--插入三條數(shù)據(jù)
insert [TestPage]
values(1,REPLICATE('A',3900))
insert [TestPage]
values(2,REPLICATE('B',3900))
insert [TestPage]
values(3,REPLICATE('C',3900))
go--查看頁信息
dbcc  traceon(3604)--查看庫中頁集合
dbcc extentinfo(CnblogsTestDB,[TestPage])

復(fù)制代碼

可以看到,該表中現(xiàn)在有三個(gè)數(shù)據(jù)頁,我們來看看數(shù)據(jù)頁應(yīng)該也是近乎沾滿的

 上圖顯示了,通過掃描表信息,共含有3個(gè)數(shù)據(jù)頁,每個(gè)數(shù)據(jù)頁中的數(shù)據(jù)量存儲占比到了96.55%,也就是說基本上是填充滿了。

 當(dāng)然,我們還可以通過DBCC PAGE命令,來查看每個(gè)頁中的具體內(nèi)容,我們簡單的看一個(gè)頁面編號為90的數(shù)據(jù)頁:

通過上面的命令可以看到,該數(shù)據(jù)頁中存儲的為表中的第一行的數(shù)據(jù),并且在數(shù)據(jù)庫存儲文件中是以十六進(jìn)制方式編碼存儲。

當(dāng)然,如果感覺此方式不直觀,可以利用一個(gè)小工具進(jìn)行數(shù)據(jù)頁的查看,這里我推薦使?Internal Views(此工具在樺仔的博文中有詳細(xì)介紹),可更直觀的展示數(shù)據(jù)存儲頁信息:

這里我們可以點(diǎn)擊我上面上面查看的第一行的數(shù)據(jù)內(nèi)容頁進(jìn)行查看

 

經(jīng)過上面的分析步驟,其實(shí)我的目的是想重現(xiàn)在SQL Server啟動過程中,或者在線上的數(shù)據(jù)庫經(jīng)常遇到的經(jīng)典錯(cuò)誤824錯(cuò)誤

上述過程是原理篇,因?yàn)槲覀儽仨氈罃?shù)據(jù)存儲的底層原理,才能理解好這個(gè)錯(cuò)誤的原因,以及找到正確的處理方法。

 

下一步,我們來重現(xiàn)這個(gè)錯(cuò)誤的原因,我們知道在我新建的測試表中含有兩個(gè)字段:a和b,并且a為int類型、b為nvarchar類型

然后我們介紹了底層的存儲機(jī)制,我現(xiàn)在將第一列a字段的整形數(shù)據(jù)內(nèi)容存儲改成字符串類型,依次來損壞掉該數(shù)據(jù)頁內(nèi)容

我先將服務(wù)停掉,然后用文件編輯工具,修改此數(shù)據(jù)頁內(nèi)容,該數(shù)據(jù)頁內(nèi)容為十六進(jìn)制內(nèi)容,當(dāng)然在我搞壞這部分?jǐn)?shù)據(jù)頁之前我先做一個(gè)完整備份

 

然后修改該數(shù)據(jù)頁信息,這里我使用UltraEdit文本編輯工具,打開文件,找到該數(shù)據(jù)頁內(nèi)容

我們將上面的源數(shù)據(jù)更該一下,來把這個(gè)數(shù)據(jù)頁損壞掉

 我們保存,然后重新啟動該數(shù)據(jù)庫看看

 這就是我們平常比較常見的824錯(cuò)誤的過程,而此過程有可能是磁盤壞道造成,或者誤修改文件等諸多原因,但是此問題還是比較常見的

當(dāng)然,這種數(shù)據(jù)頁面的損壞可能造成的影響不是庫級別的,也就說不會造成數(shù)據(jù)庫不能訪問,其它表是能正常訪問的,但是只是在操作此損壞的數(shù)據(jù)頁的時(shí)候才會報(bào)錯(cuò),但有時(shí)候這幾個(gè)數(shù)據(jù)頁的損壞對業(yè)務(wù)產(chǎn)生的影響有可能就是致命的,所以我們要解決掉。

鄭重提示:上面過程也可以正確的更改數(shù)據(jù)頁中的數(shù)據(jù),但是如果沒有確切的把握,基本上能把數(shù)據(jù)庫搞癱瘓掉,我是為了重現(xiàn)問題才修改底層元數(shù)據(jù),所以在自己的生產(chǎn)庫中千萬不要亂搞!

在數(shù)據(jù)庫啟動的過程中,會發(fā)生一致性校驗(yàn),所以該錯(cuò)誤應(yīng)該會記錄到Error的錯(cuò)誤日志文件中,我們來看:

windows平臺下的錯(cuò)誤日志:

當(dāng)然,在啟動的過程中該問題有可能發(fā)生很多,比如磁盤壞道等原因,一系列的數(shù)據(jù)頁可能就沒法訪問了。所以SQL Server會將這些損壞的頁面記錄到msdb系統(tǒng)庫中,這我們在這個(gè)庫中查找到損壞的頁面集合:

至此,我們已經(jīng)重現(xiàn)了經(jīng)典的824錯(cuò)誤,那我們該如何解決此問題呢? 

解決方法:

a、如果此問題出現(xiàn)的頁面為數(shù)據(jù)承載頁,也就說該頁存儲的為內(nèi)容數(shù)據(jù)或者為聚集索引的葉子節(jié)點(diǎn)數(shù)據(jù),并且存在鏡像,版本在SQL Server2005以上,那么這個(gè)錯(cuò)誤基本可以忽略,SQL Server能夠自動幫你修復(fù)此錯(cuò)誤。

b、如果此問題出現(xiàn)在沒有鏡像的環(huán)境中,那就要區(qū)分是損壞頁面是否為聚集索引葉子節(jié)點(diǎn)數(shù)據(jù),如果是,那就簡單了,直接重建索引就好了,如果不是,那此種方案還是不能解?,判斷方法如下:

利用DBCC PAGE命令查看當(dāng)前數(shù)據(jù)頁內(nèi)容,根據(jù)ObjectId跟蹤該頁位于哪個(gè)對象上,Metdata:IndexID的值判斷是否為索引樹中的節(jié)點(diǎn)值,如果大于0則表示為索引值,此時(shí),重建該索引既可以。比如:

我們根據(jù)該頁的ObjectID,從數(shù)據(jù)庫中查找該頁所屬對象。

 c、如果上述方案都不能滿足,那只有采取此種方案,我們可以利用數(shù)據(jù)庫備份進(jìn)行還原,當(dāng)然為了最大限度的避免數(shù)據(jù)庫離線,我們最好采取數(shù)據(jù)頁還原的方式,此種方式最為簡單,還原速度也最快,能夠最大限度的縮短數(shù)據(jù)庫離線時(shí)間,并且保證數(shù)據(jù)完整性。

這里提示下:在SQL Server2012版本一下,SSMS不提供圖像化數(shù)據(jù)頁還原方式,在SQL Sever以后的版本中,有圖像化界面操作。

所以,我們只能通過如下腳本進(jìn)行還原:

RESTORE DATABASE CnblogsTestDB
PAGE='1:90'FROM DISK = N'F:SQLTestCnlogsTestDB.bak'WITH NORECOVERY

當(dāng)然有事務(wù)日志、更新備份的,需要依次恢復(fù)這過程的所有的備份,不要忘記備份尾部日志。

但是此方法也有局限性:

如果損壞的數(shù)據(jù)頁為

  1、分配頁:GAM、SGAM和PFS頁

  2、所有數(shù)據(jù)文件的啟動頁

如果發(fā)生損壞的是以上兩種,則無法通過該備份恢復(fù)頁方式進(jìn)行恢復(fù)。如果這種情況下,建議考慮找合適的時(shí)間段進(jìn)行全庫的恢復(fù)操作。(推薦)

d、上述情況是在存在有備份的情況下,如果沒有數(shù)據(jù)庫備份,那我們只能選擇最后的一招了,那就是DBCC CHECKDB命令,同樣和上面一樣,此種方式可能會造成數(shù)據(jù)丟失,所以不建議采用,如果能容忍數(shù)據(jù)丟失,采用的過程參照文中的上半部分。(不推薦)

 

至此,我們已經(jīng)完成了一個(gè)SQL Server啟動過程或者平常最經(jīng)常遇到的一個(gè)經(jīng)典錯(cuò)誤824錯(cuò)誤,我們來總結(jié)下:

824錯(cuò)誤原因:大部分是由于磁盤存儲導(dǎo)致的數(shù)據(jù)頁損壞,導(dǎo)致的SQL Server在讀取的時(shí)候發(fā)生了錯(cuò)誤。

導(dǎo)致錯(cuò)誤場景:磁盤壞道、突然斷電等情況下經(jīng)常會出現(xiàn)此錯(cuò)誤。

 

----------------------------------------------------------霸氣的分割線-----------------------------------------------------------------------

和824錯(cuò)誤相關(guān)的還有一種是823錯(cuò)誤,我們來介紹下該錯(cuò)誤信息
由于場景所限,我就不重現(xiàn)該錯(cuò)誤了,在這里我詳細(xì)的介紹下這兩種錯(cuò)誤的原因和原理,就可以了,如果遇到了,解決的方式基本都是一致的,可參照上面的824錯(cuò)誤解決方法。

SQL Server在每次寫入頁面的時(shí)候,會根據(jù)頁面里的數(shù)據(jù)算出一個(gè)校驗(yàn)值?一同存儲到頁面中去。當(dāng)下次讀取頁面的時(shí)候,再根據(jù)這次讀到的頁面數(shù)據(jù),算出一個(gè)新的校驗(yàn)值。如果寫入和讀出的數(shù)據(jù)一模一樣,那么兩個(gè)校驗(yàn)值就是相等的。如果兩個(gè)校驗(yàn)值不相等,就意味著上次SQL Server寫入的數(shù)據(jù)和這次讀取出來的一定不同,現(xiàn)在讀取出來的數(shù)據(jù)就有問題了。

823錯(cuò)誤就代表著SQL Server在向操作系統(tǒng)申請某個(gè)頁面讀寫的時(shí)候遇到了Windows?取或?qū)懭胝埱笫?。所以該問題的原因大部分是源自于操作系統(tǒng)層面,更確切的說是物理文件損壞而導(dǎo)致此錯(cuò)誤,比如設(shè)備驅(qū)動程序?qū)е碌取?/p>

824錯(cuò)誤則是在讀取數(shù)據(jù)頁面時(shí)候,發(fā)現(xiàn)數(shù)據(jù)頁面有問題,比如讀取出來的校驗(yàn)值不對等。 

當(dāng)上面描述的823和824錯(cuò)誤出現(xiàn)大面積的時(shí)候,或者直接部分?jǐn)?shù)據(jù)文件完全壞掉的情況下,在SQL Server啟動過程中就會出現(xiàn)數(shù)據(jù)庫SUSPECT“質(zhì)疑”狀態(tài)。

經(jīng)過我的多次數(shù)據(jù)頁的破壞和摧殘,我已經(jīng)順利的將我們的這個(gè)測試庫給搞成?質(zhì)疑狀態(tài),我們來看SUSPECT(質(zhì)疑)的狀態(tài)庫:

這里我直接DBCC CHECKDB命令嘗試著恢復(fù)下看看

 

所以到此,我們要做的就是避免上述錯(cuò)誤的發(fā)生。如果在生產(chǎn)庫中?生了我上面的情況,然后沒有數(shù)據(jù)庫備份,那么剩下來你要做的事情:我估計(jì)就是準(zhǔn)備簡歷了..... 

結(jié)語

文章主要還是分析SQL Server啟動過程中,加載用戶數(shù)據(jù)庫的時(shí)候,所遇到的一系列問題,文中部分內(nèi)容需要有一定數(shù)據(jù)庫基礎(chǔ)知識才能讀懂,篇幅有限,我們沒有做深入的講解分析,比如上面的幾個(gè)重要的命令DBCC PAGE....DBCC CHECKDB..等等,隨便一個(gè)都能寫出一系列的內(nèi)容,我們側(cè)重的還是問題的解決,和問題原因分析,后續(xù)文章中會介紹這一系列的命令作用,以及正確的使用技巧。

文中部分?jǐn)?shù)據(jù)庫錯(cuò)誤都是我耗費(fèi)精力一步一步調(diào)整出來,目的是真實(shí)的展現(xiàn)錯(cuò)誤明細(xì),其實(shí)問題解決容易,問題重現(xiàn)的過程復(fù)雜。

如果經(jīng)常使用SQL Server,其實(shí)這些問題都是我們會經(jīng)常遇到的,所以我們要記住相應(yīng)的解決方案,做的有備無患!


提交成功!非常感謝您的反饋,我們會繼續(xù)努力做到更好!

這條文檔是否有幫助解決問題?

非常抱歉未能幫助到您。為了給您提供更好的服務(wù),我們很需要您進(jìn)一步的反饋信息:

在文檔使用中是否遇到以下問題: