在生活中,你必定有過相似這樣的經歷:web
好比部門發禮品、或者說學校發課本。若是在發放的時候,你們一窩蜂的涌了過來,畢竟雙拳雙敵四手,漸漸你就招架不過來。sql
爲了工做更好作,你會有幾個選擇,提早打印個名單,一個個來領,領的人在名單上打勾,東西拿走。或者你們都來拿,你看一眼,記在腦海裏,但可能中途打個岔就記錯了。也能夠記住是誰,找個紙記下來,每次記一下或者隔一會記幾下。數據庫
對比上面的場景,你沒有發現,不一樣的方式,效率上也存在的差異。好比在名單上找到打勾,那就會徹底串行,每一個人來都得在定位到本身那條信息上,找的過程費時間。tomcat
找一張紙,每隔一段時間記一次,這樣效率也還挺高,問題就在於別人打岔的頻率。安全
在計算機科學領域也存在這樣的時候,好比咱們經常使用的數據庫系統裏。數據庫爲了避免喝娃哈哈AD鈣奶,就能保證ACID中的A和D,使用了一種被稱作「WAL」的機制。全稱是write-ahead logging。數據庫中全部的變動,會先寫到日誌裏,最後纔會寫到持久存儲的數據文件中。像MySQL 裏的 redo log 和undo log 就是這種機制。微信
像你在紙上記錄同樣,一直不停的向後寫,順序寫,速度就會快,時不時的回過頭去檢查一下,改一下速度就降下來了。app
若是大量記錄到白紙上的內容,沒有及時的彙總記錄到一個表格上,那等最後所有彙總也比較費力氣。就像數據庫裏一直寫WAL以後就應用到內存數據修改,速度很快,但若是出現故障的時候,就須要從新回放大量的redo log,恢復時間也沒法接受。編輯器
就像行政急着要結果的時候,你纔開始「回放」白紙上的內容,就會慢不少。若是是在發放的過程當中,能夠過一段時間彙總一下,而後在白紙上加個「標記」,用於一會提示本身上次算到什麼位置了。這種就是數據庫裏的 checkpoint,下次恢復的時候,就直接從checkpoint 開始向後恢復就行,前面的已經持久化到了磁盤,不用再費事了。ui
此外,計算機裏,許多時候,都是一個根據本身的場景權衡的過程。好比對於使用WAL的時候,MySQL 提供了不一樣的配置來支持什麼時機,多長時間將 log 應用到數據文件,畢竟log 寫到磁盤也仍是要花點兒時間的。每次都刷盤,會影響效率,但間隔時間太長,就會在機器故障的時候丟失數據。url
MySQL 默認將log 刷到磁盤的時機有三個:
提交一個事務的時候
固定大小的 log buffer 滿了的時候
不管 log buffer 是否滿,每秒會刷一次
redo log 寫磁盤的過程
redo log buffer和page cache都是在內存中,因此寫入這二者都比較快,而fsync則須要消耗磁盤IO。Mysql的後臺每隔1秒也會自動將redo log buffer中的內容刷到磁盤中去。
借用MySQL 官方博客的幾張圖來講明下
那有了redo log,就保證了故障時安全了嗎?是的。
機器在故障的時候,內存中包含數據的內容,也就是所謂的「髒頁」通常就會丟了,怎麼樣恢復丟失的數據呢?我們前面看到,redo log 先刷盤,以後真正的數據庫變動才刷盤,因此咱們丟失的數據已經保存在磁盤中的redo log裏了。重放redolog 就能夠。但這裏有例外的狀況是MySQL 裏包含一個 innodb_flush_log_at_trx_commit 的配置,默認是1,即嚴格的D,非1的狀況下會丟失redo log buffer和page cache中的數據。
上次送書,除了留言點贊獲獎的讀者外,分別根據助手APP裏提示【分享最多】和【閱讀最多】各取第一名,對於和留言獲獎者重複的,順延一位。
請【無意看劇】和【陳良良】兩位讀者看到後後臺聯系我,提供快遞收貨信息。
相關閱讀
Java七武器系列長生劍 -- Java虛擬機的顯微鏡 Serviceability Agent
嵌套事務、掛起事務,Spring 是怎樣給事務又實現傳播特性的?
源碼|實戰|成長|職場
這裏是「Tomcat那些事兒」
請留下你的足跡
咱們一塊兒「終身成長」
本文分享自微信公衆號 - Tomcat那些事兒(tomcat0000)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。