日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

系統(tǒng) 2487 0
原文: 簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

轉(zhuǎn)自: http://blogs.msdn.com/b/apgcdsd/archive/2011/12/30/10251946.aspx

我的數(shù)據(jù)庫(kù)只有10GB,為什么我的日志文件有40GB,而且還在增長(zhǎng)?

2.???????我無(wú)法對(duì)數(shù)據(jù)庫(kù)進(jìn)行更改操作了。報(bào)錯(cuò)說(shuō)我的日志空間已滿。

3.???????我數(shù)據(jù)庫(kù)的恢復(fù)模式明明是Simple,為什么還有日志,還那么大?

4.???????我的數(shù)據(jù)庫(kù)一直處于恢復(fù)狀態(tài),其他應(yīng)用程序都報(bào)連接出錯(cuò)。

歸根結(jié)底一句話,我數(shù)據(jù)庫(kù)的日志的增長(zhǎng)遠(yuǎn)遠(yuǎn)超過(guò)我的預(yù)期,而導(dǎo)致我的業(yè)務(wù)受到影響。數(shù)據(jù)庫(kù)事務(wù)日志(Transaction Log),或簡(jiǎn)稱日志文件(Log)文件的 異常 增長(zhǎng) 有時(shí)候?qū)?shù)據(jù)庫(kù)的應(yīng)用的影響是致命的。

想象一下,在你的業(yè)務(wù)最繁忙的時(shí)候,你的數(shù)據(jù)庫(kù)由于日志文件占滿整個(gè)磁盤空間,而無(wú)法使用。有人說(shuō),很簡(jiǎn)單啊!我把日志文件刪掉。如果你真的這樣做,你會(huì)發(fā)現(xiàn)數(shù)據(jù)庫(kù)日志文件正被SQL Server進(jìn)程鎖定,而無(wú)法刪除。于是,你停止SQL Server服務(wù),然后很開心的將Transaction Log文件刪除了,節(jié)省了大概200GB的空間。再于是,你很“傷心”的發(fā)現(xiàn)你的數(shù)據(jù)庫(kù)無(wú)法啟動(dòng),因?yàn)槿鄙偃罩疚募?。如果你在日志文件原有的路徑?chuàng)建一個(gè)同名的日志文件,好吧,既然你那么堅(jiān)決,SQL Server會(huì)告訴你日志文件格式已損壞。突然,你發(fā)現(xiàn)自己有個(gè)很好的習(xí)慣,當(dāng)你刪除那個(gè)200GB的日志文件的時(shí)候,你只是把它扔到了垃圾箱,于是你把它找了回來(lái),重新啟動(dòng)你的SQL Server,很開心的發(fā)現(xiàn),它成功的啟動(dòng)了。于是你松了一口氣,泡上一杯咖啡,考慮是不是找你的Disk Vendor申請(qǐng)更多的磁盤空間。突然你的電話鈴聲大作,好多連接到你的數(shù)據(jù)庫(kù)的應(yīng)用程序的管理人員都向你抱怨他們無(wú)法連接到數(shù)據(jù)庫(kù)。你打開SSMS,發(fā)覺(jué)那個(gè)數(shù)據(jù)庫(kù)一直處于“恢復(fù)中”(In Recovery)狀態(tài)???好像它永遠(yuǎn)不會(huì)終止。好吧,你是不是有想砸機(jī)器的沖動(dòng)了,并且想氣勢(shì)洶洶的告訴全世界,這是微軟SQL Server的另一個(gè)Bug?

如果,你認(rèn)真的讀完這篇文章,你會(huì)發(fā)現(xiàn)這只不過(guò)是SQL Server的另一個(gè) 不恰當(dāng) 應(yīng)用的一個(gè)案例。

?

什么是日志文件(Transaction Log)

簡(jiǎn)而言之,日志文件通過(guò)一個(gè)簡(jiǎn)化的格式記錄了所有對(duì)數(shù)據(jù)庫(kù)的修改操作,包括Insert,?Update和Delete等能夠幫助你重現(xiàn)對(duì)數(shù)據(jù)庫(kù)內(nèi)容修改的操作。日志文件的后綴名為*.LDF。

數(shù)據(jù)文件?(*.mdf)Vs.?日志文件?(*.ldf)

有人本以為數(shù)據(jù)文件是存儲(chǔ)數(shù)據(jù)的“核心”文件,但是很詫異的發(fā)現(xiàn),原來(lái)日志文件存儲(chǔ)了所有的數(shù)據(jù)修改。有些人會(huì)想到,通過(guò)日志文件,其實(shí)我就可以把我的數(shù)據(jù)庫(kù)恢復(fù)到某個(gè)特定時(shí)間點(diǎn)的狀態(tài)。這句話,在某些限制條件下是對(duì)的,將在下文進(jìn)行討論。

那么,數(shù)據(jù)文件和日志文件的關(guān)系是什么呢?他們?nèi)绾喂ぷ鳎?

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

SQL Server是一個(gè)很依賴于內(nèi)存(Memory)使用的系統(tǒng)。任何一個(gè)對(duì)于數(shù)據(jù)的讀入/修改都是和內(nèi)存進(jìn)行交互。當(dāng)一個(gè)修改操作發(fā)生時(shí),修改的將是內(nèi)存中所對(duì)應(yīng)的在內(nèi)存中的數(shù)據(jù)頁(yè)。這個(gè)操作將會(huì) 實(shí)時(shí)地 被寫入日志文件。但是,該修改被寫入數(shù)據(jù)文件(*.mdf)的時(shí)間,只有在以下三種情況下發(fā)生:(1)做Checkpoint 時(shí)(2)Lazy write運(yùn)行時(shí)(3)Eager write運(yùn)行時(shí)。Lazy write發(fā)生在有內(nèi)存壓力時(shí),而Eager write通常發(fā)生在bulk insert和select into操作時(shí)的。 這里只談比較普遍的checkpoint情況。

Checkpoint是SQL Server的一個(gè)自動(dòng)的行為。 http://msdn.microsoft.com/en-us/library/ms188748.aspx ?所以,你的數(shù)據(jù)文件和日志文件的數(shù)據(jù)差異間隔會(huì)是兩個(gè)Checkpoint之間的時(shí)間差。Checkpoint本身也會(huì)被寫入日志文件。如果在某些情況下,Checkpoint并沒(méi)有如預(yù)期那樣短時(shí)間中發(fā)生,數(shù)據(jù)差異間隔會(huì)更長(zhǎng)。

日志文件如何影響我數(shù)據(jù)庫(kù)的啟動(dòng)?

無(wú)論你的SQL Server啟動(dòng),或者你將某數(shù)據(jù)庫(kù)重備份中恢復(fù),或者其他的一些情況,總之在你的數(shù)據(jù)庫(kù)能夠被正常使用之前,你的數(shù)據(jù)庫(kù)都會(huì)進(jìn)入?Recovery的狀態(tài)。 http://msdn.microsoft.com/en-us/library/ms190442.aspx ?如果這一個(gè)步失敗,那么你的數(shù)據(jù)庫(kù)就會(huì)進(jìn)入Suspect狀態(tài)而無(wú)法正常使用。在一些特殊情況下,這個(gè)Recovery所花費(fèi)的時(shí)間會(huì)很長(zhǎng)。在數(shù)據(jù)庫(kù)進(jìn)入Online狀態(tài)之前,我們都不能認(rèn)為SQL Server可以被正常使用了。

那么在Recovery中做了什么呢?

我們可以在你的SSMS中運(yùn)行如下語(yǔ)句。在運(yùn)行之前,你可以先按下Ctrl+T來(lái)把結(jié)果轉(zhuǎn)化成Plain Text格式。

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

sp_readerrorlog 會(huì)返回自從最近一次SQL Server服務(wù)啟動(dòng),或者Error Log被回收開始的SQL Server的Error Log信息。這里有兩個(gè)詞匯可能會(huì)讓你感到疑惑。 首先,這里的Log和我們上文所說(shuō)的日志文件(Transaction Log)中的Log不是一件事情。其次,所謂的Error Log,并不是說(shuō)這里出現(xiàn)了Error。 SQL Server使用這個(gè)Error Log記錄了很多診斷信息。所以,你可以認(rèn)為這只是一個(gè)普通的記錄了很多SQL Server相關(guān)信息的日志文件。

在結(jié)果返回中,你可能會(huì)找到上面的這些信息。引號(hào)中為在你當(dāng)前數(shù)據(jù)庫(kù)實(shí)例下的各個(gè)數(shù)據(jù)庫(kù)名。

以數(shù)據(jù)庫(kù)‘CaseLync’為例。由于Error Log會(huì)記錄當(dāng)前SQL Server實(shí)例下的所有數(shù)據(jù)庫(kù)的相關(guān)信息,所以你可能會(huì)看到和這個(gè)數(shù)據(jù)庫(kù)相關(guān)的日志被順序地分布在日志的不同地方。在上圖中,第一和第二行提及兩個(gè)詞:rolled forward和rolled back。這兩個(gè)詞和我們本文中所提及的Transaction Log息息相關(guān)。

在前文中,我們提到過(guò)數(shù)據(jù)修改的過(guò)程:先同步的被寫入Transaction Log,然后再Checkpoint發(fā)生的時(shí)候被同步到Data File里。那么,如果我的事物(Transaction)沒(méi)有被提交(Commit)或者回滾(Rollback),那么這個(gè)數(shù)據(jù)修改是否也在日志文件(Transaction Log)還是在數(shù)據(jù)文件里(Data File)?

答案是:都在!

SQL Server在記錄數(shù)據(jù)改變時(shí),并不會(huì)區(qū)分該語(yǔ)句是否有顯示的進(jìn)行事物操作(Begin Transaction,Commit / Rollback Transaction),?或者該事務(wù)是否有完成。SQL Server會(huì)忠實(shí)地記錄所有的修改操作。而Begin Transaction和Commit / Rollback Transaction本身也是日志文件需要記錄的操作之一。

由于對(duì)于事物日志的修改要先于對(duì)于數(shù)據(jù)文件的修改,所以當(dāng)你的數(shù)據(jù)庫(kù)處于Recovery的狀態(tài)時(shí),那么Transaction Log 就會(huì)從最近的一個(gè)Checkpoint 點(diǎn)開始做如下操作:

1.???????如果該操作已在在Transaction Log中,而不在Data File之中,并且如果它使用顯式的Transaction操作符而且處于Commit狀態(tài),則會(huì)發(fā)生一次Rolled Forward操作,將該操作同步到Data File之中。

2.???????如果該操作已在在Transaction Log中,而不在Data File之中,并且如果它使用顯式的Transaction操作符而且處于Rollback Transaction狀態(tài),則會(huì)發(fā)生一次Rolled back操作,將Data File之中的相關(guān)數(shù)據(jù)修改回滾到Transaction發(fā)生之前。

3.???????如果該操作已在在Transaction Log中,而不在Data File之中,并且如果它使用顯式的Transaction在日志文件中即沒(méi)有Commit操作,也沒(méi)有Rollback操作,則會(huì)發(fā)生一次Rolled back操作,將Data File之中的相關(guān)數(shù)據(jù)修改回滾到Transaction發(fā)生之前。

4.???????如果該操作已在在Transaction Log中,而不在Data File之中,并且如果它沒(méi)有使用顯式的Transaction操作符(Begin Transaction??,?則被認(rèn)為是一個(gè)Rolled Forward操作。

5.???????如上步驟都完成后,SQL Server會(huì)對(duì)該數(shù)據(jù)庫(kù)做一個(gè)Checkpoint的標(biāo)識(shí),并寫入Transaction Log,表示Data File和Transaction Log已經(jīng)同步。這表明了數(shù)據(jù)庫(kù)的Recovery完成。數(shù)據(jù)庫(kù)將進(jìn)入Online狀態(tài),并被正常使用。如果你的數(shù)據(jù)庫(kù)在最近的一次Checkpoint到現(xiàn)今的修改操作足夠多,在Error Log中也會(huì)看到SQL Server用百分比標(biāo)識(shí)Recovery完成的進(jìn)展。

?

問(wèn)題:我的數(shù)據(jù)庫(kù)一直處于?In Recovery狀態(tài),跑了好幾個(gè)小時(shí)了。

解決方案:好吧,這個(gè)說(shuō)明你的數(shù)據(jù)庫(kù)自從上一次的Checkpoint到你現(xiàn)在的這個(gè)點(diǎn)對(duì)該數(shù)據(jù)庫(kù)的修改足夠多。這種情況所對(duì)應(yīng)的癥狀是:

1.?你有個(gè)Begin很長(zhǎng)時(shí)間的Transaction,但是沒(méi)有Commit/Rollback。

·?????????如果是這樣,慢慢等吧。

2.?你的數(shù)據(jù)庫(kù)也許很長(zhǎng)時(shí)間沒(méi)有做Checkpoint了。

·?????????如果是這樣,建議你在Performance Monitor檢測(cè)一下Checkpoint的調(diào)用頻率。

問(wèn)題:我已經(jīng)理解了Recovery的工作模式,但是我真的很急,而且愿意承擔(dān)Data File和Transaction Log之間的差異。我只是想讓我的數(shù)據(jù)庫(kù)快點(diǎn)上線。

解決方案:第一件你需要考慮的是三思你是否確實(shí)要這樣做。雖然也許Data File與Transaction Log之間的差異并非那么多,但是你可能會(huì)在你的Data File里留下沒(méi)有被Commit的數(shù)據(jù),從而在邏輯上影響你應(yīng)用程序的使用。

如果你真的決定那么做,那么遵循以下步驟:

1.?設(shè)置單用戶,設(shè)置緊急狀態(tài)。

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

2.?獲取Transaction Log的物理名和邏輯名

3.?重建Log

?????

??????? 4.?將數(shù)據(jù)庫(kù)設(shè)置成Online和Multi_User狀態(tài)

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

?

如何維護(hù)事務(wù)日志(Transaction Log)

首先我們要理解SQL Server數(shù)據(jù)庫(kù)的恢復(fù)模式。

SQL Server的數(shù)據(jù)庫(kù)恢復(fù)模式分為3種 http://msdn.microsoft.com/en-us/library/ms189275.aspx ?:

·?????????Full:完全記錄事物日志??梢赃M(jìn)行日志備份。

·?????????Bulk-Logged:使用于批量操作的數(shù)據(jù)庫(kù)。以更壓縮的方式處理日志。可以進(jìn)行日志備份。

·?????????Simple:無(wú)法進(jìn)行日志備份。意味著你并不在乎日志文件。但是,依然生成數(shù)據(jù)庫(kù)日志文件。

雖然,日志文件記錄了所有的數(shù)據(jù)庫(kù)的更改操作,但是日志文件并非無(wú)限增長(zhǎng)的,是因?yàn)镾QL Server會(huì)按照一定的規(guī)則重用Log Space。

1.???????首先,Log是順序記錄的。而來(lái)自不同Transaction的對(duì)于同一個(gè)數(shù)據(jù)庫(kù)的Log可能是交錯(cuò)出現(xiàn)。

2.???????Transaction Log能夠申請(qǐng)/釋放的空間以Virtual Log File(VLF)為單位。

3.???????在同時(shí)滿足以下條件的前提下,Log Space可以被重用,即被覆蓋

a.???????最近一次Checkpoint之前。意味著Log File和Data File已經(jīng)同步。

b.??????最早一個(gè)Begin而沒(méi)有Commit/Rollback的Transaction之前的Virtual Log File(VLF)。

c.???????滿足以上條件的Virtual Log Space被標(biāo)識(shí)為可重用。Full和Bulk-Logged恢復(fù)模式的數(shù)據(jù)庫(kù)在備份日志時(shí)標(biāo)識(shí)。Simple模式的數(shù)據(jù)庫(kù)在做Checkpoint時(shí)標(biāo)識(shí)可重用。

4.???????Transaction Log到文件尾以后,如果文件頭的Virtual Log File(VLF)可以被重用,則會(huì)回溯到文件頭。

對(duì)于日志文件的重用性,通常會(huì)有以下誤區(qū):

1.??Simple模式下沒(méi)有日志文件。

·?????????其實(shí),任何模式下都有日志文件產(chǎn)生。只不過(guò),Simple模式下通過(guò)Checkpoint自動(dòng)地將可以重用的Virtual Log File(VLF)標(biāo)識(shí)為可重用。如果有個(gè)很早就Begin Transaction,而忘記被Commit/Rollback,你依然可能看到一個(gè)很大的日志文件。

2.??完整備份(Full Backup)會(huì)打斷日志備份鏈(Log Backup Chain)。

·?????????這個(gè)問(wèn)題源自于Log Shipping:在一臺(tái)做Log Shipping的Primary?機(jī)器上,是否可以做Full Backup?答案是可以的。假設(shè)你在做初始化的Full Backup1時(shí)的LSN是0-100,?其后周期性的Log Backup1, Log Backup2, Log Backup3的LSN分別是101-200,?201-300,301-400。而在做第二個(gè)Log Backup時(shí),你在該機(jī)器上做了一次Full Backup2的LSN為:0-250。則當(dāng)你從Full Backup2?開始做Restore過(guò)程是這樣的:

???????????????????????????????????????????????????????????????i.??????恢復(fù)?Full Backup2:0-250。

?????????????????????????????????????????????????????????????ii.??????加載/恢復(fù)Log Backup2: 201-300.?實(shí)際被恢復(fù)Log Backup2的LSN:251-300。

????????????????????????????????????????????????????????????iii.??????加載/恢復(fù)?Log Backup2: 301-400。

·?????????所以Log Backup2其實(shí)包含了完整的日志,但是在上述恢復(fù)的例子中,將從251開始恢復(fù)。

·?????????Log Backup Chain會(huì)在以下情況下被打破。

???????????????????????????????????????????????????????????????i.??????第一次做Full Backup。

?????????????????????????????????????????????????????????????ii.??????恢復(fù)模式在Full/Bulk Logged和Simple之間進(jìn)行轉(zhuǎn)換。

3.??如果文件很大(Data File或者Transaction Log File),我通過(guò)Shrink來(lái)收縮空間。

·?????????通常,我們并不推薦使用Shrink的方式來(lái)進(jìn)行收縮。因?yàn)镮O對(duì)于SQL Server而言是個(gè)非常昂貴的操作。你通過(guò)Shrink的方式收縮的磁盤空間,會(huì)在下次再次被SQL Server重新申請(qǐng)。而且在很多時(shí)候,你使用Shrink能夠回收的磁盤空間并不那么理想。所以我們的目標(biāo)是提高文件的重用性。

所以,對(duì)于維護(hù)日志來(lái)說(shuō)主要需要注意的是以下幾個(gè)方面:

1.??對(duì)于Full和Bulk-Logged,定期做日志備份。(在此之前最起碼有1個(gè)完整備份。)兩次備份的間隔是你能夠容忍數(shù)據(jù)丟失的時(shí)間跨度。

2.??Transaction盡可能短而快。避免長(zhǎng)時(shí)間開啟一個(gè)Transaction,或者Begin Transaction而忘記Commit/Rollback Transaction的事情發(fā)生。

問(wèn)題:我的日志文件很大,而且收縮不下來(lái)。

解決方案:

首先,我們并不贊成通過(guò)自動(dòng)/定期收縮的方式來(lái)控制文件的大小。我們建議通過(guò)建立良好的維護(hù)計(jì)劃來(lái)提高日志文件空間的重用性而達(dá)到同樣的目的。當(dāng)然,如果你想把日志文件收縮(Shrink)到一個(gè)合理的程度,你可以參考如下步驟。

第一步,你需要查找的是,是否有個(gè)開了很長(zhǎng)時(shí)間的Transaction,但是沒(méi)有Commit/Rollback?可以通過(guò)以下語(yǔ)句查找該數(shù)據(jù)庫(kù)下,跑了最長(zhǎng)而沒(méi)有被提交的Transaction。

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

如果有的話,你要么通知那個(gè)應(yīng)用程序的管理人員來(lái)Commit/Rollback?這個(gè)Transaction。要么在SQL Server這邊粗暴的殺死這個(gè)Session。下例中,1234為執(zhí)行這個(gè)Transaction的Session ID(SPID)。

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

第二步,通過(guò) DBCC ?SQLperf ( Logspace ) 檢查L(zhǎng)og文件被使用的情況。

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

如果數(shù)據(jù)庫(kù)的Log Size很大,而Log Space Used(%)相對(duì)較小。那么說(shuō)明有足夠可以被收縮的空間。(但是當(dāng)Log Space Used很大時(shí),也不代表無(wú)法收縮足夠的空間)

第三步,通過(guò) dbcc ?loginfo檢查VLF的使用的情況。

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)

在這里值得關(guān)注的是Status列。0 –?可以被Log所使用的VLF。?2-?已被使用,而且無(wú)法重用的VLF。通過(guò)備份Log的方式,將Status為2的行變成0。此時(shí)該空間已可被重用。如果,你真的想要進(jìn)行日志收縮,可以在這步之后進(jìn)行。則OS可以回收從最后一個(gè)0到最近一個(gè)2行的空間。(當(dāng)前的Status=2的行標(biāo)識(shí)當(dāng)前的Log記錄位置)

?

?

總結(jié)

其實(shí)如果有人問(wèn)我20GB的Transaction Log大不大。其實(shí)這個(gè)問(wèn)題只是個(gè)相對(duì)概念。理論上只要你有足夠的磁盤空間,日志文件可以足夠大。如果你有個(gè)400GB的數(shù)據(jù)庫(kù),20GB的日志文件也在合理的范疇。如果你的數(shù)據(jù)庫(kù)只有5GB,那么你的應(yīng)用程序?qū)τ赥ransaction的使用和日志的維護(hù)一定是有問(wèn)題了。

簡(jiǎn)介數(shù)據(jù)庫(kù)日志文件的增長(zhǎng)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。。?/p>

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 天峻县| 乌拉特前旗| 彰化县| 海门市| 伊川县| 万州区| 开远市| 全南县| 荆州市| 嘉鱼县| 遂平县| 兰州市| 定日县| 阆中市| 长顺县| 淮滨县| 门源| 册亨县| 兰考县| 武安市| 班戈县| 靖江市| 博客| 安徽省| 揭阳市| 大安市| 海阳市| 伊宁县| 金溪县| 新津县| 阿坝| 大同市| 临泉县| 延津县| 札达县| 黄梅县| 卢湾区| 文安县| 米易县| 通化市| 怀来县|