有關CheckPoint的概念對大多數SQL Server開發或DBA人員都不陌生。但是包括我自己在內,大家對于CheckPoint都或多或少存在某些誤區,最近和高文佳同學(感謝高同學的探討)關于該處進行過一些探討,整理出來幾個誤區。
1.CheckPoint實例級別,而不是數據庫級別
CheckPoint的時間雖然可以在實例級別進行設置,但CheckPoint的過程是以數據庫為粒度。從CheckPoint在Redo和Undo的作用來看,CheckPoint是為了優化IO和減少Recovery時間,而Recovery是需要日志支持,因此日志是數據庫級別的概念,因此可以知道CheckPoint是以數據庫為單位進行的。
我們來做一個簡單的實驗,分別設置兩個連接A和B,A和B使用不同的數據庫并修改數據產生臟數據,在A上進行了CheckPoint后,A連接的數據庫臟頁全部寫入磁盤,而B連接產生的臟頁依然駐留在Buffer中,因此可以確定CheckPoint是數據庫級別而不是服務器級別。
圖1.CheckPoint是數據庫級別的
2.由于日志增長導致的自動CheckPoint會將所有數據庫的臟頁寫入磁盤
事實證明,這也是錯誤的,自動CheckPoint僅僅會將某些臟頁或日志過多的數據庫臟頁寫入磁盤。可以同樣通過圖1的例子進行。
3.CheckPoint僅僅將已經提交的臟數據寫入磁盤
這同樣是錯誤的,無論事務是否提交,所產生的臟數據都會被CheckPoint寫入磁盤。例證可以參看我的博文:再談SQL Server中日志的的作用中有關CheckPoint的實驗。
4.如果一個實例上有多個數據庫,則CheckPoint是并行的
錯誤,通過3502跟蹤標記來看,CheckPoint是串行的,也就是一個數據庫CheckPoint完了才會繼續下一個。如圖2所示。
圖2.串行CheckPoint
我們可以注意到,CheckPoint使用的是同一個Spid。
5.將恢復間隔設置為1分鐘,意味著每1分鐘會對所有的數據庫做一次CheckPoint
錯誤。將恢復間隔設置為1分鐘不能想成建立一個Agent,每分鐘寫一個CheckPoint命令,這是兩碼事。這只是意味著每分鐘去檢查一次是否需要做CheckPoint,如果期間積累的日志量足夠,才會對積累足夠日志量的數據庫去做CheckPoint。即使中間積累了巨量的日志,不到1分鐘也不會做CheckPoint。
6.SQL Server一些Internal CheckPoint時,比如說關閉數據庫,會對所有數據庫做CheckPoint(高同學補充)
這條是正確的,因為SQL Server此時需要保證所有的數據寫入磁盤,從而保證了數據庫一致性,如果沒有活動的事務,那么這種關閉方式叫做Clean ShutDown,這意味著該數據本身一致,因此即使沒有日志,MDF也可以附加。
7.CheckPoint是一個時間點(高同學補充)
錯誤,這是打游戲存檔的想法,從哪存進度,從哪取進度,是某個時間點。在SQL Server中,CheckPoint是一個完整的過程,這個過程的耗時取決于臟數據的大小,更多資料,請參閱MSDN:http://technet.microsoft.com/zh-cn/library/ms188748.aspx
8.引發自動CheckPoint的條件是內存中臟頁的多少(高同學補充)
錯誤,CheckPoint的觸發條件,是在CheckPoint期間生成日志的大小。因此,大家見過內存中有很多臟頁,卻不引發CheckPoint的情況。
9.當數據所在磁盤壓力大時,通過checkpoint pages/ sec 計數器來觀察寫入磁盤的臟頁(高同學補充)
部分正確。實際上,臟頁被寫入磁盤一共有3中方式,CheckPoint僅僅是其中一種,我們還需要將Lazy writes/sec考慮在內。
10.TempDB上永遠不會寫入臟頁
錯誤。TempdB是一個特殊的數據庫,永遠只能簡單恢復模式,如果您在TempDB上造成大量臟頁,自動CheckPoint時會發現的確不會有任何臟頁寫入操作,但手動CheckPoint時,臟頁依然會被寫入磁盤。
最后,再次感謝高文佳同學和我探討。
文章列表