1. 程式人生 > >你所不知道的SQL Server資料庫啟動過程,以及啟動不起來的各種問題的分析及解決技巧

你所不知道的SQL Server資料庫啟動過程,以及啟動不起來的各種問題的分析及解決技巧

目前SQL Server資料庫作為微軟一款優秀的RDBMS,其本身啟動的時候是很少出問題的,我們在平時用的時候,很少關注起啟動過程,或者很少了解其底層執行過程,大部分的過程只關注其內部的表、儲存過程、檢視、函式等一系列應用方式,而當有一天它執行的正常的時候突然啟動不起來了,這時候就束手無策了,能做的或許只能是重灌、配置、還原等,但這一個過程其實是一個非常耗時的過程,尤其當我們面對是龐大的生產庫的時候,可能在這火燒眉毛的時刻,是不允許你再重搭建一套環境的。

所以作為一個合格的資料庫使用者,我們要了解其啟動、執行過程的事情,一旦發生問題,我們也能及時定位,迅速解決。

閒言少敘,我們進入本篇的正題。 

SQL Server本身就是一個Windows服務,每一個例項對應的就是一個sqlserver.exe程序。這是一個可執行的檔案,預設就放在SQL Server的安裝目錄下,當我們啟動的時候,就是直接呼叫這個檔案,然後啟動這個服務。 

第一部分、SQL Server例項啟動的方法和啟動所發生的問題

  SQL Server例項分為下面幾種啟動方法:

(1)在Windows服務控制檯裡手動啟動,或者自動啟動(預設),這個也是最常用的方式

(2)第二種方式是SQL Server本身自己提供的啟動方式,我們這裡可以手動啟動

(3)在SQL Server的SSMS裡面手動啟動它,這個方式一般大部分利用這種方式進行手動重啟

(4)通過Windows命令視窗,用'net start'命令手動啟動,這種方法也可以用

以上這幾種方式都可以啟動SQL Sever,並且都會在SQL 日誌資訊中有所記錄。

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

第二部分、SQL Server例項啟動的詳細過程以及所發生的問題項

第一步、檢查登錄檔項

當一個sqlserver.exe檔案開始啟動的時候,首先要乾的第一件事就是先檢查它的配置資訊存放於登錄檔的值項

比較重要的幾個鍵值有下面幾個:

這裡的

AuditLevel:其實就是SQL 如何記錄使用者登入記錄;

LoginMode:是SQL Server伺服器身份驗證方式等;

BackupDirectory:預設的備份路徑等資訊;

關於登錄檔資訊簡要了解即可,不建議做任何修改,當然這些值的資訊預設在SQL Server中都能設定:

在不修改登錄檔的情況下,一般這一步的啟動順序一般不會出現問題,當然出現問題了也通常沒有辦法解決,大部分的解決方式只有重灌了。

但這一步驟,通常出現以下兩個個問題通常是可以解決的:

<1>啟動賬號許可權問題

如果我們啟動SQL Server的程序使用的賬號連讀登錄檔的許可權都沒有,那這個服務是怎麼也啟動不了的,通常這時候連SQL 的錯誤日誌都沒有能力生成出來。

這時候我們該如何發現呢,雖然這時候它沒有能力建立SQL 的錯誤日誌,但是它在Windows層面留下了痕跡,我們來看:

我將服務啟動賬號設定成gust來賓賬號,來啟動該服務

這時候會產生以下錯誤資訊:

在Windows的日誌資訊裡也會產生一條錯誤日誌記錄:

這裡的拒絕訪問指的就是拒絕訪問登錄檔資訊了。

解決方法

此問題的解決方式就很簡單了,只需要將當然的使用者提權到SQL Server服務的啟動賬號就行了,提權的方式也很簡單,只需要新增到SQL的本地使用者的啟動服務組就可以了。

當然,也可以直接換一個更高級別的使用者登入。一般預設都用的超級管理員賬戶。

<2>訪問日誌和資料夾出現問題

預設在SQL Server啟動的時候會建立一個啟動日誌檔案,記錄所有正確的日誌資訊,當然也包括錯誤的日誌資訊,如果這時候找不到這個日誌資訊的路徑,或者已經存在一個日誌,但是日誌被鎖定了(某些NB的防毒軟體擅長幹這個),這時候這個服務也是啟動不了的,同樣也建立不出SQL Server的日誌檔案,這時候我們還得藉助於Windows平臺本身,來解決。

SQL Server啟動的建立的日誌檔案路徑,同樣存在於登錄檔項裡,我們來看這個引數:

這裡我們故意改成一個錯誤的路徑,來啟動下看看:

會產生以下錯誤

系統的錯誤日誌資訊

錯誤說明的很清楚。

解決方法

這個問題解決起來也很簡單,只需要檢查好該路徑,確保路徑下的檔案正確就可以。

不過有一點需要注意,當SQL Server還沒啟動起來的時候,有部分錯誤資訊日誌需要檢查Windows平臺下的系統日誌。

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

 第二步、檢查系統配置環境,包括硬碟、記憶體與CPU等

當我們進行完第一步的時候,SQL Server已經讀取完登錄檔資訊,完成了它的errorlog檔案的建立,然後開始進行第二步的進行,這一步驟所有的資訊就會按照順序依次記錄到errorlog檔案中,我們可以通過檢視該檔案來詳細跟蹤這一步驟的進行,根據上一步的登錄檔資訊,我們先來手動清空下這個日誌,然後重啟一下SQL Server服務,檢視下這個日誌記錄

我們簡單大致分了以下幾大步驟:

一、首先檢查系統的軟體環境,包括OS版本、電腦訊號、記憶體、硬碟、登錄檔基礎配置項是否正確等

二、啟動系統資料庫master

三、開始利用服務使用者登入系統、啟動系統資源資料庫、檢查資料庫版本資訊等

四、啟動系統資料庫model

五、開始網路配置進行連線,對外提供服務,使用的預設的1433埠

我們接著分析下面的日誌:

六、其實完成上面的第五步之後,也就開始啟動msdb系統資料庫

七、這時候開始真正的啟動使用者資料庫,並且完整各個庫的完整性校驗,並且在啟動使用者資料庫之前,先將系統庫的tempdb進行清空

八、在搭建完成之後,才開始啟系統的另外一個數據庫tempdb

上面的整個SQL  Server系統啟動的過程產生了詳細的日誌記錄,我們下面會依次按照該步驟進行詳細的進行逐步分析。

在檢查系統軟硬體環境的過程中,基本不會發生什麼致命錯誤。比較常見的問題就是記憶體配置問題,其實在上面的日誌記錄中有一句特別重要,它反映的就是SQL Server利用記憶體的情況,我們來看:

這句話的意思是將所有的資料頁鎖定到記憶體中,作為大部分資料庫而言,記憶體就是生命線,SQL Server同樣也是,如果系統(64bit中)沒有記憶體壓力的情況下,才能將資料頁正常的鎖定到記憶體中,如果記憶體壓力過大,系統記憶體是不允許將資料頁也加入到記憶體中,而這樣導致的問題就是SQL  Server嚴重的效能問題。

很多使用者希望限制SQL Server記憶體使用,並且有些客戶機將它限制到服務都不能啟動的情況,這時候在SQL Server的日誌中是這樣展現的,我們來看:

可以看到,該錯誤的原因還是挺清楚的,修復該錯誤的解決方法也很簡單,將記憶體配置調大就可以。

跟記憶體有關的還有一種特殊的情況,就是SQL Server的啟動賬號在伺服器上沒有Lock page in memory的許可權,如果沒有這個許可權,在明細日誌中檢視不到上面的日誌記錄,該問題的解決方法也很簡單,只需要將需要許可權加上就可,加許可權的方式如下:

經過上面的步驟基本,完成資料的軟硬體檢測過程。

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

 第三步、啟動系統資料庫master

master資料庫是SQL Server系統啟動過程中的第一個系統庫,是非常關鍵的資料庫。如果這個庫不能被正常開啟,則SQL Server就不能正常啟動。

和其它資料庫一樣,master資料庫也分為資料檔案和日誌檔案,啟動的過程是依次開啟,然後做恢復動作,如果這個過程沒問題的話,在Errorlog日誌檔案中,我們會看到如下的這句話:

如果這個過程出現了任何問題,SQL Server的啟動過程都會被中斷,啟動過程失敗。

而這個過程發生的錯誤,無非就集中以下幾種情況,我們來分析一下:

<1>在指定的路徑找不到master資料的資料檔案或日誌檔案

關於這個SQL Server的最主要的系統資料庫的路徑,它是以登錄檔形式存在的,在一下注冊表項,可以看到

如果在該路徑下找不到這個系統資料庫的話,服務是啟動不了的,並且會產生相應的錯誤日誌資訊,我們來模擬下,關掉服務,將這兩個檔案移除走,然後啟動看一下:

首先,該服務是啟動失敗的

我們來看一下系統日誌

看Errorlog的日誌資訊

可以看到,該問題提示錯誤資訊還是挺詳細的。我們來看第二種情況

<2>檔案找到了,但是沒有許可權訪問,或者不能以排他的方式開啟該檔案(預設的是獨佔鎖進行檔案開啟的)

此種情況也是有可能產生的,比如某些NB的防毒軟體就可以幹這個事,讓你的系統庫無法訪問,這樣同樣也是啟動不了的,我們這樣來看,提示的錯誤的資訊有哪些:

來看Errorlog的錯誤記錄:

<3>檔案找到了,訪問許可權也有,但是檔案有問題,就是說是資料庫損壞了

這個問題也經常出現,比如磁碟壞掉了,恢復後發現檔案有問題,不能正常開啟,這種問題我們來看錯誤資訊:

 

日誌中的資訊

關於master系統庫的啟動過程,基本就是上面的三種錯誤,關於這三種問題,我們該如何解決呢?

解決方法:首先如果根據錯誤日誌定位出問題的性質,如果是前兩種問題其實是挺好解決的,比如檔案沒找到、許可權項不對等,這些問題相應的去解決就可以,最棘手的就是第三種情況,出現這種情況最理想的情況是master資料庫進行了備份,通過備份檔案進行恢復就可以,一切就可以正常,當然通過暴力的停掉服務,拷貝檔案進去也可以解決。

最揪心的就是這個庫就沒備份,那該如何解決呢?這種方式的解決就得藉助SQL Server的安裝程式,進行重建master資料了,但是這種方式重建的master資料庫會導致以前的SQL Server的設定全部清空掉。

清空的資訊包括:所有的賬戶資訊(意味著需要重建)、msdb中的所有job資訊等(也需要重建)、使用者資料庫資訊(必須全部重新附加attch上)

而這一系列過程如果是一個生產庫,可能會是一個非常大的工作量!

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

 第四步、啟動系統資源資料庫,並檢查資料版本資訊

資源資料庫是SQL Server2005中引入的邏輯資料庫,在例項下是看不到的,但是有它的物理檔案,主資料庫預設名稱為:mssqlsystemresource.mdf、日誌名稱為:mssqlsystemresource.ldf

如果該資料庫啟動的過程中也出現了問題,那SQL Server也不能正常啟動。

這個系統資料庫比較特別,它是一個只讀資料庫,完全由SQL Server自己維護,使用者是不能更改的,所以我們只要保證它的是資料庫檔案和日誌完好就可以,不需要對它進行任何的跟蹤和維護。

當然如果非要看這個資料庫,可以通過單使用者的DAC方式進行連線。

所以這個資料庫在一般情況下不會發生意外,基本上是能正常啟動,不過特殊情況下,不能啟動的情況就以下兩種:

<1>資料庫檔案不存在,無法訪問,或者檔案壞掉了

其實它的報的錯誤資訊,類似於上面的master資料庫,我來截個圖,看一下:

這個是errorlog記錄的錯誤資訊

在windows層面也有它自己的錯誤日誌資訊:

<2>資源資料庫的版本和SQL Server的版本不一致

這個有可能是人為的更改了這個資源資料庫,導致現有的資源資料庫檔案和資料庫版本不一致,這樣的話也會導致錯誤的形成

 

windwos平臺也記錄下了該錯誤的資訊,看下面的圖片:

 

解決方法:

關於資源庫的這兩個問題解決方法,非常的簡單。只要找到和這臺伺服器上的SQL Server的版本一致的資料庫,拷貝過來就行。

當然最好的預防措施是:每當安裝完SQL Server或者打完補丁之後,就及時的備份這個兩個檔案,放在安全的地方,用的時候拷貝過來就行備份是資料庫管理員的天職

當然有時候在緊急的情況下,找不到相同版本的資料庫,理論上這個庫是隻讀的,所以不會發生任何改變,我們隨便找一臺機器,安裝一下同版本資料庫,然後拷貝過來就行,當然一定注意的是這裡面是相同版本。 

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

第五步、啟動系統資料庫model

model系統資料庫同樣也是SQL Server啟動過程中用到的一個非常關鍵的資料庫,如果這個庫損壞,SQL Server啟動也會失敗,關於model資料不能啟動的原因基本和master的類似,同樣也是兩種:1、資料庫檔案早不到或者不能訪問;2、資料庫檔案能訪問但是是損壞的檔案。

診斷此種問題的方式也和上面的兩種方式一樣,檢視啟動過程產生的errorlog檔案或者windows系統日誌,這裡我們就不重現該問題了。

我們只給出此種問題的解決方法

1、如果該庫我們已經做過備份,那最直接也是最有效的解決方式就是直接還原,這裡的還原方式可能和普通庫的還原方式不一樣,因為SQL  Server例項還沒有啟動,我們恢復過程採取以下過程:

a.用引數啟動SQL Server,在命令提示行中執行以下命令,這樣的話SQL Server啟動就會跳過model資料庫恢復這一步

net start MSSQLSERVER /f /m /T3608

b.現在恢復model資料庫,開啟SSMS,直接輸入

RESTORE DATABASE model FROM DISK ='G:\data\model.bak'
WITH 
MOVE 'modeldev' TO 'E:\dataDefaultFileManger\MSSQL10.MSSQLSERVER\MSSQL\DATA\model.mdf'
MOVE 'modellog' TO 'E:\dataDefaultFileManger\MSSQL10.MSSQLSERVER\MSSQL\DATA\model.ldf'
,replace

c.恢復成功後,直接重啟SQL Server既可以。

2、將SQL Server關閉,然後直接採取暴力的方式將model資料檔案拷貝回來就可以,這種方式簡單有效,但是非常規操作

3、還有一種方式是利用setup安裝檔案,重建該資料庫,過程緩慢,稍顯複雜,很不推薦。

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

第六步、開始網路配置進行連線,對外提供服務,使用的預設的1433埠

當上面的幾個重要的系統庫都已經啟動完成之後,下一步就是開始檢查網路環境,進行網路服務的配置,對外進行提供服務了,一般來講,在SQL Server中利用的網路啟動協議有三種:Shared Memory、Named Pope和TCP/IP,其實在日常我們最常用的就是TCP/IP這種方式了,並且預設開啟的是1433埠。

我們來看一下正常啟動過程中,該部分的詳細日誌:

這裡面的Shared Memory是專供本地連線通過LPC(Local Procedure Call)技術向SQL Server做的連線。它不走網路層,所以他是速度最快的連線方式。正常啟動後會顯示上面的正常日誌。

Named Pipe方式正常啟動,也會顯示出上面的日誌。可以看到。

這其中我們最常用的TCP/IP這種方式,也正常的啟動了,並且指定了兩種訪問方式,ipv4/ipv6,然後後面加上了1433埠號。

在這個過程中最常出現的問題就是,1433埠被其它程式佔用,這樣就導致TCP/IP協議無法正常啟動,這樣我們會看到如下日誌資訊

並且在windows 系統日誌中也會有記錄

解決方法

其實這裡出現的問題還是挺好解決的,只需要找到佔用這個埠的應用程式,採取措施讓它把這個埠給讓出來就可以。

當然出現這些問題就意味著客戶端已經無法通過TCP/IP這種遠端連線的方式進行連線訪問了。

這時候一般管理員可以採用SQL Server給其提供的“專用管理員連線”(DAC)進行連線,這種方式我們以後再介紹。

當然,在SQL Server啟動的過程中,一般出現這種網路問題,或者協議不能成功載入,SQL Server會報出錯誤資訊,但是一般情況下是不會影響SQL Server的正常啟動的。受影響的可能只是出問題的那種協議功能。

我們只需要根據日誌,定位問題,然後解決掉,重新啟動就可以了。

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

第七步、開始啟動msdb系統資料庫

關於msdb這個系統資料庫,它是被安排在系統庫中接近最後一個了,除了使用者資料庫和臨時庫tempdb之外,當啟動過程中已經進行到這一步的時候,其實我們的例項就已經啟動起來了,並且能夠連線。

我們知道msdb這個庫中主要的儲存的資訊是應用各個庫的備份資訊,各種job的歷史跑批資訊等,其實諸多的都是來自於使用者資料庫所產生的一些客觀資料。

我們來看一下這個庫出現了問題會產生什麼現象:

我將這個庫檔案移除走,然後重新啟動服務,啟動過程中沒有報任何錯誤,並且能夠順利啟動,我們用SSMS直接連線過去,也可以正常連線

但是當我們點選開資料的時候,其實是看不到任何使用者資料庫的,並且會產生一個錯誤提示:

看來是不能使用的,我們來檢視一下錯誤日誌:

雖然這個庫的重要性比起master之類的庫重要性要稍顯差一些,但是缺少了它我們的SQL Server雖然能啟動,但是依然不能使用。

解決方法

要解決這個問題其實方式就很多種了,因為到此我們的SQL Server例項已經能夠正常啟動了,我們可以採取:

1、利用備份還原該庫,參考文章前面的方式(推薦)

2、關掉服務,利用暴力的拷貝檔案的方式進行恢復,簡單有效,非常規操作

3、找臺相同的環境,找到相同的檔案,直接拷貝過來使用

4、利用安裝檔案進行恢復(不推薦)

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

第八步、啟動使用者資料庫,並且完整各個庫的完整性校驗,並且在啟動使用者資料庫之前,先將系統庫的tempdb進行清空

本步驟所遇到的問題層出不窮,各種樣式,我打算再重新組織一篇文章,專門列舉,此篇就不介紹了。

但有一點需要記住:在這一步之前SQL Server會將tempdb這個系統庫清空掉,也就是說,每次的重啟操作,系統都會將tempdb清空,然後重建,這一步一般不會發生異常,成功之後會出現以下日誌資訊:

第九步、開始重建系統的另外一個數據庫tempdb

tempdb這個庫比較特殊,每次重啟的時候都是重新建立的,SQL Server會根據master資料庫裡的記錄的資訊以model資料庫為版本進行建立。所以只要我們保證model資料庫沒有問題,然後硬碟沒有問題,tempdb的資料庫檔案就應該沒有問題。

關於temdb這個庫的所有配置資訊是儲存於master的資料庫中的,裡面的內容資訊是儲存於model系統庫中的

這樣就帶來了一個問題,有時候我們的master的庫是從別的機器下面備份下來的,所以它裡面會記錄這個tempdb這個庫在原來機器上的路徑,這樣在啟動建立的時候就會報錯。

所以我們需要執行以下命令更改這個庫路徑

a、用引數啟動SQL Server

net start MSSQLSERVER /f  /m  /T3608

b.修改資料檔案和日誌檔案路徑

ALTER DATABASE tempdb MODIFY FILE(NAME=tempdev,FILENAME='C:\right path....\temdb.mdf');
go
ALTER DATABASE tempdb MODIFY FILE(NAME=tempdev,FILENAME='C:\right path....\temdblog.ldf');
go

c.正常啟動資料庫既可以

還有一種情況,就是建立該檔案的時候,提供的硬碟空間不足,或者許可權不夠,我們也是根據上面的方式,修改到一個正確的路徑,並且確保許可權正確。

也可以更改temp檔案的大小,預設是4M,程式碼如下:

ALTER DATABASE tempdb MODIFY FILE(NAME=tempdev,SIZE=100MB);
go
ALTER DATABASE tempdb MODIFY FILE(NAME=tempdev,SIZE=100MB);
go

至此,如果上面的整個過程都沒出問題的話,一個正常的SQL Server就可以啟動成功的。

結語

本篇文章到此結束了.....此篇耗時三天.....為了儘可能的呈現出所有的問題現象,我對本地的SQL Server進行了多種無情的蹂躪、各種的摧殘,力求能夠重顯各種不同的應用場景問題現象,然後儘可能的找到合適的解決方案,當然還有很多的情況沒有展現出來,後續遇到,會一一補充進來,當然有遇到不能解決的,也可以留言,我們一起分析解決。

關於使用者資料庫啟動過程,這個過程是一個問題較易發生的步驟,神馬質疑、恢復中、不可用等等現象,我後續的文章中列舉分析。

已經補充出該篇的關聯篇:

如果您看了本篇部落格,覺得對您有所收穫,請不要吝嗇您的“推薦”。