轉發來源:
https://www.jianshu.com/p/a37ceed648a8
https://www.cnblogs.com/daduxiong/archive/2010/09/30/1839533.html
WAL:Write-Ahead Logging
為什么進入WAL?
持久性是指,事務提交后,對系統的影響必須是永久的,即使系統意外宕機,也必須確保事務提交時的修改已真正永久寫入到永久存儲中。最簡單的實現方法,當然是在事務提交后立即刷新事務修改后的數據到磁盤。但是磁盤和內存之間的IO操作是最影響數據庫系統影響時間的,一有事務提交就去刷新磁盤,會對數據庫性能產生不好影響。
WAL機制的引入,即保證了事務持久性和數據完整性,又盡量地避免了頻繁IO對性能的影響。
WAL的概念就是對數據文件的改變(包括表和索引)必須先寫入日志,即日志記錄刷新到永久儲存之后,才能被寫。遵循這個過程,就不需要在每個事務提交時都刷新數據頁到磁盤,因為在宕機時可以用日志來恢復數據庫:任何沒有應用到數據頁上的改動都可以根據日志記錄重做。
WAL如何工作?
WAL機制實際是在這個寫數據的過程中加入了對應的寫WAL log的過程,步驟一樣是先到Buffer,再刷新到Disk。
Change發生時:
- 先將變更后內容記入WAL Buffer
- 再將更新后的數據寫入Data Buffer
Commit發生時:
- WAL Buffer刷新到Disk
- Data Buffer寫磁盤推遲
Checkpoint發生時:
- 將所有Data Buffer刷新到磁盤
Change時:
Commit和Checkpoint時
WAL的好處?
使用WAL可以顯著地減少寫磁盤的次數,因為只需要把日志文件刷新到磁盤就可以保證事務被提交,而不需要把事務改動過的每一個數據文件都刷新到磁盤。日志文件是連續寫的,所以同步log的花銷遠小於刷新數據頁的花銷。特別是服務器要處理涉及數據存儲不同部分的大量小事務時更是這樣。另外,當服務器在處理大量並行小事務時,log文件一次fsync就可以提交多個事務。
WAL還使得在線備份和時間點恢復成為可能。通過歸檔WAL數據,我們可以恢復到WAL數據覆蓋范圍內的任何時間點:只需install一份數據庫的物理備份,並恢復WAL日志到所需時間即可。更重要的是,這個物理備份並不必須是一個數據庫狀態的瞬時快照—如果一段時間的快照,那把WAL日志也恢復成那一段時間的即可。
WAL的配置參數:
- fsync:該參數直接控制日志是否先寫入磁盤。默認值是ON(先寫入)。開啟該值時表明,更新數據寫入磁盤時系統必須等待WAL的寫入完成。可以配置該參數為OFF,更新數據寫入磁盤完全不用等待WAL的寫入完成,沒有了等待的時間,顯然接下來的工作能夠更早的去做,節省了時間,提高了性能。其直接隱患是無法保證在系統崩潰時最近的事務能夠得到恢復,也就無法保證相關數據的真實與正確性。
- synchronous_commit:參數表明是否等待WAL完成后才返回給用戶事務的狀態信息。默認值是ON,表明必須等待WAL完成后才返回事務狀態信息。配置OFF值能夠更快的反饋回事務狀態。因參數只是控制事務的狀態反饋,因此對於數據的一致性不存在風險。但事務的狀態信息影響着數據庫的整個狀態。該參數可以靈活的配置,對於業務沒有嚴謹要求的事務可以配置為OFF,能夠為系統的性能帶來不小的提升。
- wal_sync_method:WAL寫入磁盤的控制方式,默認值是fsync。可選用值:open_datasync,fdatasync,fsync_writethrough,fsync,open_sync。
- full_page_writes:表明是否將整個page寫入WAL。
- wal_buffers:用於存放WAL數據的內存空間。系統默認值是64K,執行一個大的事務肯定受到影響,應該適當的增大該參數。類似oracle中的log buffer。該參數還受以下幾個參數影響。
- wal_writer_delay:WAL writer進程的間歇時間。默認值是200ms。准確的配置應該根據自身系統的運行狀況。如果時間過長可能造成WAL buffer的內存不足;反之過小將會引起WAL的不斷的寫入,對磁盤的IO也是很大考驗。
- commit_delay:表示了一個已經提交的數據在WAL buffer中存放的時間,單位ms,默認值是0,不用延遲。非0值表示可能存在多個事務的WAL同時寫入磁盤。如果設置為非0,表明了某個事務執行commit后不會立即寫入WAL中,而仍存放在WAL buffer中,這樣對於后面的事務申請WAL buffer時非常不利,尤其是提交事務較多的高峰期,可能引起WAL buffer內存不足。如果內存足夠大,可以盡量延長該參數值,能夠使數據集中寫入這樣降低了系統的IO,提高了性能。同樣如果此時崩潰數據面臨着丟失的危險。個人建議采用默認值,同時將WAL文件存放在IO性能好的磁盤上。
- commit_siblings:該參數非常有意思,該參數還決定了commit_delay的有效性。系統默認值是5。表示當一個事務發出提交請求,此時數據庫中正在執行的事務數量大於5,則該事務將等待一段時間(commit_delay的值),反之,該事務則直接寫入WAL。