MySQL中的三大日志用法及分析
MySQL中三大日志用法
- undolog日志是inndb存儲引擎層生成的日志,實現(xiàn)了事務(wù)的原子性,主要用于事務(wù)回滾和MVCC。
- redolog日志是inndb存儲引擎層生成的日志,實現(xiàn)了事務(wù)的持久性,主要用于掉電等故障恢復(fù)。
- binlog日志是Server層生成的日志,主要用于數(shù)據(jù)備份和主從復(fù)制。
undolog回滾日志
undolog是如何實現(xiàn)事務(wù)回滾和MVCC?
三個隱藏字段:事務(wù)id、回滾指針、主鍵(如果我們在表中沒有指定主鍵,則會創(chuàng)建一個默認(rèn)的隱藏主鍵row_id,如果表中有主鍵,則不會創(chuàng)建)。
在我們開啟事務(wù)后,執(zhí)行事務(wù)的過程中,如果我們對數(shù)據(jù)進(jìn)行增刪改操作,會先記錄undolog日志,記錄數(shù)據(jù)變更之前的信息,然后更新數(shù)據(jù)庫中的記錄,并且記錄本次操作的事務(wù)ID、回滾指針。通過回滾指針,我們可以構(gòu)建出每條記錄的版本鏈,即數(shù)據(jù)庫中每一條記錄的歷史版本信息。
通過構(gòu)建的版本鏈,如果我們在執(zhí)行事務(wù)的過程中發(fā)生了異常,這時候就會根據(jù)版本鏈的信息將每條記錄中回滾到舊值。

MVCC的實現(xiàn)是利用版本鏈和開啟ReadView快照讀時記錄的信息,根據(jù)一定的規(guī)則去判斷修改記錄的事務(wù)是否已經(jīng)提交。如果提交了,在讀已提交的隔離級別下就可以讀取到已提交事務(wù)的信息了;如果在可重復(fù)讀隔離級別下,則會在后續(xù)的ReadView中復(fù)用之前的視圖,只能看到第一次創(chuàng)建ReadView時候的數(shù)據(jù)信息。
redolog重做日志
為什么需要redolog,解決了什么問題?
我們做數(shù)據(jù)的增刪改操作時,并不是直接將數(shù)據(jù)寫入到磁盤中,而是先將數(shù)據(jù)寫入到Buffer Pool緩存中。如果我們每次將數(shù)據(jù)都寫入到磁盤,將會導(dǎo)致磁盤I/O頻繁,內(nèi)存開銷大。
有了Buffer Pool之后,我們的具體操作流程為:
- 讀取數(shù)據(jù)時,如果數(shù)據(jù)存在于Buffer Pool中,客戶端直接讀取Buffer Pool中的數(shù)據(jù),否則再去磁盤中讀取。
- 當(dāng)修改數(shù)據(jù)時,如果數(shù)據(jù)存在于Buffer Pool當(dāng)中,那直接修改Buffer Pool所在的頁,然后將其頁設(shè)置為臟頁(該頁內(nèi)存數(shù)據(jù)和磁盤數(shù)據(jù)已經(jīng)不一致了),為了減少磁盤I/O,不會立即將臟頁寫入到磁盤,后續(xù)由后臺線程在一個合適的時機(jī)將臟頁寫入磁盤。
引入Buffer Pool做數(shù)據(jù)緩存解決了頻繁讀寫I/O的問題,但是又導(dǎo)致了緩存中的數(shù)據(jù)和磁盤中的數(shù)據(jù)存在不一致的問題。即我們更新完緩存中的數(shù)據(jù),這時候還沒來得及更新磁盤中的數(shù)據(jù),mysql發(fā)生故障,導(dǎo)致緩存中的數(shù)據(jù)丟失,數(shù)據(jù)持久化失敗。
為了解決這個問題,MySQL在Innodb存儲引擎層引入了redolog日志。這時候,當(dāng)有一條數(shù)據(jù)更新的時候,InnoDB引擎就會先更新內(nèi)存(同時標(biāo)記為臟頁),然后將本次對這個頁的修改以redo log的形式記錄下來,這時候更新就算完成了。后續(xù)InnoDB存儲引擎會在后臺啟動一個線程,將redolog中的記錄寫入到磁盤中,并將binlog中已經(jīng)寫入磁盤的內(nèi)容清空,這時候更新操作最終完成。
有的同學(xué)可能會有疑問?我將更新的操作寫入到redolog中也是做磁盤的IO操作,為什么不直接將數(shù)據(jù)寫入到數(shù)據(jù)庫中呢?先寫入到redolog中,再寫入到數(shù)據(jù)庫中不是更加浪費(fèi)開銷嗎?
要解答這個問題,首先我們需要先了解一下常見的兩種寫入磁盤的方式:
- 順序?qū)懭?/strong>:我們向磁盤中寫入數(shù)據(jù)遵循一定的規(guī)則,比如從頭到尾。
- 隨機(jī)寫入:我們向磁盤中寫入數(shù)據(jù)是隨機(jī)的,一會寫到這里,一會寫到那里。
打個比方:就像我們寫作業(yè)一樣,順序?qū)懭胧菑牡谝豁搶懙阶詈笠豁?;而隨機(jī)寫入則是我們一會寫到第一頁,一會寫到第五頁。我們進(jìn)行順序?qū)懭胧遣僮鞅入S機(jī)寫入的操作要快很多,這也是MySQL為什么引入redolog的另一個目的。
redolog的兩大作用:
- 將臟頁數(shù)據(jù)保存下來,實現(xiàn)事務(wù)的持久化。
- 提高讀寫效率,將MySQL的隨機(jī)寫入轉(zhuǎn)變?yōu)轫樞驅(qū)懭搿?/li>
什么時候持久化:
- 后臺的進(jìn)程會每隔一秒將redolog中的日志寫入到磁盤中。
- 即使目前事務(wù)還沒有提交,如果沒有提交,會在mysql異常重啟之后進(jìn)行回滾操作。
binlog記錄日志
我們前面介紹的undolog和redolog都是InnDB存儲引擎層生成的日志。
MySQL在完成一條更新操作后,Server層還會生成一條binlog,等之后事務(wù)提交的時候,會將該事務(wù)執(zhí)行過程中產(chǎn)生的所有binlog統(tǒng)一寫入binlog文件。
binlog文件記錄了所有的數(shù)據(jù)庫表結(jié)構(gòu)變更和表數(shù)據(jù)修改的日志,不會記錄查詢類的操作,比如SELECT、SHOW操作。
為什么要有binlog日志,binlog和redolog的區(qū)別是什么?
我們先來談一談為什么要有binlog日志?
如果我們的數(shù)據(jù)庫是因為磁盤故障或者損壞引起的,這時候可能發(fā)生數(shù)據(jù)丟失。在這種情況下,數(shù)據(jù)庫可能無法正常啟動或者無法讀取先前持久化的數(shù)據(jù)。如果數(shù)據(jù)庫中存儲了重要的數(shù)據(jù),必須進(jìn)行恢復(fù),這時候通過undolog和redolog都是沒有辦法恢復(fù)的。undolog記錄的是當(dāng)前事務(wù)的執(zhí)行語句的相反操作,只能用于事務(wù)的回滾。redolog僅僅記錄的是內(nèi)存中已經(jīng)更改的數(shù)據(jù)但是磁盤上未進(jìn)行更改的數(shù)據(jù),隨著redolog刷盤條件的達(dá)成,redolog中的記錄會刪除,也就是說,通過redolog只能夠恢復(fù)部分?jǐn)?shù)據(jù),僅為redolog記錄的僅僅是一定范圍內(nèi)的數(shù)據(jù),有限。
這時候,我們就想,如果能夠一個日志系統(tǒng),能夠?qū)?shù)據(jù)庫的所有DML語句都記錄下來,并且不斷地堆積,那該多好啊!這就是MySQL中binlog的作用,用于做數(shù)據(jù)備份和數(shù)據(jù)的恢復(fù)。
除了數(shù)據(jù)備份和恢復(fù)外,binlog還用于實現(xiàn)主從復(fù)制。因為binlog中記錄的所有DML語句,如果想要在另一個服務(wù)器上復(fù)制這一個表,只需要將binlog文件在想要復(fù)制的服務(wù)器上重新執(zhí)行一遍即可。
binlog只有在事務(wù)提交的時候,才會將binlog日志持久化到本地。
總結(jié)
MySQL當(dāng)中的三大日志,作用不同,互為補(bǔ)充,提高了數(shù)據(jù)存儲的安全性和一致性。
其中,undolog和redolog用于實現(xiàn)InnoDB存儲引擎中事務(wù)四大特性的原子性和持久性,保證小范圍內(nèi)的數(shù)據(jù)一致性。binlog用于實現(xiàn)數(shù)據(jù)庫的全量備份,為數(shù)據(jù)恢復(fù)提供了一種重要的方式,值得注意的是,如果我們想要通過binlog恢復(fù)數(shù)據(jù)庫中的所有信息,就需要定期的進(jìn)行數(shù)據(jù)備份。因為 mysql僅會保證一定數(shù)量的數(shù)據(jù)文件,如果超過了該數(shù)量會將舊值刪除。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Mysql連接數(shù)據(jù)庫時host和user的匹配規(guī)則
這篇文章主要介紹了淺談Mysql連接數(shù)據(jù)庫時host和user的匹配規(guī)則,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
mysql數(shù)據(jù)庫日志binlog保存時效問題(expire_logs_days)
這篇文章主要介紹了mysql數(shù)據(jù)庫日志binlog保存時效問題(expire_logs_days),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
在IDEA的maven項目中連接并使用MySQL8.0的方法教程
這篇文章主要介紹了如何在IDEA的maven項目中連接并使用MySQL8.0,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02
MYSQL突破secure_file_priv寫shell問題
這篇文章主要介紹了MYSQL突破secure_file_priv寫shell問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01

