日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MySQL事務(wù)日志

數(shù)據(jù)分析與開(kāi)發(fā) ? 來(lái)源:數(shù)據(jù)分析與開(kāi)發(fā) ? 作者:Java建設(shè)者 -神韻 ? 2020-11-14 09:58 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

大家都清楚,日志是 MySQL 數(shù)據(jù)庫(kù)的重要組成部分,記錄著數(shù)據(jù)庫(kù)運(yùn)行期間各種狀態(tài)信息。MySQL 日志主要包括「錯(cuò)誤日志」、「查詢?nèi)罩尽?、「慢查詢?nèi)罩尽?、「二進(jìn)制日志(binlog)」和 事務(wù)日志(redo log、undo log)幾大類。

其中,「二進(jìn)制日記」和「事務(wù)日記」尤為重要,一直被人重視、深入研究;可是事實(shí)很殘忍,重視或者說(shuō)大多數(shù)人一般都是了解個(gè)表面,真正懂得人并不多。真想攻破這兩塊日記必須下血本,而且還不一定能攻破。但是不要緊,為了讓你們省下血本還能順利攻破這兩塊日記,我連續(xù)研究幾周 MySQL日記,最終肝出了這篇文章。

必要概念字典介紹

基礎(chǔ)不牢地動(dòng)山搖,還是常規(guī)套路,先把必要知識(shí)普及/溫習(xí)一遍,當(dāng)后續(xù)文章出現(xiàn)疑慮反過(guò)來(lái)看下這些概念字典,說(shuō)不定能柳暗花明又一村呢?

寫(xiě)了又寫(xiě),想了又想,糾結(jié)了好久,這部分知識(shí)確實(shí)有點(diǎn)多,最后還是決定將這些必要概念字典單獨(dú)分出一個(gè)文章,后續(xù)打算用截圖方式引入各個(gè)章節(jié)中,建議遇到不懂名詞查閱一下字典。


圖1:進(jìn)階知識(shí)部分示意圖

認(rèn)識(shí)二進(jìn)制日記(Binlog)

Binlog 概念

Binlog 是邏輯日記,用于記錄數(shù)據(jù)庫(kù)執(zhí)行的寫(xiě)入操作(查詢不記錄)信息,Server層記錄和引擎層無(wú)關(guān),并且是以追加方式進(jìn)行寫(xiě)入,可以通過(guò)參數(shù)max_binlog_size設(shè)置每個(gè) Binlog 文件的大小,文件大小達(dá)到設(shè)定值時(shí)會(huì)生成新的文件來(lái)保存日記。


Binlog 作用

在實(shí)際應(yīng)用中,主要用在兩個(gè)場(chǎng)景:主從復(fù)制和數(shù)據(jù)恢復(fù)

主從復(fù)制場(chǎng)景:在 Master 主端開(kāi)啟 Binlog,將 Binlog 發(fā)生到各個(gè) Slave 從端,Slave 從端重放 Binlog 從而達(dá)到主從數(shù)據(jù)一致

數(shù)據(jù)恢復(fù)場(chǎng)景:通過(guò)使用 mysqlbinlog 工具來(lái)恢復(fù)數(shù)據(jù)

Binlog 記錄過(guò)程及刷盤(pán)時(shí)機(jī)

Binlog 大致記錄過(guò)程是先寫(xiě) Binlog Buffer,然后通過(guò)刷盤(pán)時(shí)機(jī),控制刷入 OS Buffer,控制 fsync() 進(jìn)行寫(xiě)入 Binlog File 日記磁盤(pán)的過(guò)程。


對(duì)于 Binlog,MySQL 是通過(guò)參數(shù) sync_binlog 參數(shù)來(lái)控制刷盤(pán)時(shí)機(jī),取值是 0、1 和 N 三種值。0 表示由系統(tǒng)自行判斷何時(shí)調(diào)用 sync() 寫(xiě)入磁盤(pán);1 表示每次事務(wù) commit 都要調(diào)用 fsync() 寫(xiě)入磁盤(pán);N 表示每 N 個(gè)事務(wù),才會(huì)調(diào)用 fsync() 寫(xiě)入磁盤(pán)。


圖2:內(nèi)存和磁盤(pán)日記結(jié)構(gòu)圖

Binlog 記錄格式

MySQL 5.7.7 版本之前默認(rèn)格式是STATEMENT,版本之后默認(rèn)是ROW,可以通過(guò)參數(shù) binlog-format 指定。

認(rèn)識(shí)事務(wù)日記(Undo log)

Undo log 概念

Undo log是邏輯日記、回滾日記。比如一條修改 +3 的邏輯語(yǔ)句,Undo log 會(huì)記錄對(duì)應(yīng)一條 -3 的邏輯日記,一條插入語(yǔ)句則會(huì)記錄一條刪除語(yǔ)句,這樣發(fā)生錯(cuò)誤時(shí),根據(jù)執(zhí)行 Undo log 就可以回滾到事務(wù)之前的數(shù)據(jù)狀態(tài)。

Undo log 作用

回滾數(shù)據(jù):當(dāng)程序發(fā)生異常錯(cuò)誤時(shí)等,根據(jù)執(zhí)行 Undo log 就可以回滾到事務(wù)之前的數(shù)據(jù)狀態(tài),保證原子性,要么成功要么失敗。

MVCC 一致性視圖:通過(guò) Undo log 找到對(duì)應(yīng)的數(shù)據(jù)版本號(hào),是保證 MVCC 視圖的一致性的必要條件。

Undo log 記錄過(guò)程及刷盤(pán)時(shí)機(jī)

刷盤(pán)過(guò)程及時(shí)機(jī)類似于 Binlog 和 Redo,可以參考 Redo log 刷盤(pán)時(shí)機(jī)章節(jié)給出的圖片,已經(jīng)體現(xiàn)出來(lái)了。

Undo log 總結(jié)

Undo log 日記內(nèi)容不是很多,重點(diǎn)是回滾和多版本控制 MVCC那塊。此外,我記得印象筆記深刻的是長(zhǎng)事務(wù)會(huì)導(dǎo)致日記過(guò)多,這個(gè)日記就是 Undo log。因?yàn)殚L(zhǎng)事務(wù)存在,導(dǎo)致需要保存很多視圖快照,其實(shí)這里就是涉及到Undo log 何時(shí)刪除和生成的問(wèn)題,當(dāng)時(shí)糾結(jié)好久,其實(shí)很簡(jiǎn)單。生成是事務(wù)開(kāi)始后寫(xiě) Redo log 之前生成,當(dāng)沒(méi)有事務(wù)需要用到 Undo log 時(shí)就會(huì)被刪除。舉個(gè)例子,如果事務(wù) A 一直存活,那么事務(wù) A 之后產(chǎn)生的事務(wù) B、C...等等就算提交了,也不會(huì)被刪除,因?yàn)槭聞?wù) A 需要用到 B、C... 事務(wù)去找 A 的版本。所以避免長(zhǎng)事務(wù)可以減少Undo log 日記量,當(dāng)然還可以提高性能。

認(rèn)識(shí)事務(wù)日記 (Redo log)

Redo log 概念

Redo log 是重做日記,屬于InnoDB引擎的日記。是物理日記,日記記錄的內(nèi)容的是數(shù)據(jù)頁(yè)的更改,這個(gè)頁(yè) “做了什么改動(dòng)”。如:add xx記錄 to Page1,向數(shù)據(jù)頁(yè)P(yáng)age1增加一個(gè)記錄。


Redo log 作用

前滾操作:具備crash-safe能力,提供斷電重啟時(shí)解決事務(wù)丟失數(shù)據(jù)問(wèn)題。

提高性能:先寫(xiě)Redo log記錄更新。當(dāng)?shù)鹊接锌臻e線程、內(nèi)存不足、Redo log滿了時(shí)刷臟。寫(xiě) Redo log 是順序?qū)懭?,刷臟是隨機(jī)寫(xiě),節(jié)省的是隨機(jī)寫(xiě)磁盤(pán)的 IO 消耗(轉(zhuǎn)成順序?qū)懀?,所以性能得到提升。此技術(shù)稱為WAL技術(shù):Write-Ahead Logging,它的關(guān)鍵點(diǎn)就是先寫(xiě)日記磁盤(pán),再寫(xiě)數(shù)據(jù)磁盤(pán)。

Redo log 兩階段提交

更新內(nèi)存后引擎層寫(xiě) Redo log 將狀態(tài)改成 prepare 為預(yù)提交第一階段,Server 層寫(xiě) Binlog,將狀態(tài)改成 commit為提交第二階段。兩階段提交可以確保 Binlog 和 Redo log 數(shù)據(jù)一致性。

Redo log 容災(zāi)恢復(fù)過(guò)程

MySQL的處理過(guò)程如下

判斷 redo log 是否完整,如果判斷是完整(commit)的,直接用 Redo log 恢復(fù)

如果 redo log 只是預(yù)提交 prepare 但不是 commit 狀態(tài),這個(gè)時(shí)候就會(huì)去判斷 binlog 是否完整,如果完整就提交 Redo log,用 Redo log 恢復(fù),不完整就回滾事務(wù),丟棄數(shù)據(jù)。

只有在 redo log 狀態(tài)為 prepare 時(shí),才會(huì)去檢查 binlog 是否存在,否則只校驗(yàn) redo log 是否是 commit 就可以啦。怎么檢查 binlog:一個(gè)完整事務(wù) binlog 結(jié)尾有固定的格式。

Redo log 刷盤(pán)時(shí)機(jī)

Undo log 的刷盤(pán)時(shí)機(jī)和 Redo log 差不多,但是對(duì)于 Undo log 我沒(méi)找到對(duì)應(yīng)的刷盤(pán)參數(shù)設(shè)計(jì),所以不在提。Redo log 每次先寫(xiě)入 Redo Log Buffer 中,然后通過(guò)刷盤(pán)時(shí)機(jī)控制刷入 OS Buffer 時(shí)間和刷入日記磁盤(pán)的時(shí)間。


圖3:內(nèi)存和磁盤(pán)日記結(jié)構(gòu)圖

在 Undo Log 中,MySQL 是通過(guò)參數(shù)innodb_flush_log_at_trx_commit來(lái)控制刷盤(pán)時(shí)機(jī),取值是 0、1 和 2三種值。0 表示事務(wù)提交后,每秒寫(xiě)入 OS Buffer 并調(diào)用 fsync() 寫(xiě)入日記磁盤(pán)中;1 表示每次事務(wù)提交會(huì)寫(xiě)入OS Buffer 并調(diào)用 fsync() 將日記寫(xiě)入日記磁盤(pán)中。2 表示事務(wù)每次提交寫(xiě)入到 OS Buffer,每秒調(diào)用 fsync() 寫(xiě)入日記磁盤(pán)。可見(jiàn)參數(shù)為 1 是最安全的,同時(shí)也是默認(rèn)值。


圖4:Redo log刷盤(pán)時(shí)機(jī)參數(shù)對(duì)應(yīng)操作圖

Redo log 存儲(chǔ)方式


圖5:Redo log File 環(huán)形存儲(chǔ)結(jié)構(gòu)圖

上圖是日記磁盤(pán)的 Redo log 環(huán)形設(shè)計(jì)圖(從頭寫(xiě),寫(xiě)到結(jié)束又從頭開(kāi)始寫(xiě)~循環(huán))。write pos 和 check point 是兩個(gè)指針,write pos指針指向當(dāng)前日記文件寫(xiě)入的位置,check point 指針指向當(dāng)前要擦除的開(kāi)始位置。圖中綠色部分是可以寫(xiě)入 Redo log 地方,每次寫(xiě)入,write pos 指針會(huì)順時(shí)針推進(jìn),當(dāng)然基本不會(huì)與 check point 指針重合,因?yàn)?MySQL 有這種機(jī)制去實(shí)現(xiàn),每次觸發(fā)檢查點(diǎn)checkpoint,check point 會(huì)指針向前推進(jìn),這個(gè)過(guò)程就是需要進(jìn)行刷日記和數(shù)據(jù)磁盤(pán),記錄相應(yīng)的 LSN,引出難點(diǎn) LSN。

Redo Log 檢查點(diǎn)

啥時(shí)候會(huì)觸發(fā)檢查點(diǎn) checkpoint


圖6:檢查點(diǎn)觸發(fā)時(shí)機(jī)

「Checkpoint 發(fā)生的時(shí)間、條件及臟頁(yè)的選擇等都非常復(fù)雜。而 Checkpoint 所做的事情無(wú)外乎是將緩沖池中的臟頁(yè)刷回到磁盤(pán),不同之處在于每次刷新多少頁(yè)到磁盤(pán),每次從哪里取臟頁(yè),以及什么時(shí)間觸發(fā) Checkpoint。這些本文不會(huì)去研究」。

Redo Log LSN

LSN 這個(gè)概念,比較復(fù)雜。LSN 稱為日志的邏輯序列號(hào)(log sequence number),在 innodb 存儲(chǔ)引擎中,lsn占用 8 個(gè)字節(jié)。LSN 的值會(huì)隨著日志的寫(xiě)入而逐漸增大?!缚梢院?jiǎn)單理解SLN就是記錄從開(kāi)始到現(xiàn)在已經(jīng)產(chǎn)生了多少字節(jié)的Redo log值」。

存儲(chǔ)方式兩個(gè)指針又是通過(guò) LSN 計(jì)算得到指向位置,因?yàn)?LSN 記錄的是文件的大小字節(jié),當(dāng)超過(guò)文件大小時(shí),需要用取模計(jì)算出這兩個(gè)指針位置,取模使得寫(xiě)入就會(huì)從頭開(kāi)始寫(xiě),這樣使得兩個(gè)指針在一個(gè)文件中,一直落在循環(huán)位置,你追我趕的過(guò)程。這就是 Redo log 環(huán)形邏輯思想設(shè)計(jì)實(shí)現(xiàn)。

上面提到LSN比較復(fù)雜,是因?yàn)樗泻芏鄠€(gè)值,輸入命令 show engine innodb status; ,可以看到四個(gè)的 lsn 記錄


圖7:LSN值列表

為了方便識(shí)別,我都為它們重新命名,如下所示。名詞記不住,后面無(wú)法繼續(xù)深入

內(nèi)存日記:redo log buffer lsn;磁盤(pán)日記:redo log file lsn;

一般關(guān)系為:redo log buffer lsn >= redo log file lsn,如果刷盤(pán)時(shí)機(jī)為1,則redo log buffer lsn = redo log file lsn。

內(nèi)存數(shù)據(jù)頁(yè):data buffer lsn;數(shù)據(jù)磁盤(pán)數(shù)據(jù)頁(yè):data disk lsn;

一般關(guān)系為data buffer lsn > data disk lsn,如果已經(jīng)刷入數(shù)據(jù)磁盤(pán),則data buffer lsn = data disk lsn。

檢查點(diǎn):chckpoint lsn;

后面提到檢查點(diǎn)刷盤(pán),數(shù)據(jù)刷盤(pán)和日記刷盤(pán)(如果有日記刷盤(pán):則說(shuō)明我假設(shè)的日記刷盤(pán)的時(shí)機(jī)設(shè)置值不為1,為1 是同步的,即始終 redo log buffer lsn = redo log file lsn,不會(huì)由檢查點(diǎn)觸發(fā)刷日記磁盤(pán))。

都說(shuō) Redo log 是環(huán)形記錄,那么怎么記錄的?下面結(jié)合 LSN 給出記錄過(guò)程虛構(gòu)圖,可以對(duì)比 Redo log 存儲(chǔ)方式圖

?

相關(guān)知識(shí):日記磁盤(pán) + redo log file lsn + checkpoint lsn + 雙指針(write pos、check point)

?

1-8 按時(shí)間順序發(fā)生。1 點(diǎn)是假設(shè)最初的狀態(tài);2、3 點(diǎn)寫(xiě)日記磁盤(pán);4 點(diǎn)是觸發(fā)了檢查點(diǎn) checkpoint,進(jìn)行刷盤(pán),「checkpoint lsn=1開(kāi)始」,刷盤(pán)結(jié)束并更新「checkpoint lsn=512」。在 5 點(diǎn)、6 點(diǎn)已經(jīng)刷過(guò)了一循環(huán)內(nèi)存、二循環(huán)內(nèi)存,「從頭開(kāi)始寫(xiě)入 log,兩個(gè)指針指向回到了頭部」。第 7 點(diǎn)也是一個(gè)觸發(fā) checkpoint 的過(guò)程。9 點(diǎn)是假設(shè)沒(méi)有更新,最后達(dá)到平衡的結(jié)果,即內(nèi)存中數(shù)據(jù)頁(yè)和日記都完成了刷盤(pán)。


圖8:Redo Log File存儲(chǔ)過(guò)程

整個(gè)流程:

在某些情況下,觸發(fā) checkpoint,觸發(fā)數(shù)據(jù)頁(yè)和日志頁(yè)刷盤(pán),此時(shí)將內(nèi)存中的臟數(shù)據(jù)---數(shù)據(jù)臟頁(yè)和日志臟數(shù)據(jù)"分別刷到數(shù)據(jù)磁盤(pán)和日記磁盤(pán)中,而且兩者刷盤(pán)速度不一樣。checkpoint 會(huì)保護(hù)機(jī)制,當(dāng)數(shù)據(jù)刷盤(pán)速度超過(guò)日志刷盤(pán)時(shí),將會(huì)暫時(shí)停止數(shù)據(jù)刷盤(pán),等待日志刷盤(pán)進(jìn)度超過(guò)數(shù)據(jù)刷盤(pán)。

刷盤(pán)時(shí),對(duì)于數(shù)據(jù)磁盤(pán),全部都是在內(nèi)存中,此時(shí)每次刷一個(gè)數(shù)據(jù)頁(yè)到內(nèi)存更新數(shù)據(jù)頁(yè)也更新了「data disk lsn」為「data buffer lsn」(在更新內(nèi)存數(shù)據(jù)頁(yè)時(shí),會(huì)更新data buffer lsn)「?!?/p>

對(duì)于日記磁盤(pán),除了要記錄 checkpoint lsn 的值為檢查點(diǎn) checkpoint的值(必須在結(jié)束時(shí)直接記錄一個(gè)值,速度很快),這里是針對(duì)日記刷盤(pán)時(shí)機(jī)不是1(1是同步緩存刷日記刷盤(pán))時(shí),并且日記還沒(méi)刷到日記磁盤(pán)需要觸發(fā)將緩存中日記提前刷到日記磁盤(pán)中,此時(shí)會(huì)將redo buffer log刷到redo log file中也更新了redo log file lsn為redo log buffer lsn。

模擬檢查點(diǎn)觸發(fā)前后,整個(gè)流程變化,一個(gè)數(shù)據(jù)頁(yè)和日記,「數(shù)據(jù)變化及l(fā)sn從179-180的變化圖(刷盤(pán)時(shí)機(jī)不為1)」


Redo log 容災(zāi)恢復(fù)過(guò)程與 LSN

Redo log 容災(zāi)恢復(fù)過(guò)程和 LSN 的知識(shí),再次細(xì)化 Redo log 恢復(fù)過(guò)程

重啟 innodb 時(shí),Redo log 完不完整,采用 Redo log 相關(guān)知識(shí)。用 Redo log 恢復(fù),啟動(dòng)數(shù)據(jù)庫(kù)時(shí),InnoDB 會(huì)掃描數(shù)據(jù)磁盤(pán)的數(shù)據(jù)頁(yè) data disk lsn 和日志磁盤(pán)中的 checkpoint lsn。兩者相等則從 checkpoint lsn 點(diǎn)開(kāi)始恢復(fù),恢復(fù)過(guò)程是利用 redo log 到 buffer pool,直到 checkpoint lsn 等于 redo log file lsn,則恢復(fù)完成。

如果 checkpoint lsn 小于 data disk lsn,說(shuō)明在檢查點(diǎn)觸發(fā)后還沒(méi)結(jié)束刷盤(pán)時(shí)數(shù)據(jù)庫(kù)宕機(jī)了。因?yàn)?checkpoint lsn 最新值是在數(shù)據(jù)刷盤(pán)結(jié)束后才記錄的,檢查點(diǎn)之后有一部分?jǐn)?shù)據(jù)已經(jīng)刷入數(shù)據(jù)磁盤(pán),這個(gè)時(shí)候數(shù)據(jù)磁盤(pán)已經(jīng)寫(xiě)入部分的部分恢復(fù)將不會(huì)重做,直接跳到?jīng)]有恢復(fù)的 lsn 值開(kāi)始恢復(fù)。

了解 ChangeBuffer

為啥提到 ChangeBuffer

為啥本文我會(huì)提到 ChangeBuffer 呢,其實(shí)很多時(shí)候會(huì)將 ChangeBuffer 和 Redo log 搞混,兩者都是巧用內(nèi)存,減少磁盤(pán) IO,為了不弄混我覺(jué)得有必要專門(mén)對(duì)這個(gè)進(jìn)行一個(gè)講解。

ChangeBuffer 概念及作用

下面是我對(duì) ChangeBuffer 的簡(jiǎn)單介紹


也就是說(shuō)對(duì)于更新的操作,如果用到了 ChangeBuffer,更新的數(shù)據(jù)所在的數(shù)據(jù)頁(yè)如果不在內(nèi)存中,將不用去數(shù)據(jù)磁盤(pán)將數(shù)據(jù)頁(yè)讀到內(nèi)存,而是將這一次操作記錄在 ChangeBuffer 中,「ChangeBuffer 主要節(jié)省的則是隨機(jī)讀磁盤(pán)的 IO 消耗」,下次讀取查詢等讀取數(shù)據(jù)頁(yè)時(shí)用上 ChangeBuffer 中的記錄即可。其實(shí)也是一種巧用內(nèi)存的思想。

ChangeBuffer 與 Redo log 區(qū)別

Redo log 主要節(jié)省的是隨機(jī)寫(xiě)磁盤(pán)的 IO 消耗(轉(zhuǎn)成順序?qū)懀?,?ChangeBuffer 主要節(jié)省的則是隨機(jī)讀磁盤(pán)的 IO 消耗

這句話怎么理解,看下面:

Redo log 與 ChangeBuffer (含磁盤(pán)持久化) 這 2 個(gè)機(jī)制,不同之處在于優(yōu)化了整個(gè)變更流程的不同階段。

先不考慮 Redo log、ChangeBuffer 機(jī)制,簡(jiǎn)化抽象一個(gè)更新 (insert、update、delete) 流程:

從磁盤(pán)讀取待變更的行所在的數(shù)據(jù)頁(yè),讀入內(nèi)存頁(yè)中

對(duì)內(nèi)存頁(yè)中的行,執(zhí)行變更操作

將變更后的數(shù)據(jù)頁(yè),寫(xiě)入至數(shù)據(jù)磁盤(pán)中

其中,流程中的步驟 1 涉及隨機(jī)讀磁盤(pán) IO;步驟 3 涉及隨機(jī)寫(xiě)磁盤(pán) IO;剛好對(duì)應(yīng) ChangeBuffer 和 Redo log。

對(duì)那句話的理解答案:

ChangeBuffer 機(jī)制,優(yōu)化了步驟 1——避免了隨機(jī)讀磁盤(pán) IO ,將不在內(nèi)存中的數(shù)據(jù)頁(yè)的操作寫(xiě)入ChangeBuffer 中,而不是將數(shù)據(jù)頁(yè)從磁盤(pán)讀入內(nèi)存頁(yè)中

Redo log 機(jī)制, 優(yōu)化了步驟 3——避免了隨機(jī)寫(xiě)磁盤(pán) IO,將隨機(jī)寫(xiě)磁盤(pán),優(yōu)化為了順序?qū)懘疟P(pán)(寫(xiě) Redo log,確保 crash-safe)

有沒(méi)有用到 ChangeBuffer 對(duì)于 Redo log 的區(qū)別

Redo log 機(jī)制,為了保證 crash-safe,一直都會(huì)用到。有無(wú)用到 ChangeBuffer 機(jī)制,對(duì)于 redo log 這步的區(qū)別在于—— 用到了 ChangeBuffer 機(jī)制時(shí),在 Redo log 中記錄的本次變更,是記錄 new change buffer item 相關(guān)的信息,而不是直接的記錄物理頁(yè)的變更。在我們 mysql innodb 中, ChangeBuffer 機(jī)制不是一直會(huì)被應(yīng)用到,僅當(dāng)待操作的數(shù)據(jù)頁(yè)當(dāng)前不在內(nèi)存中,需要先讀磁盤(pán)加載數(shù)據(jù)頁(yè)時(shí),ChangeBuffer 才有用武之地。

ChangeBuffer的 merge 過(guò)程


除了訪問(wèn)這個(gè)數(shù)據(jù)頁(yè)會(huì)觸發(fā) merge 外,系統(tǒng)有后臺(tái)線程會(huì)定期 merge。在數(shù)據(jù)庫(kù)正常關(guān)閉(shutdown)的過(guò)程中,也會(huì)執(zhí)行 merge 操作。

merge 過(guò)程做三步

從磁盤(pán)讀入數(shù)據(jù)頁(yè)到內(nèi)存(老版本的數(shù)據(jù)頁(yè));

從 change buffer 里找出這個(gè)數(shù)據(jù)頁(yè)的 change buffer 記錄 (可能有多個(gè)),依次應(yīng)用,得到新版數(shù)據(jù)頁(yè);

寫(xiě) redo log。這個(gè) redo log 包含了數(shù)據(jù)的變更和 change buffer 的變更。

日記大連貫U-R-B,一舉攻破拿下

前面分別講的是 Binlog、Undo log 和 Redo log,下面將他們都串聯(lián)起來(lái),在一些流程體現(xiàn)全部日記。

同樣,以一些最經(jīng)典的更新語(yǔ)句例子展開(kāi)說(shuō)明。

制造演示數(shù)據(jù)

測(cè)試語(yǔ)句:插入語(yǔ)句+查詢語(yǔ)句,a字段是普通索引

1、insert into ta(a,b) values(2,5),(7, 5) 2、select * from t where a in (2, 7)

假設(shè)原來(lái)的數(shù)據(jù)如下圖,數(shù)據(jù)頁(yè) page1 在內(nèi)存中,page2 不在。插入的數(shù)據(jù) (2,5) 落在 page1,數(shù)據(jù) (7,5) 落在page2 中。


假設(shè)沒(méi)有日記和 ChangeBuffer 示范

先不考慮所有日記及 ChangeBuffer 機(jī)制,簡(jiǎn)化抽象一個(gè)更新 insert 流程

從磁盤(pán)讀取待變更的行所在的數(shù)據(jù)頁(yè),讀入內(nèi)存頁(yè)中

對(duì)內(nèi)存頁(yè)中的行,執(zhí)行變更操作

將變更后的數(shù)據(jù)頁(yè),寫(xiě)入至數(shù)據(jù)磁盤(pán)中


考慮所有日記和 ChangeBuffer 示范--現(xiàn)有 Innodb 流程

過(guò)程是 兩階段提交-----日記刷盤(pán)------數(shù)據(jù)刷盤(pán)(涉及 Redo log lsn 和 ChangeBuffer 的內(nèi)容)

兩階段提交過(guò)程

數(shù)據(jù) (2,5) 所在頁(yè) page 1 在內(nèi)存中直接更新內(nèi)存;數(shù)據(jù) (7,5) 所在頁(yè) page 2 不在內(nèi)存中,記錄 change buffer(具有唯一性的索引或者沒(méi)有使用 change buffer 的操作是將磁盤(pán)中的數(shù)據(jù)頁(yè)讀入內(nèi)存中并做更新)。

寫(xiě) undo 日記?!赶葘?xiě)緩存,后面根據(jù)刷盤(pán)參數(shù)決定何時(shí)刷入磁盤(pán),后面的 redo/Binlog 都一樣」。日記刷盤(pán) 在每一個(gè)日記中基本已經(jīng)提到,它和設(shè)置的參數(shù)有關(guān),下文不會(huì)再展開(kāi)介紹。

寫(xiě) redo 日記(先記在內(nèi)存中的更新,然后記不在內(nèi)存中的 change buffer 的改變)

日記狀態(tài)改成 prepare 階段。

寫(xiě) Binlog日記。

提交事務(wù),日記狀態(tài)改成 commit 階段。


merge 過(guò)程

緊接著上文,圖片可上下參考,假設(shè)現(xiàn)在執(zhí)行查詢語(yǔ)句 select * from t where a in (2, 7) ,此次查詢索引 a=7 所在的數(shù)據(jù)頁(yè)不在內(nèi)存中,并且上一步更新已經(jīng)在 change buffer 中有記錄,將會(huì)觸發(fā) merge 過(guò)程

將 page 2 讀入內(nèi)存

依次應(yīng)用 change buffer 中的記錄,得到最新版數(shù)據(jù)頁(yè)

寫(xiě)入 redo,之前記錄的 changebuffer 改動(dòng),現(xiàn)在改成數(shù)據(jù)頁(yè)的改動(dòng)

至于 changebuffer 被應(yīng)用后是刪除還是標(biāo)記,還有 redo 中原有的記錄 changebuffer 的改動(dòng)怎么調(diào)整是刪除還是修改成數(shù)據(jù)頁(yè)的改動(dòng)這里下面的圖是按照自己的想法描述出來(lái),如有誤望留言指正。


數(shù)據(jù)刷盤(pán)過(guò)程

數(shù)據(jù)刷盤(pán) flush 的有四種情況

InnoDB 的 redo log 寫(xiě)滿了。這時(shí)候系統(tǒng)會(huì)停止所有更新操作,把 checkpoint 往前推進(jìn),redo log 留出空間可以繼續(xù)寫(xiě)

系統(tǒng)內(nèi)存不足。當(dāng)需要新的內(nèi)存頁(yè),而內(nèi)存不夠用的時(shí)候,就要淘汰一些數(shù)據(jù)頁(yè),空出內(nèi)存給別的數(shù)據(jù)頁(yè)使用。如果淘汰的是臟頁(yè),就要先將臟頁(yè)寫(xiě)到磁盤(pán)

MySQL 認(rèn)為系統(tǒng)空閑的時(shí)候

MySQL 正常關(guān)閉的情況

數(shù)據(jù)刷盤(pán)也代表著 Redo log 檢查點(diǎn) checkpoint 觸發(fā),較為復(fù)雜。

假設(shè)數(shù)據(jù)刷盤(pán) flush 的四種情況發(fā)生了一種,那么聯(lián)系上文的過(guò)程將如下

將臟頁(yè)從內(nèi)存中刷回到數(shù)據(jù)磁盤(pán)

刷完后更新檢查點(diǎn) checkpoint 的值


流程中間某個(gè)環(huán)節(jié)數(shù)據(jù)庫(kù)宕機(jī)后,恢復(fù)具體過(guò)程,這些留在心里了,沒(méi)往上去寫(xiě),讀者可以自行思考,不難。

結(jié)尾

整個(gè)文章講了 Binlog、Undo log 和 Redo log,隨帶一提 ChangeBuffer,對(duì)此,講到這里,基本上要把我要將的已經(jīng)講完,內(nèi)容挺多,有耐心可以慢慢啃,不懂歡迎留言!

思考環(huán)節(jié),下面留下兩個(gè)問(wèn)題,歡迎大家留言解答

1、為啥 Binlog 沒(méi)有 crash-safe 功能?

2、保證 crash-safe 為啥要用兩個(gè)日記,不能用一個(gè)日記嗎(Redo log 或 Binglog)?

責(zé)任編輯:xj

原文標(biāo)題:面試官的靈魂一擊:你懂 MySQL 事務(wù)日志嗎?

文章出處:【微信公眾號(hào):數(shù)據(jù)分析與開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    4085

    瀏覽量

    68569
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    931

    瀏覽量

    29775

原文標(biāo)題:面試官的靈魂一擊:你懂 MySQL 事務(wù)日志嗎?

文章出處:【微信號(hào):DBDevs,微信公眾號(hào):數(shù)據(jù)分析與開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    MySQL磁盤(pán)空間問(wèn)題的成因和排查方法

    運(yùn)維工程師經(jīng)常會(huì)遇到這樣的場(chǎng)景:MySQL 服務(wù)器的磁盤(pán)空間告警,但查看數(shù)據(jù)目錄時(shí)發(fā)現(xiàn)數(shù)據(jù)庫(kù)本身并不大。大量磁盤(pán)空間被未知文件消耗。通過(guò)排查發(fā)現(xiàn),二進(jìn)制日志(Binary Log)是主要的磁盤(pán)空間消耗者。
    的頭像 發(fā)表于 04-13 13:57 ?150次閱讀

    NineData 社區(qū)版的慢SQL分析,比查看日志+看EXPLAIN適合中小團(tuán)隊(duì)

    本文探討 NineData 社區(qū)版在 MySQL 慢 SQL 場(chǎng)景對(duì)中小團(tuán)隊(duì)的適用性。與 “查看日志 + 看 EXPLAIN” 傳統(tǒng)方式不同,它將慢 SQL 按模板聚合,能從大盤(pán)、模板、診斷等多維
    的頭像 發(fā)表于 03-17 14:07 ?139次閱讀
    NineData 社區(qū)版的慢SQL分析,比查看<b class='flag-5'>日志</b>+看EXPLAIN適合中小團(tuán)隊(duì)

    MySQL事務(wù)與鎖機(jī)制詳解

    在我擔(dān)任某互聯(lián)網(wǎng)金融平臺(tái)SRE期間,曾遇到過(guò)一次嚴(yán)重的線上事故:凌晨3點(diǎn),監(jiān)控系統(tǒng)瘋狂告警,數(shù)據(jù)庫(kù)活躍連接數(shù)從平時(shí)的200飆升到2000,大量請(qǐng)求超時(shí)。緊急排查后發(fā)現(xiàn),一個(gè)批量更新任務(wù)與在線交易產(chǎn)生了死鎖,導(dǎo)致數(shù)據(jù)庫(kù)連接被占滿。
    的頭像 發(fā)表于 01-27 10:33 ?401次閱讀

    模組日志功能技術(shù)概覽

    模組日志功能技術(shù)方案以低侵入、高可用為原則,提供統(tǒng)一的日志API、多級(jí)日志分類與條件輸出機(jī)制。通過(guò)集成該技術(shù),開(kāi)發(fā)者可在不干擾業(yè)務(wù)邏輯的前提下,全面掌握模組的執(zhí)行狀態(tài)與異常行為。 一、本文討論的邊界
    的頭像 發(fā)表于 01-14 15:32 ?255次閱讀
    模組<b class='flag-5'>日志</b>功能技術(shù)概覽

    恒訊科技解析:如何安裝MySQL并創(chuàng)建數(shù)據(jù)庫(kù)

    安裝和管理MySQL不必復(fù)雜。只需幾分鐘,你就能在Linux服務(wù)器上搭建MySQL,創(chuàng)建第一個(gè)數(shù)據(jù)庫(kù),甚至自動(dòng)化備份——同時(shí)確保數(shù)據(jù)安全有序。 什么是 MySQL? MySQL 是一個(gè)
    的頭像 發(fā)表于 01-14 14:25 ?401次閱讀

    電能質(zhì)量在線監(jiān)測(cè)裝置數(shù)據(jù)日志能加密存儲(chǔ)嗎?

    電能質(zhì)量在線監(jiān)測(cè)裝置的數(shù)據(jù)日志 可以加密存儲(chǔ) ,且已成為工業(yè)級(jí)與電力系統(tǒng)合規(guī)應(yīng)用的標(biāo)準(zhǔn)配置。加密機(jī)制通常采用 分級(jí)加密策略 ,并結(jié)合硬件安全模塊保障密鑰安全,確保日志數(shù)據(jù)的完整性與保密性。 一、日志
    的頭像 發(fā)表于 12-05 10:16 ?778次閱讀
    電能質(zhì)量在線監(jiān)測(cè)裝置數(shù)據(jù)<b class='flag-5'>日志</b>能加密存儲(chǔ)嗎?

    工業(yè)數(shù)據(jù)中臺(tái)支持接入MySQL數(shù)據(jù)庫(kù)嗎

    工業(yè)數(shù)據(jù)中臺(tái)完全支持接入MySQL數(shù)據(jù)庫(kù) ,且通過(guò)數(shù)據(jù)同步、集成與治理等技術(shù)手段,能夠充分發(fā)揮MySQL在數(shù)據(jù)存儲(chǔ)與事務(wù)處理方面的優(yōu)勢(shì),同時(shí)彌補(bǔ)其在數(shù)據(jù)分析與共享能力上的不足,具體分析如下: 技術(shù)
    的頭像 發(fā)表于 12-04 11:23 ?517次閱讀
    工業(yè)數(shù)據(jù)中臺(tái)支持接入<b class='flag-5'>MySQL</b>數(shù)據(jù)庫(kù)嗎

    使用littlefs存儲(chǔ)ulog日志,然后讀日志文件會(huì)出錯(cuò),為什么?

    使用littlefs存儲(chǔ)ulog日志,然后通過(guò)命令讀取日志文件,或者通過(guò)API接口讀取或拷貝日志文件,都會(huì)導(dǎo)致線程卡死,嘗試了多種方法都不行,有沒(méi)有大佬有遇到或者處理過(guò)類似問(wèn)題? 改成fatfs來(lái)存
    發(fā)表于 09-29 06:14

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)28: TLP 事務(wù)處 理程序的執(zhí)行流程

    前面提到最小橋設(shè)備模型的每個(gè)端口的輸入端對(duì)接一個(gè) TLP事務(wù)處理程序, 該程序負(fù)責(zé)將接收到的 TLP 事務(wù)進(jìn)行解析和路由轉(zhuǎn)發(fā)。 TLP 事務(wù)處理程序的執(zhí)行流程如圖 1 所示。圖1 TLP 事務(wù)
    發(fā)表于 09-21 08:51

    電商API日志分析的實(shí)用工具

    ? 在當(dāng)今數(shù)字化電商時(shí)代,API(應(yīng)用程序編程接口)已成為平臺(tái)與外部系統(tǒng)交互的核心通道。電商API日志記錄了每一次請(qǐng)求的詳細(xì)信息,包括用戶行為、交易狀態(tài)、錯(cuò)誤響應(yīng)等。分析這些日志能幫助企業(yè)監(jiān)控性能
    的頭像 發(fā)表于 07-23 15:50 ?807次閱讀
    電商API<b class='flag-5'>日志</b>分析的實(shí)用工具

    MySQL數(shù)據(jù)備份與恢復(fù)策略

    數(shù)據(jù)是企業(yè)的核心資產(chǎn),MySQL作為主流的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),其數(shù)據(jù)的安全性和可靠性至關(guān)重要。本文將深入探討MySQL的數(shù)據(jù)備份策略、常用備份工具以及數(shù)據(jù)恢復(fù)的最佳實(shí)踐,幫助運(yùn)維工程師構(gòu)建完善的數(shù)據(jù)保護(hù)體系。
    的頭像 發(fā)表于 07-14 11:11 ?903次閱讀

    企業(yè)級(jí)MySQL數(shù)據(jù)庫(kù)管理指南

    在當(dāng)今數(shù)字化時(shí)代,MySQL作為全球最受歡迎的開(kāi)源關(guān)系型數(shù)據(jù)庫(kù),承載著企業(yè)核心業(yè)務(wù)數(shù)據(jù)的存儲(chǔ)與處理。作為數(shù)據(jù)庫(kù)管理員(DBA),掌握MySQL的企業(yè)級(jí)部署、優(yōu)化、維護(hù)技能至關(guān)重要。本文將從實(shí)戰(zhàn)角度出發(fā),系統(tǒng)闡述MySQL在企業(yè)環(huán)
    的頭像 發(fā)表于 07-09 09:50 ?916次閱讀

    詳解journalctl日志管理

    systemd 提供了自己的日志系統(tǒng)(logging system),稱為 journal。使用 systemd 日志,無(wú)需額外安裝日志服務(wù)(syslog)。
    的頭像 發(fā)表于 06-05 17:22 ?1975次閱讀
    詳解journalctl<b class='flag-5'>日志</b>管理

    MySQL數(shù)據(jù)庫(kù)是什么

    MySQL數(shù)據(jù)庫(kù)是一種 開(kāi)源的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS) ,由瑞典MySQL AB公司開(kāi)發(fā),后被Oracle公司收購(gòu)。它通過(guò)結(jié)構(gòu)化查詢語(yǔ)言(SQL)進(jìn)行數(shù)據(jù)存儲(chǔ)、管理和操作,廣泛應(yīng)用于Web
    的頭像 發(fā)表于 05-23 09:18 ?1475次閱讀

    如何在CentOS系統(tǒng)中部署ELK日志分析系統(tǒng)

    日志分析已成為企業(yè)監(jiān)控、故障排查和性能優(yōu)化的重要組成部分。ELK(Elasticsearch、Logstash 和 Kibana)堆棧作為一種強(qiáng)大的開(kāi)源解決方案,提供了高效的日志收集、存儲(chǔ)和可視化
    的頭像 發(fā)表于 05-08 11:47 ?1180次閱讀
    如何在CentOS系統(tǒng)中部署ELK<b class='flag-5'>日志</b>分析系統(tǒng)
    股票| 深水埗区| 虹口区| 青川县| 临海市| 京山县| 大埔县| 英山县| 留坝县| 黎平县| 侯马市| 上饶县| 东平县| 达孜县| 阳泉市| 文登市| 蒙自县| 玉溪市| 铁岭县| 乌什县| 泽库县| 宜丰县| 招远市| 灵璧县| 临高县| 霍山县| 吉林市| 华阴市| 阿克陶县| 白城市| 五常市| 临邑县| 武义县| 祁门县| 伊川县| 伊春市| 保靖县| 大渡口区| 富阳市| 蒙阴县| 常熟市|