深入理解MySQL重做日志 redo log
在事務(wù)的ACID特性中,原子性(A)、一致性(C)、持久性(D)由undo log和redo log實(shí)現(xiàn),隔離性(I)由鎖+MVCC實(shí)現(xiàn)
undo log:事務(wù)還沒有commit,中途執(zhí)行異常,可以使用undo log把數(shù)據(jù)恢復(fù)到事務(wù)執(zhí)行前的狀態(tài),確保事務(wù)的原子性
redo log:事務(wù)commit成功,由于更新磁盤數(shù)據(jù)需要一段時(shí)間,此時(shí)若發(fā)生異常,可以使用redo log重新執(zhí)行這一事務(wù)的SQL,確保事務(wù)的持久性(只要事務(wù)commit成功,不管發(fā)生什么異常事件,只要下一次MySQL服務(wù)正常進(jìn)行,那上一次commit的數(shù)據(jù)一定要恢復(fù)回來)
一、redo log概念
redo log:被稱為物理日志,記錄的就是最終修改后的按頁面存儲(chǔ)的數(shù)據(jù)頁,直接存數(shù)據(jù)最終的狀態(tài),用于確保事務(wù)的持久性
undo log:被稱為邏輯日志,存儲(chǔ)的是具體的相應(yīng)的SQL語句。如果現(xiàn)在執(zhí)行的是insert,回滾的時(shí)候就執(zhí)行delete;如果現(xiàn)在執(zhí)行的update,就把原來的舊值再update回來
redo log默認(rèn)放在/var/lib/mysql
下
redo log是在事務(wù)begin時(shí)就開始記錄(并不是事務(wù)commit時(shí)才記錄,因?yàn)檎麄€(gè)事務(wù)做的操作可能很多,如果在commit的時(shí)候才寫redo log,此時(shí)一旦發(fā)生異常,redo log還沒寫,這就太晚了,無法確保事務(wù)的持久性),不管事務(wù)是否提交都會(huì)記錄下來,在異常發(fā)生時(shí)(如數(shù)據(jù)持久化過程中掉電),InnoDB會(huì)使用redo log恢復(fù)到掉電前的時(shí)刻,保證數(shù)據(jù)的完整性
innodb_log_buffer_size默認(rèn)是16M,就是redo log緩沖區(qū)的大小,它隨著事務(wù)開始,就開始寫redo log,如果事務(wù)比較大,為了避免事務(wù)執(zhí)行過程中花費(fèi)過多磁盤IO,可以設(shè)置比較大的redo log緩存,節(jié)省磁盤IO。往磁盤上刷是有刷新的時(shí)機(jī),達(dá)到時(shí)機(jī)就花費(fèi)磁盤IO,如果buffer比較大,會(huì)更慢的達(dá)到刷新的時(shí)機(jī),效率更高。
InnoDB修改操作數(shù)據(jù),不是直接修改磁盤上的數(shù)據(jù),實(shí)際只是修改Buffer Pool中的數(shù)據(jù)。InnoDB總是先把Buffer Pool中的數(shù)據(jù)改變記錄到redo log中,用來進(jìn)行崩潰后的數(shù)據(jù)恢復(fù)。 優(yōu)先記錄redo log,然后再找時(shí)機(jī)慢慢的將Buffer Pool中的臟數(shù)據(jù)刷新到磁盤上。
innodb_log_group_home_dir指定的目錄下的兩個(gè)文件:ib_logfile0,ib_logfile1,該文件被稱作重做日志
buffer pool緩存池: 可存放索引緩存、數(shù)據(jù)緩存等,可加速讀寫,直接操作數(shù)據(jù)頁,寫redo log修改就算完成,有專門的線程去做把buffer pool中的dirty page寫入磁盤
buffer pool默認(rèn)大小為134M(MySQL 5.7)
大致結(jié)構(gòu)如圖所示:
事務(wù)讀取,修改都是優(yōu)先操作緩存池中的數(shù)據(jù)。在實(shí)際項(xiàng)目中,mysqld會(huì)單獨(dú)的跑在一個(gè)機(jī)器上,可以分配大量的內(nèi)存專門做InnoDB的buffer pool,加快CRUD
二、緩存、磁盤結(jié)構(gòu)
當(dāng)事務(wù)commit的時(shí)候,在關(guān)系圖上的操作就是把InnoDB Log Buffer的內(nèi)容寫入磁盤,寫成功的話,在磁盤上的redo log會(huì)記錄狀態(tài)——commit,如果沒有寫成功或者寫完,則記錄狀態(tài)——prepare
log在寫入磁盤的過程中也有可能發(fā)生異常,斷電等問題,導(dǎo)致在寫redo log的時(shí)候沒有寫完(這相當(dāng)于事務(wù)沒有commit成功),此時(shí)MySQL下次在恢復(fù)的時(shí)候就沒有必要考慮這個(gè)事務(wù)的完整性,因?yàn)闋顟B(tài)并不是commit,都寫入磁盤上才表示redo log寫成功,狀態(tài)才變成commit。狀態(tài)變成commit后需要維護(hù)事務(wù)的ACID特性。
是不是commit的時(shí)候,buffer poll里面的臟數(shù)據(jù)(數(shù)據(jù)有被修改)才被寫入磁盤?
并不需要等commit的時(shí)候才開始。事務(wù)可能修改的數(shù)據(jù)量比較大,而緩存容量有限,對(duì)于buffer poll緩存的數(shù)據(jù),會(huì)有專門的線程在合適的時(shí)間,往磁盤上去刷新,如果出現(xiàn)掉電,下一次MySQL啟動(dòng)后,會(huì)根據(jù)redo log里面記錄的數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行恢復(fù)。
undo log本身也是記錄在redo log中
undo log支持事務(wù)回滾,也不是一瞬間就能完整,最終要修改的也是磁盤上的數(shù)據(jù),為防止回滾過程中出現(xiàn)異常,所以u(píng)ndo log要記錄在redo log里面。事務(wù)commit成功或者rollback成功,對(duì)于底層,都是成功的把操作寫到redo log里面。
什么是真正的事務(wù)commit成功?
不是把數(shù)據(jù)全部刷到磁盤,而是把記錄事務(wù)完整操作的redo log從log buffer寫入磁盤,再把被修改數(shù)據(jù)的狀態(tài)置為commit才算是實(shí)現(xiàn)了事務(wù)commit成功。此時(shí)雖然數(shù)據(jù)還在buffer poll,但只要我們的redo log保存完整,數(shù)據(jù)就可以恢復(fù),會(huì)有專門的線程去負(fù)責(zé)把buffer poll里的數(shù)據(jù)寫入磁盤
事務(wù)進(jìn)行操作的時(shí)候,永遠(yuǎn)是先寫redo log,然后才是寫buffer pool;事務(wù)成功commit,就是要保證redo log完整記錄到磁盤上
至于表數(shù)據(jù)的更改,buffer pool的臟數(shù)據(jù)頁是不是刷新到磁盤上,我們根本不用擔(dān)心,只要redo log完整的寫到磁盤上,我們可以隨時(shí)通過redo log重做日志來恢復(fù)事務(wù)成功commit的數(shù)據(jù)狀態(tài)(數(shù)據(jù)庫最重要的是日志,而不是數(shù)據(jù))
到此這篇關(guān)于深入理解MySQL重做日志 redo log的文章就介紹到這了,更多相關(guān)MySQL redo log內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mysql日志文件之undo?log和redo?log
- MySQL Redo與Undo日志詳細(xì)解析
- mysql日志系統(tǒng)redo log和bin log介紹
- MySQL三大日志(binlog、redo?log和undo?log)圖文詳解
- mysql中的事務(wù)重做日志(redo log)與回滾日志(undo log)
- 詳解MySQL事務(wù)日志redo log
- 真的了解MySQL中的binlog和redolog區(qū)別
- mysql中 redo日志詳解
- MySQL三大日志之binlog、redoLog、undoLog詳細(xì)講解
- MySQL8.0設(shè)置redo緩存大小的實(shí)現(xiàn)
相關(guān)文章
mysql ndb集群備份數(shù)據(jù)庫和還原數(shù)據(jù)庫的方法
中午剛剛弄明白了MYSQL集群的備份與恢復(fù)。寫下來,以后就不用為這個(gè)問題浪費(fèi)時(shí)間了2011-12-12MySql Error 1698(28000)問題的解決方法
這篇文章主要介紹了MySql Error 1698(28000)問題的解決方法,需要的朋友可以參考下2017-06-06MySQL 5.6主從報(bào)錯(cuò)的實(shí)戰(zhàn)記錄
這篇文章主要給大家介紹了關(guān)于MySQL 5.6主從報(bào)錯(cuò)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03教會(huì)你完全搞定MySQL數(shù)據(jù)庫 輕松八句話
只要掌握下面的方法,就基本上能搞定mysql數(shù)據(jù)庫。2010-09-09如何添加一個(gè)mysql用戶并給予權(quán)限詳解
在很多時(shí)候我們并不會(huì)直接利用mysql的root用戶進(jìn)行項(xiàng)目的開發(fā),一般我們都會(huì)創(chuàng)建一個(gè)具有部分權(quán)限的用戶,下面這篇文章主要給大家介紹了關(guān)于如何添加一個(gè)mysql用戶并給予權(quán)限的相關(guān)資料,需要的朋友可以參考下2023-03-03網(wǎng)站前端和后臺(tái)性能優(yōu)化的34條寶貴經(jīng)驗(yàn)和方法
網(wǎng)站前端和后臺(tái)性能優(yōu)化的34條寶貴經(jīng)驗(yàn)和方法,相關(guān)網(wǎng)頁技術(shù)人員,需要注意的地方。2011-05-05mysql實(shí)現(xiàn)查詢最接近的記錄數(shù)據(jù)示例
這篇文章主要介紹了mysql實(shí)現(xiàn)查詢最接近的記錄數(shù)據(jù),涉及mysql查詢相關(guān)的時(shí)間轉(zhuǎn)換、排序等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07