溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL日志的知識(shí)點(diǎn)有哪些

發(fā)布時(shí)間:2022-10-10 11:49:11 來(lái)源:億速云 閱讀:150 作者:iii 欄目:MySQL數(shù)據(jù)庫(kù)

本篇內(nèi)容主要講解“MySQL日志的知識(shí)點(diǎn)有哪些”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“MySQL日志的知識(shí)點(diǎn)有哪些”吧!

Mysql的日志系統(tǒng)是Mysql保證無(wú)論何時(shí)崩潰數(shù)據(jù)都不會(huì)丟失的關(guān)鍵

眾所周知Mysql是持久化的數(shù)據(jù)庫(kù), 所有的數(shù)據(jù)都是持久化到硬盤中的, 保證數(shù)據(jù)不會(huì)丟失

Mysql保證數(shù)據(jù)不會(huì)丟失是從以下兩個(gè)方面來(lái)體現(xiàn)的

  • 能夠恢復(fù)到任意時(shí)刻的數(shù)據(jù)狀態(tài)

  • 無(wú)論在事務(wù)提交前還是提交后崩潰都能保證數(shù)據(jù)不丟失

事務(wù)過(guò)程中崩潰能夠恢復(fù)到事務(wù)提交前的狀態(tài)

事務(wù)提交后崩潰已提交的數(shù)據(jù)不會(huì)丟失

MySQL保證以上兩個(gè)點(diǎn)的關(guān)鍵就是通過(guò) undo log, redo log 和 binlog 這三個(gè)日志來(lái)實(shí)現(xiàn)的, 接下來(lái)將逐一介紹

undo log 回滾日志

undo log是Mysql的回滾日志, 存儲(chǔ)的是老版本的數(shù)據(jù)

主要作用

存儲(chǔ)老版本的數(shù)據(jù)

配合Read View和隱藏字段實(shí)現(xiàn)了Mysql的快照讀

用于在事務(wù)執(zhí)行失敗的時(shí)候回滾到事務(wù)開始前的版本

undo log 有什么類型

undo log 有兩種類型

對(duì)于 insert 命令, undo log 記錄的是新增的記錄的主鍵, 在回滾的時(shí)候根據(jù) undo log 中的主鍵去刪除對(duì)應(yīng)的記錄即可

對(duì)于 update / delete 命令, undo log 記錄的是被修改的記錄的舊數(shù)據(jù)

Mysql中的每一行數(shù)據(jù)都有一個(gè)最新修改當(dāng)前數(shù)據(jù)行的事務(wù)id和回滾指針這兩個(gè)字段, 當(dāng)對(duì)數(shù)據(jù)行進(jìn)行修改之后, undo log指針就會(huì)指向舊的這一行數(shù)據(jù), 而新生成的這一行數(shù)據(jù)的回滾指針就會(huì)指向undo log指針當(dāng)前指向的舊數(shù)據(jù)行

  • Mysql為了避免undo log指針修改指向的時(shí)候出現(xiàn)并發(fā)問(wèn)題, 在修改之前會(huì)對(duì)undo log指針增加排他鎖以保證undo log的正確寫入

MySQL日志的知識(shí)點(diǎn)有哪些

undo log 什么時(shí)候刪除

undo log是用于保證事務(wù)在未提交的時(shí)候可以順利回滾到事務(wù)開始前的狀態(tài), 當(dāng)事務(wù)提交之后undo log就失去作用了, 就需要被刪除

undo log是交由Mysql中的 Purage 線程來(lái)負(fù)責(zé)刪除的, purage會(huì)定期檢查undo log中的deleted_bit 標(biāo)志, 這個(gè)標(biāo)志會(huì)在事務(wù)提交后被設(shè)置為true, purage 線程發(fā)現(xiàn)為true的記錄就會(huì)負(fù)責(zé)將其刪除

redo log 重做日志

redo log是Mysql的物理日志, 負(fù)責(zé)記錄某個(gè)數(shù)據(jù)頁(yè)執(zhí)行了什么樣的操作

redo log 的作用

  • 負(fù)責(zé)記錄提交的事務(wù)對(duì)數(shù)據(jù)的修改, 記錄的內(nèi)容大概就是對(duì)x表的y頁(yè)z偏移做了a更新

  • 讓Mysql在提交事務(wù)的時(shí)候無(wú)需等待數(shù)據(jù)持久化磁盤, 只需要將redo log持久化到磁盤就可以了

  • 未清除的redo log的數(shù)量標(biāo)識(shí)了未刷盤的臟頁(yè)數(shù)量

為什么提交事務(wù)是選擇持久化redo log, 而不是持久化數(shù)據(jù)到磁盤

持久化數(shù)據(jù)到磁盤是隨機(jī)IO過(guò)程, 所以Mysql選擇將數(shù)據(jù)緩存起來(lái), 等待一個(gè)合適的時(shí)機(jī)將數(shù)據(jù)一次性寫入磁盤, 減少IO

但是數(shù)據(jù)緩存在內(nèi)存中有丟失的風(fēng)險(xiǎn), 所以Mysql選擇將redo log持久化

redo log是順序?qū)? 持久化的效率比隨機(jī)寫的效率要高, 并且redo log記錄了數(shù)據(jù)的變化情況, 只要redo log在就可以保證在Mysql重啟后恢復(fù)數(shù)據(jù)

在InnoDB中, redo log是一個(gè)固定大小的類似循環(huán)隊(duì)列的存在, 每次寫入都從后面write pos的位置, 在持久化數(shù)據(jù)的時(shí)候就移動(dòng)check point往前讀取

MySQL日志的知識(shí)點(diǎn)有哪些

這樣設(shè)計(jì)的原因是因?yàn)閞edo log是防止Mysql崩潰后緩存的臟頁(yè)數(shù)據(jù)丟失而存在的

當(dāng)Mysql中的數(shù)據(jù)被持久化到磁盤中后, 被持久化部分的redo log其實(shí)就沒(méi)有用了, 就可以騰出空間來(lái)記錄新的數(shù)據(jù)

undo log 和 redo log 的區(qū)別

undo log記錄的是事務(wù)執(zhí)行過(guò)程中舊數(shù)據(jù)的狀態(tài), redo log記錄的是數(shù)據(jù)更新之后的狀態(tài)

redo log其實(shí)保障的是事務(wù)的持久性和一致性,而undo log則保障了事務(wù)的原子性

binlog 歸檔日志

binlog是Mysql server層實(shí)現(xiàn)的日志, 是所有引擎通用的

作用

binlog記錄的是mysql原始的語(yǔ)句邏輯, 并且是采用追加寫入的形式記錄的, 所以可以用于恢復(fù)mysql在任意時(shí)刻的數(shù)據(jù)庫(kù)數(shù)據(jù)狀態(tài)

所以叫binlog是歸檔日志

同時(shí)binlog也是Mysql實(shí)現(xiàn)主從復(fù)制的依賴, 從庫(kù)通過(guò)從主庫(kù)中復(fù)制binlog回放來(lái)同步主庫(kù)的數(shù)據(jù)狀態(tài)

定義

先寫日志到磁盤中, 再寫數(shù)據(jù)到磁盤中Mysql的寫操作不是立刻寫入到磁盤中的, 而是先寫日志, 保證redo log和binlog都持久化到磁盤中再由后臺(tái)線程選擇時(shí)機(jī)將數(shù)據(jù)持久化到硬盤的

為什么要先寫日志到磁盤中

因?yàn)樗⑴K頁(yè)是一個(gè)隨機(jī)讀寫的過(guò)程, 持久化到磁盤中的速度肯定沒(méi)有redo log | binlog這些順序?qū)懙乃俣瓤? 所以選擇先在內(nèi)存中對(duì)數(shù)據(jù)進(jìn)行修改, 再后期選擇時(shí)機(jī)異步持久化到磁盤中

所以在臟頁(yè)還未刷入磁盤中的這段時(shí)間就由redo log | binlog來(lái)保證數(shù)據(jù)的持久化, 防止斷電重啟等情況內(nèi)存中的數(shù)據(jù)丟失

當(dāng)臟頁(yè)滿的時(shí)候需要將臟頁(yè)寫入到磁盤再淘汰, 為何不全部淘汰掉下次使用的時(shí)候再通過(guò)redo log來(lái)恢復(fù)呢

從性能方面考慮的, 如果每次從磁盤中讀取數(shù)據(jù)到內(nèi)存都需要和redo log比對(duì)更新, 效率很低

MySQL刷臟頁(yè)寫入到磁盤保證了數(shù)據(jù)頁(yè)只要在內(nèi)存中, 就肯定是當(dāng)前最新的數(shù)據(jù)可以返回

如果內(nèi)存中沒(méi)有數(shù)據(jù)只要從磁盤中讀取肯定能得到最新的正確數(shù)據(jù), 而不用再去同redo log進(jìn)行比對(duì)

binlog和redo log的寫入過(guò)程 - WAL機(jī)制的基本保證

binlog和redo log都是將日志寫入劃分為三個(gè)過(guò)程 寫入cache, write和sync

在事務(wù)執(zhí)行過(guò)程中會(huì)將binlog和redo log寫入到對(duì)應(yīng)分配的緩存中, 以便在事務(wù)提交的時(shí)候一次性寫入到磁盤中

在事務(wù)提交的時(shí)候會(huì)先進(jìn)行write將數(shù)據(jù)寫入到操作系統(tǒng)的頁(yè)緩存中, 此時(shí)數(shù)據(jù)還未真正寫入文件, 但是已經(jīng)是交由操作系統(tǒng)的緩存來(lái)保管了, 如果此時(shí)Mysql進(jìn)程崩潰這部分寫入的數(shù)據(jù)也不會(huì)丟失, 操作系統(tǒng)的內(nèi)核線程會(huì)負(fù)責(zé)將這部分緩存中的數(shù)據(jù)寫入磁盤

  • 但是如果操作系統(tǒng)崩潰了這部分?jǐn)?shù)據(jù)就丟失了

最后就是mysql手動(dòng)調(diào)用sync將寫入在頁(yè)緩存中的數(shù)據(jù)持久化到硬盤, 寫入完成后數(shù)據(jù)就是持久化成功了

最后的write和sync步驟mysql提供了對(duì)應(yīng)的參數(shù)來(lái)控制寫入策略

redo log是通過(guò)innodb_flush_log_at_trx_commit來(lái)控制的

  • 設(shè)置為 0 的時(shí)候,表示每次事務(wù)提交時(shí)都只是把redo log留在redo log的緩存中

丟失風(fēng)險(xiǎn)最大

  • 設(shè)置為 1 的時(shí)候,表示每次事務(wù)提交時(shí)都將redo log直接持久化到磁盤

丟失風(fēng)險(xiǎn)最小, 但是IO占用大

  • 設(shè)置為 2 的時(shí)候,表示每次事務(wù)提交時(shí)都只是把redo log寫到page cache

IO占用居中, 將寫入到磁盤這個(gè)最占用IO的過(guò)程交由操作系統(tǒng)來(lái)負(fù)責(zé)

binlog是通過(guò)參數(shù)sync_binlog來(lái)控制的

  • sync_binlog=0 的時(shí)候,表示每次提交事務(wù)都只 write,不 fsync

  • sync_binlog=1 的時(shí)候,表示每次提交事務(wù)都會(huì)執(zhí)行 fsync

  • sync_binlog=N(N>1) 的時(shí)候,表示每次提交事務(wù)都 write,但累積 N 個(gè)事務(wù)后才 fsync

兩階段日志提交

什么是兩階段日志提交

MySQL日志的知識(shí)點(diǎn)有哪些

將redo log日志提交的過(guò)程分為prepare和commit這兩個(gè)階段, binlog日志提交在這兩個(gè)階段中間

事務(wù)提交時(shí)redo log先提交后進(jìn)入prepare狀態(tài), 然后binlog提交完成后redo log才能將日志的狀態(tài)修改為commit已提交

為什么需要兩階段日志提交

和InnoDB引擎的回滾機(jī)制有關(guān), InnoDB的redo log提交了事務(wù)就無(wú)法回滾了, 如果在redo log提交后binlog寫入失敗的話就會(huì)出現(xiàn)兩份不統(tǒng)一的情況

如果此時(shí)數(shù)據(jù)庫(kù)異常重啟的話要依據(jù)那一份來(lái)恢復(fù)數(shù)據(jù)就值得思考了, 所以才需要兩階段日志提交

假設(shè)現(xiàn)在在時(shí)刻A數(shù)據(jù)庫(kù)崩潰的話, 因?yàn)閎inlog還未寫入, redo log還未提交, 所以重啟后事務(wù)會(huì)回滾, 兩份日志依舊是統(tǒng)一狀態(tài)

如果是時(shí)間段B的話, 就需要對(duì)redo log的提交標(biāo)志進(jìn)行判斷了, 在查詢r(jià)edo log中是否有commit提交標(biāo)志, 如果有的話事務(wù)沒(méi)有問(wèn)題, 直接提交

  • 如果redo log中沒(méi)有對(duì)應(yīng)事務(wù)的提交標(biāo)志的話會(huì)對(duì)binlog進(jìn)行檢查

  • 如果binlog完整并且?guī)в衏ommit標(biāo)志, 就會(huì)提交事務(wù)并在redo log后面補(bǔ)上commit標(biāo)志如果binlog不完整就回滾事務(wù)

這里可以發(fā)現(xiàn)兩階段日志提交中發(fā)生了崩潰是依據(jù)binlog來(lái)進(jìn)行標(biāo)準(zhǔn)判斷的, 原因是因?yàn)橹鲝膹?fù)制是依據(jù)binlog來(lái)進(jìn)行的

如果對(duì)兩份日志都需要檢查完整性的話, 主庫(kù)掛掉切換到從庫(kù)的時(shí)間會(huì)變長(zhǎng), 以binlog為基準(zhǔn)的話主庫(kù)掛了直接拿著binlog去從庫(kù)恢復(fù)數(shù)據(jù)即可, 無(wú)需檢查redo log的完整性

此外binlog是Mysql Server層的通用日志, 這也是選擇binlog作為基準(zhǔn)的原因

兩階段日志提交的缺點(diǎn)

  • 磁盤IO次數(shù)高

在提交日志的時(shí)候會(huì)有redo log和binlog對(duì)應(yīng)的刷盤操作, IO次數(shù)高

  • 鎖競(jìng)爭(zhēng)激烈

為了保證多個(gè)事務(wù)提交的時(shí)候日志的記錄和事務(wù)的提交順序是一致的, 會(huì)使用鎖來(lái)保證日志提交的相對(duì)順序

但是在并發(fā)量大的情況下性能會(huì)變差

組提交機(jī)制

組提交機(jī)制的作用

當(dāng)有躲過(guò)事務(wù)提交的時(shí)候, 將多個(gè)事務(wù)的日志合并在一起去寫入, 減少磁盤IO操作

組提交機(jī)制的實(shí)現(xiàn)

組提交機(jī)制將commit過(guò)程拆分成三個(gè)過(guò)程, 對(duì)每個(gè)過(guò)程都維護(hù)了一個(gè)隊(duì)列, 并且通過(guò)鎖來(lái)保證事務(wù)的寫入順序

  • 分成三個(gè)階段分別加鎖可以減少鎖粒度, 無(wú)需鎖住事務(wù)的整個(gè)提交過(guò)程

當(dāng)隊(duì)列為空的時(shí)候第一個(gè)進(jìn)入隊(duì)列的事務(wù)會(huì)成為后續(xù)進(jìn)入的事務(wù)的領(lǐng)導(dǎo)者, 帶領(lǐng)后續(xù)事務(wù)完成接下來(lái)的階段操作

階段一 : flush階段 : 多個(gè)事務(wù)按進(jìn)入的順序?qū)inlog從cache中寫入文件 (不刷盤)

第一個(gè)進(jìn)入flush階段的事務(wù)會(huì)作為領(lǐng)導(dǎo)者領(lǐng)導(dǎo)后面進(jìn)入的事務(wù)

領(lǐng)導(dǎo)者事務(wù)會(huì)帶領(lǐng)所有的事務(wù)對(duì) redo log 進(jìn)行一次 write + fsync, 也就是將redo log 寫入磁盤, 完成redo log 的propare階段

如果在這個(gè)階段Mysql崩潰了, 會(huì)在重啟后回滾這組事務(wù)

階段二 : sync : 對(duì)binlog文件做fsync操作 (將多個(gè)事務(wù)的binlog合并一起刷盤)

在flush階段將binlog寫入到binlog文件后, 會(huì)等待一段時(shí)間再進(jìn)行刷盤, 目的是組合更多事務(wù)的binlog一起刷盤減少消耗

等待會(huì)有時(shí)間限制和最大事務(wù)限制, 滿足其中一個(gè)條件就會(huì)立刻對(duì)binlog進(jìn)行刷盤

sync階段主要負(fù)責(zé)binlog的組提交, 如果當(dāng)前階段Mysql崩潰的話, 在重啟后可以通過(guò)redo log的刷盤記錄繼續(xù)完成事務(wù)提交

  • 因?yàn)榇藭r(shí)binlog已經(jīng)完成提交了, 所以可以根據(jù)redo log來(lái)繼續(xù)提交事務(wù)

階段三 : commit : 對(duì)各個(gè)事務(wù)做InnoDB的commit操作

到此,相信大家對(duì)“MySQL日志的知識(shí)點(diǎn)有哪些”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI