淺談SQL Server中的事務日志(二)----事務日志在修改數據時的角色


    本篇文章是系列文章中的第二篇,以防你還沒有看過第一篇.上一篇的文章地址如下:

    淺談SQL Server中的事務日志(一)----事務日志的物理和邏輯構架

 

簡介

    每一個SQL Server的數據庫都會按照其修改數據(insert,update,delete)的順序將對應的日志記錄到日志文件.SQL Server使用了Write-Ahead logging技術來保證了事務日志的原子性和持久性.而這項技術不僅僅保證了ACID中的原子性(A)和持久性(D),還大大減少了IO操作,把對數據的修改提交到磁盤的工作交給lazy-writer和checkpoint.本文主要講述了SQL Server修改數據時的過程以及相關的技術。

 

預寫式日志(Write-Ahead Logging (WAL))

    SQL Server使用了WAL來確保了事務的原子性和持久性.實際上,不光是SQL Server,基本上主流的關系數據庫包括oracle,mysql,db2都使用了WAL技術.

    WAL的核心思想是:在數據寫入到數據庫之前,先寫入到日志.

    因為對於數據的每筆修改都記錄在日志中,所以將對於數據的修改實時寫入到磁盤並沒有太大意義,即使當SQL Server發生意外崩潰時,在恢復(recovery)過程中那些不該寫入已經寫入到磁盤的數據會被回滾(RollBack),而那些應該寫入磁盤卻沒有寫入的數據會被重做(Redo)。從而保證了持久性(Durability)

    但WAL不僅僅是保證了原子性和持久性。還會提高性能.

    硬盤是通過旋轉來讀取數據,通過WAL技術,每次提交的修改數據的事務並不會馬上反映到數據庫中,而是先記錄到日志.在隨后的CheckPoint和lazy Writer中一並提交,如果沒有WAL技術則需要每次提交數據時寫入數據庫:

    1

       而使用WAL合並寫入,會大大減少磁盤IO:

      2

     也許你會有疑問,那每次對於修改的數據還是會寫入日志文件.同樣消耗磁盤IO。上篇文章講過,每一筆寫入日志的記錄都是按照先后順序,給定順序編號的LSN進行寫入的,日志只會寫入到日志文件的邏輯末端。而不像數據那樣,可能會寫到磁盤的各個地方.所以,寫入日志的開銷會比寫入數據的開銷小很多。

   

SQL Server修改數據的步驟

     SQL Server對於數據的修改,會分為以下幾個步驟順序執行:

     1.在SQL Server的緩沖區的日志中寫入”Begin Tran”記錄

     2.在SQL Server的緩沖區的日志頁寫入要修改的信息

     3.在SQL Server的緩沖區將要修改的數據寫入數據頁

     4.在SQL Server的緩沖區的日志中寫入”Commit”記錄

     5.將緩沖區的日志寫入日志文件

     6.發送確認信息(ACK)到客戶端(SMSS,ODBC等)

  

     可以看到,事務日志並不是一步步寫入磁盤.而是首先寫入緩沖區后,一次性寫入日志到磁盤.這樣既能在日志寫入磁盤這塊減少IO,還能保證日志LSN的順序.

     上面的步驟可以看出,即使事務已經到了Commit階段,也僅僅只是把緩沖區的日志頁寫入日志,並沒有把數據寫入數據庫.那將要修改的數據頁寫入數據庫是在何時發生的呢?

 

Lazy Writer和CheckPoint

    上面提到,SQL Server修改數據的步驟中並沒有包含將數據實際寫入到磁盤的過程.實際上,將緩沖區內的頁寫入到磁盤是通過兩個過程中的一個實現:

     這兩個過程分別為:

     1.CheckPoint

     2.Lazy Writer

    任何在緩沖區被修改的頁都會被標記為“臟”頁。將這個臟頁寫入到數據磁盤就是CheckPoint或者Lazy Writer的工作.

    當事務遇到Commit時,僅僅是將緩沖區的所有日志頁寫入磁盤中的日志文件:

    3

 

     而直到Lazy Writer或CheckPoint時,才真正將緩沖區的數據頁寫入磁盤文件:

    4

   

    前面說過,日志文件中的LSN號是可以比較的,如果LSN2>LSN1,則說明LSN2的發生時間晚於LSN1的發生時間。CheckPoint或Lazy Writer通過將日志文件末尾的LSN號和緩沖區中數據文件的LSN進行對比,只有緩沖區內LSN號小於日志文件末尾的LSN號的數據才會被寫入到磁盤中的數據庫。因此確保了WAL(在數據寫入到數據庫之前,先寫入日志)。

 

Lazy Writer和CheckPoint的區別

    Lazy Writer和CheckPoint往往容易混淆。因為Lazy Writer和CheckPoint都是將緩沖區內的“臟”頁寫入到磁盤文件當中。但這也僅僅是他們唯一的相同點了。

    Lazy Writer存在的目的是對緩沖區進行管理。當緩沖區達到某一臨界值時,Lazy Writer會將緩沖區內的臟頁存入磁盤文件中,而將未修改的頁釋放並回收資源。

    而CheckPoint存在的意義是減少服務器的恢復時間(Recovery Time).CheckPoint就像他的名字指示的那樣,是一個存檔點.CheckPoint會定期發生.來將緩沖區內的“臟”頁寫入磁盤。但不像Lazy Writer,Checkpoint對SQL Server的內存管理毫無興趣。所以CheckPoint也就意味着在這個點之前的所有修改都已經保存到了磁盤.這里要注意的是:CheckPoint會將所有緩沖區的臟頁寫入磁盤,不管臟頁中的數據是否已經Commit。這意味着有可能已經寫入磁盤的“臟頁”會在之后回滾(RollBack).不過不用擔心,如果數據回滾,SQL Server會將緩沖區內的頁再次修改,並寫入磁盤。

    通過CheckPoint的運作機制可以看出,CheckPoint的間歇(Recovery Interval)長短有可能會對性能產生影響。這個CheckPoint的間歇是一個服務器級別的參數。可以通過sp_config進行配置,也可以在SSMS中進行配置:

    5

    恢復間歇的默認參數是0,意味着由SQL Server來管理這個回復間隔。而自己設置恢復間隔也是需要根據具體情況來進行界定。更短的恢復間歇意味這更短的恢復時間和更多的磁盤IO,而更長的恢復間歇則帶來更少的磁盤IO占用和更長的恢復時間.

    除了自動CheckPoint之外,CheckPoint還會發生在Alter DataBase以及關閉SQL Server服務器時。sysadmin和db_backupoperator組的成員以及db_owner也可以使用CheckPoint指令來手動保存CheckPoint:

    6

    通過指定CheckPoint后的參數,SQL Server會按照這個時間來完成CheckPoint過程,如果時間指定的短,則SQL Server會使用更多的資源優先完成CheckPoint過程。

    通常情況下,將“臟”頁寫入磁盤的工作,Lazy Writer要做的比CheckPoint會多出許多。

 

總結

    本文簡單介紹了WAL的概念和修改數據庫對象時,日志所扮演的角色。還分別介紹了CheckPoint和Lazy Writer,對於這些概念的理解是理解SQL Server DBA工作的基礎。下篇文章將會講述在簡單恢復模式下日志的機制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM