詳解MySQL事務(wù)日志redo log
redo log介紹
redo log
又叫“重做日志”,是存儲(chǔ)引擎層 (innoDB
) 生成的日志,記錄的是"物理級(jí)別"上的頁(yè)修改操作,比如頁(yè)號(hào)x,偏移量y寫入了'z'數(shù)據(jù),主要目的為了保證數(shù)據(jù)不丟失,當(dāng)MySQL發(fā)生宕機(jī)的時(shí)候,可以利用redo log
日志進(jìn)行數(shù)據(jù)恢復(fù),如下圖所示。
默認(rèn)的redo log
日志文件為ib_logfile0, ib_logfile1
,如下圖:
那想過(guò)為什么要"多此一舉"先寫入到redo log
磁盤文件中,然后再落到數(shù)據(jù)庫(kù)表中?而不直接落到數(shù)據(jù)庫(kù)表中?
主要是因?yàn)轫樞騃O性能遠(yuǎn)高于隨機(jī)IO。
數(shù)據(jù)在MySQL中存儲(chǔ)是以頁(yè)為單位,事務(wù)中的數(shù)據(jù)可能遍布在不同的頁(yè)中,如果直接寫入到對(duì)應(yīng)的頁(yè)中,是隨機(jī)IO寫入。
而redo log
是通過(guò)順序IO"追加"的方式寫入到文件末尾,而且寫入的內(nèi)容也是物理日志,比如比如,某個(gè)事務(wù)將系統(tǒng)表空間中第10號(hào)頁(yè)面中偏移量為 100 處的那個(gè)字節(jié)的值 1 改成 2等信息,日志占用空間也很小。
redo log整體流程
事務(wù)在寫入到數(shù)據(jù)庫(kù)中涉及到redo log的整體流程如下圖所示:
性能不夠,緩存來(lái)湊。由于CPU的性能遠(yuǎn)遠(yuǎn)大于磁盤,為了消除這個(gè)鴻溝,引入了兩個(gè)緩存,Buffer Pool
和redo log buffer
。Buffer Pool
用來(lái)存放各種操作,比如寫入數(shù)據(jù)時(shí),先寫到內(nèi)存中,然后由后臺(tái)線程再刷寫到磁盤。redo log buffer
用來(lái)存放重做日志,后續(xù)刷到磁盤中。
- 先將原始數(shù)據(jù)從磁盤中讀入到
Buffer Pool
中 - 修改
Buffer Pool
中的數(shù)據(jù) - 生成一條重做日志并寫入
redo log buffer
,記錄數(shù)據(jù)修改后的值 - 當(dāng)事務(wù)提交時(shí),將
redo log buffer
中的內(nèi)容追加磁盤中的redo log
文件中 - 將磁盤日志文件
redo log file
內(nèi)容刷到數(shù)據(jù)庫(kù)表中
上面流程中這種先寫日志,再寫磁盤,只有日志寫入成功,才算事務(wù)提交成功的技術(shù)思想在MySQL也叫做WAL
技術(shù) (Write-Ahead Logging
)。
redo log落盤策略
事務(wù)的日志是先寫入到redo log buffer
中是很快的,那如何保證redo log buffer
中的信息高效的落到磁盤日志文件中呢?
redo log buffer
不是直接將日志內(nèi)容刷盤到redo log file
中。redo log buffer
內(nèi)容先刷入到操作系統(tǒng)的文件系統(tǒng)緩存 (page cache
)中去,這個(gè)過(guò)程很快,而且整個(gè)系統(tǒng)宕機(jī)概率相對(duì)MySQL會(huì)小很多。- 最后,日志內(nèi)容會(huì)從操作系統(tǒng)的文件系統(tǒng)緩存中刷到磁盤的日志文件中,至于什么時(shí)候觸發(fā)這個(gè)動(dòng)作,MySQL的innoDB引擎提供了3種策略可選。
InnoDB
引擎提供了 innodb_flush_log_at_trx_commit
參數(shù),該參數(shù)控制 commit
提交事務(wù)時(shí),如何將 redo log buffer
中的日志刷新到 redo log file
的3種策略。
- innodb_flush_log_at_trx_commit=1
- 每次事務(wù)提交時(shí)都將進(jìn)行同步, 執(zhí)行主動(dòng)刷盤操作,如上圖的紅線位置,所以只要事務(wù)提交成功,
redo log
記錄就一定在硬盤里,不會(huì)有田可數(shù)據(jù)丟失。 - 該種方式是MySQL
innoDB
存儲(chǔ)引擎默認(rèn)的刷盤機(jī)制。 - 如果事務(wù)執(zhí)行期間MySQL掛了或宕機(jī),這部分日志丟了,但是事務(wù)并沒(méi)有提交,所以日志丟了也不會(huì)有損
失??梢员WCACID的D,數(shù)據(jù)絕對(duì)不會(huì)丟失,但是效率最差的。
- innodb_flush_log_at_trx_commit=2
- 為2時(shí),只要事務(wù)提交成功,
redo log buffer
中的內(nèi)容只寫入文件系統(tǒng)緩存(pagecache
) - 如果僅僅只是MySQL掛了不會(huì)有任何數(shù)據(jù)丟失,但是操作系統(tǒng)宕機(jī)可能會(huì)有1秒數(shù)據(jù)的丟失,這種情況下無(wú)法滿足ACID中的D
- 數(shù)值2的效率是高于數(shù)值等于1的
- innodb_flush_log_at_trx_commit=0
- 為0時(shí),后臺(tái)線程每隔1秒進(jìn)行一次重做日志的刷盤操作,因此MySQL掛了最多丟失1秒鐘內(nèi)的事務(wù)。
- 這種方式效率是最高的,這種策略也有丟失數(shù)據(jù)的風(fēng)險(xiǎn),也無(wú)法保證持久性。
- 其他被動(dòng)觸發(fā)刷盤的場(chǎng)景
除了上面3種策略進(jìn)行刷盤以外,還有兩種場(chǎng)景會(huì)讓一個(gè)沒(méi)有提交的事務(wù)的 redo log
寫入到磁盤中。
redo log buffer
占用的空間即將達(dá)到innodb_log_buffer_size
一半的時(shí)候,后臺(tái)線程會(huì)主動(dòng)寫盤。注意,由于這個(gè)事務(wù)并沒(méi)有提交,所以這個(gè)寫盤動(dòng)作只是write
,而沒(méi)有調(diào)用fsync
,也就是只留在了文件系統(tǒng)的page cache
。- 并行的事務(wù)提交的時(shí)候,順帶將這個(gè)事務(wù)的
redo log buffer
持久化到磁盤。假設(shè)一個(gè)事務(wù) A 執(zhí)行到一半,已經(jīng)寫了一些redo log
到buffer
中,這時(shí)候有另外一個(gè)線程的事務(wù) B 提交,如果innodb_flush_log_at_trx_commit
設(shè)置的是 1,那么按照這個(gè)參數(shù)的邏輯,事務(wù) B 要把redo log buffer
里的日志全部持久化到磁盤。這時(shí)候,就會(huì)帶上事務(wù) A 在redo log buffer
里的日志一起持久化到磁盤。
小結(jié):
我們可以根據(jù)實(shí)際的業(yè)務(wù)場(chǎng)景,在性能和持久性做一些權(quán)衡,但建議使用默認(rèn)值,雖然操作系統(tǒng)宕機(jī)的概率理論小于數(shù)據(jù)庫(kù)宕機(jī)的概率,但是一般既然使用了事務(wù),那么數(shù)據(jù)的安全相對(duì)來(lái)說(shuō)更重要些。
redo log寫入數(shù)據(jù)頁(yè)機(jī)制
目前事務(wù)日志已經(jīng)落入到磁盤的redo log file
中了,MySQL會(huì)去讀取這個(gè)文件將數(shù)據(jù)寫入到數(shù)據(jù)頁(yè)中。
很顯然,目前對(duì)redo log file
會(huì)進(jìn)行讀和寫的操作。在日志文件組中有兩個(gè)重要的“指針”,分別是 write pos、``checkpoint
。
write pos
是當(dāng)前記錄的位置,一邊寫一邊后移checkpoint
是當(dāng)前要擦除的位置,也是往后推移
- 每次刷盤 redo log 記錄到日志文件組中,write pos 位置就會(huì)后移更新。
- 每次MySQL加載日志文件組恢復(fù)數(shù)據(jù)時(shí),會(huì)清空加載過(guò)的
redo log
記錄,并把checkpoint
后移更新。 - 如果
write pos
追上checkpoint
,表示日志文件組滿了,這時(shí)候不能再寫入新的redo log
記錄,MySQL 得停下來(lái),清空一些記錄,把checkpoint
推進(jìn)一下,如下圖:
這就是整個(gè)redo log file
中的日志恢復(fù)到數(shù)據(jù)頁(yè)中的過(guò)程。
總結(jié)
本文講解了事務(wù)日志redo log
在MySQL innoDB
存儲(chǔ)引擎工作的機(jī)制,它主要是用來(lái)保證事務(wù)的持久性,避免數(shù)據(jù)丟失。如果本文對(duì)你有幫助,請(qǐng)留下一個(gè)贊。
到此這篇關(guān)于詳解MySQL事務(wù)日志redo log的文章就介紹到這了,更多相關(guān)MySQL事務(wù)日志redo log內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入理解MySQL重做日志 redo log
- 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中的binlog和redolog區(qū)別
- mysql中 redo日志詳解
- MySQL三大日志之binlog、redoLog、undoLog詳細(xì)講解
- MySQL8.0設(shè)置redo緩存大小的實(shí)現(xiàn)
相關(guān)文章
MySQL 8.0數(shù)據(jù)字典緩存管理機(jī)制解析
MySQL 8.0中的數(shù)據(jù)字典,通過(guò)對(duì)兩級(jí)緩存的逐級(jí)訪問(wèn),以及精妙的對(duì)緩存未命中情況的處理方式,有效的加速了在不同場(chǎng)景下數(shù)據(jù)庫(kù)對(duì)DD的訪問(wèn)速度,顯著的提升了數(shù)據(jù)庫(kù)訪問(wèn)元數(shù)據(jù)信息的效率,這篇文章主要介紹了解讀MySQL 8.0數(shù)據(jù)字典緩存管理機(jī)制,需要的朋友可以參考下2024-07-07mysql授予用戶遠(yuǎn)程訪問(wèn)權(quán)限的實(shí)現(xiàn)
在默認(rèn)情況下,MySQL 數(shù)據(jù)庫(kù)僅允許在本地主機(jī)上進(jìn)行訪問(wèn),如果您需要遠(yuǎn)程連接到 MySQL 數(shù)據(jù)庫(kù),您需要授予用戶遠(yuǎn)程訪問(wèn)權(quán)限,本文就來(lái)2023-11-11MySQL系列之開(kāi)篇 MySQL關(guān)系型數(shù)據(jù)庫(kù)基礎(chǔ)概念
數(shù)據(jù)庫(kù)是指長(zhǎng)期儲(chǔ)存在計(jì)算機(jī)中的有組織的、可共享的數(shù)據(jù)集合,數(shù)據(jù)具有三大基本特點(diǎn),永久存儲(chǔ),有組織,可共享,是數(shù)據(jù)庫(kù)系統(tǒng)的核心,本文給大家分享MySQL關(guān)系型數(shù)據(jù)庫(kù)基礎(chǔ)概念,需要的朋友參考下吧2021-07-07mysql類似oracle rownum寫法實(shí)例詳解
在本篇文章里小編給大家分享的是關(guān)于mysql類似oracle rownum寫法以及相關(guān)實(shí)例內(nèi)容,需要的朋友們可以學(xué)習(xí)下。2019-09-09Mysql字符串類型如何通過(guò)order by排序的正確方式
這篇文章主要介紹了Mysql字符串類型如何通過(guò)order by排序的正確方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08mysql重置root密碼的完整步驟(適用于5.7和8.0)
這篇文章主要介紹了mysql重置root密碼的完整步驟,文中描述了如何停止MySQL服務(wù)、以管理員身份打開(kāi)命令行、替換配置文件路徑、修改密碼以及重新啟動(dòng)MySQL服務(wù)的過(guò)程,需要的朋友可以參考下2025-01-01