解決簡單恢復模式下產生的日誌增加

簡介程序員

  最近測試服務器進行數據歸檔,其間程序員發現一個問題,空間不足,我查看緣由發現日誌文件暴漲。而後將數據庫改成簡單恢復模式,可是依然存在這個問題。通過查詢資料發現了日誌文件在簡單模式下依然增長的緣由。sql

Simple概念數據庫

  Simple恢復模式也叫作」Checkpoint with truncate log「,其實這個名字更形象,在Simple模式下,SQL Server會在每次checkpoint或backup以後自動截斷log,也就是丟棄全部的閒置日誌記錄,僅保留用於實例啓動時自動發生的instance recovery所需的少許log,這樣作的好處是log文件很是小,不須要DBA去維護、備份log,但壞處也是顯而易見的,就是一旦數據庫出現異常,須要恢復時,最多隻能恢復到上一次的備份,沒法恢復到最近可用狀態,由於log丟失了。緩存

Checkpoint服務器

  CheckPoint和lazyWriter同樣,都會將緩衝區內臟數據寫入到磁盤,同時在簡單恢復模式下截斷日誌;lazyWriter緩存不足的時候會觸發執行,這裏咱們暫且不作討論。性能

針對CheckPoint我請教了Careyson之後總結出如下幾個觸發其執行的緣由:測試

  1. 一些Internal CheckPoint時,好比說關閉數據庫實例等。
  2. 數據庫完整備份或差別備份(日誌備份不會觸發checkpoint)。
  3. 數據庫恢復模式爲簡單恢復模式下當日志文件使用超過70%時。
  4. CheckPoint執行的時間間隔閾值被足夠多的日誌記錄超過。
  5. 手動執行CheckPoint。

場景描述:this

  Simple模式主要用於非critical的業務,好比開發庫和測試庫,那麼此次因爲測試環境的磁盤緊張咱們也都採用了簡單模式。可是數據歸檔發生時依然產生了大量的日誌,而且增長了磁盤佔用,這又是什麼緣由那?由於咱們在歸檔處理中使用了大量的insert和delete以及update操做,這樣話,短期內產生了大量的日誌,這個時候日誌迅速增長;又由於在SQL Server中,CheckPoint是一個完整的過程,這個過程的耗時取決於髒數據的大小。一旦在很短期內,日誌的CheckPoint沒完成的時候日誌增長超過了日誌的規定上限。則將產生更多的日誌。spa

  如上所述,產生這個問題的緣由就是:CheckPoint時間間隔閾值被足夠多的日誌記錄超過,觸發CheckPoint才寫入磁盤。日誌

  下面這個實例來自於:

      http://sqlblog.com/blogs/linchi_shea/archive/2009/04/12/a-race-condition-in-the-simple-recovery-mode-why-is-my-log-autogrowing.aspx

    讓咱們用一個腳原本實際的闡明這種行爲。首先在一個測試數據庫中運行一下腳本建立一個測試表並填充一些數據。

  測試數據庫設置:

  1.設置爲簡單的恢復模式。

  2.日誌的大小爲100M。

  3.日誌文件的自動增加被禁用(由於觀察日誌空間被用完的錯誤比檢查自動增加要容易)。

複製代碼
--建立表並初始化數據
create table test(i int, c char(1000))
go
declare @i int 
set @i = 1
while @i < 10000     --插入9999條測試數據
begin          
  insert test values(@i'abc')          
  set @i = @i + 1      
end
複製代碼

   運行如下腳本,觀察資源競爭:

複製代碼
set nocount on go
declare @change_size int
set @change_size = 100 -- 根據須要來調整這個值
declare @i int
set @i = 1
while @i < 100      
begin           
if @i % 2 = 0             
   update test set c = replicate('a'@change_size)            
else               
  update test set c = replicate('b'@change_size)                       
select @i = @i + 1       
end
複製代碼

 反覆根據修改@change_size來看結果,當我將@change_size改成120甚至更大時,獲得了9002的錯誤信息,很是準確的告訴我數據庫的事務日誌已滿。

經過上面這個引用的例子,很好地再現了問題的產生機制,那麼咱們怎麼處理這個狀況那?

解決

  方案1:

  強制執行CheckPoint。可是執行後有個很很差的影響,嚴重影響了存儲過程的執行時間。由此可知這樣作很消耗性能啊。

  方案2:

  縮短CheckPoint時間間隔閾值。

 默認值是0,意味着由SQL Server來管理這個回覆間隔。   

 也能夠SQL語句實現這個功能:

  方案3:

  增大日誌文件大小。

總結:

  日誌文件是一個雙刃劍,WAL機制很好的保證了數據的一致性和維護性。可是也產生了額外的性能和維護的成本的上升。須要咱們根據實際狀況去處理這些不一樣的情景。須要注意的是在TempDB中是不會產生日誌的,除非手動執行。除此以外,並不是全部的時間間隔後都會產生日誌,由於當數據不多的時候有可能不觸發Checkpoint執行。

相關文章
相關標籤/搜索