MySQL三大日志之binlog、redoLog、undoLog詳細(xì)講解
前言
日志是mysql數(shù)據(jù)庫(kù)的重要組成部分,記錄著數(shù)據(jù)庫(kù)運(yùn)行期間各種狀態(tài)信息,能幫助我們進(jìn)行很多容錯(cuò)及分析工作,其中有三大日志與我們這些開(kāi)發(fā)者息息相關(guān),本文將介紹binlog、redoLog、undoLog三種日志:
1. redoLog
1.1 為什么需要redo log
我們都知道,事務(wù)的四大特性里面有一個(gè)是持久性,具體來(lái)說(shuō)就是只要事務(wù)提交成功,那么對(duì)數(shù)據(jù)庫(kù)做的修改就被永久保存下來(lái)了,不可能因?yàn)槿魏卧蛟倩氐皆瓉?lái)的狀態(tài)。
事務(wù)在運(yùn)行過(guò)程中,都是在內(nèi)存的Buffer Pool修改頁(yè)面,事務(wù)提交后,這些被修改后的臟頁(yè)并不會(huì)立刻刷盤(立刻刷盤開(kāi)銷太大,一方面是一個(gè)頁(yè)面可能就修改了一點(diǎn)點(diǎn),將整個(gè)頁(yè)面刷盤不值當(dāng),另一方面是一個(gè)事務(wù)會(huì)涉及不同的頁(yè)面,如果將這些頁(yè)面都刷盤會(huì)產(chǎn)生很多的隨機(jī)IO)。
但如果不采取其他措施,那么在事務(wù)提交后MySQL發(fā)生故障,導(dǎo)致內(nèi)存中數(shù)據(jù)丟失,那么這個(gè)已提交事務(wù)作出的更改也會(huì)丟失,那么mysql是如何保證內(nèi)存和磁盤的一致性的呢?
最簡(jiǎn)單的做法是在每次事務(wù)提交的時(shí)候,將該事務(wù)涉及修改的數(shù)據(jù)頁(yè)全部刷新到磁盤中。但是這么做會(huì)有嚴(yán)重的性能問(wèn)題,主要體現(xiàn)在兩個(gè)方面:
1)、 因?yàn)镮nnodb是以頁(yè)為單位進(jìn)行磁盤交互的,而一個(gè)事務(wù)很可能只修改一個(gè)數(shù)據(jù)頁(yè)里面的幾個(gè)字節(jié),這個(gè)時(shí)候?qū)⑼暾臄?shù)據(jù)頁(yè)刷到磁盤的話,太浪費(fèi)資源了!
2)、 一個(gè)事務(wù)可能涉及修改多個(gè)數(shù)據(jù)頁(yè),并且這些數(shù)據(jù)頁(yè)在物理上并不連續(xù),使用隨機(jī)IO寫入性能太差!
所以這里就需要引入redo日志,對(duì)任意頁(yè)面進(jìn)行修改的操作都會(huì)生成redo日志,在事務(wù)提交時(shí),只要保證生成的redo日志成功落盤即可,這樣,即使MySQL發(fā)生故障導(dǎo)致內(nèi)存中的數(shù)據(jù)丟失,也可以根據(jù)已落盤的redo日志恢復(fù)數(shù)據(jù)
1.2 redo log基本概念
redo log是InnoDB存儲(chǔ)引擎層的日志,又稱重做日志文件,用于記錄事務(wù)操作的變化,記錄的是數(shù)據(jù)修改之后的值,不管事務(wù)是否提交都會(huì)記錄下來(lái)。一個(gè)事務(wù)生成的redo日志是按順序?qū)懭氪疟P的,是順序IO,在實(shí)例和介質(zhì)失?。╩edia failure)時(shí),redo log文件就能派上用場(chǎng),如數(shù)據(jù)庫(kù)掉電,InnoDB存儲(chǔ)引擎會(huì)使用redo log恢復(fù)到掉電前的時(shí)刻,以此來(lái)保證數(shù)據(jù)的完整性。
redo log包括兩部分:
一個(gè)是內(nèi)存中的 日志緩沖(redo log buffer)
另一個(gè)是磁盤上的日志文件(redo log file) 。mysql每執(zhí)行一條DML語(yǔ)句,先將記錄寫入redo log buffer,后續(xù)某個(gè)時(shí)間點(diǎn)再一次性將多個(gè)操作記錄寫到redo log file。這種先寫日志,再寫磁盤的技術(shù)就是MySQL里經(jīng)常說(shuō)到的WAL(Write-Ahead Logging) 技術(shù)。
1.3 redo log記錄形式
redo log 日志的大小是固定的,即記錄滿了以后就從頭循環(huán)寫。
redolog記錄方式:
簡(jiǎn)單的redo日志 —— 記錄哪個(gè)表空間中的哪個(gè)頁(yè)面從哪個(gè)位置開(kāi)始的多少個(gè)節(jié)點(diǎn)要修改成什么
復(fù)雜的redo日志 —— 記錄了對(duì)哪個(gè)表空間的哪個(gè)頁(yè)面進(jìn)行修改,存儲(chǔ)了對(duì)該頁(yè)面進(jìn)行修改操作的一些必備要素,重啟時(shí),MySQL會(huì)根據(jù)redo日志的類型,將redo日志中的必備要素作為參數(shù),調(diào)用日志類型對(duì)應(yīng)的函數(shù),恢復(fù)數(shù)據(jù)
在計(jì)算機(jī)操作系統(tǒng)中,用戶空間(user space)下的緩沖區(qū)數(shù)據(jù)一般情況下是無(wú)法直接寫入磁盤的,中間必須經(jīng)過(guò)操作系統(tǒng)內(nèi)核空間(kernel space)緩沖區(qū)(OS Buffer)。因此,redo log buffer寫入redo log file實(shí)際上是先寫入OS Buffer,然后再通過(guò)系統(tǒng)調(diào)用fsync()將其刷到redo log file中,過(guò)程如下:
mysql支持三種將redo log buffer寫入redo log file的時(shí)機(jī),可以通過(guò)innodb_flush_log_at_trx_commit參數(shù)配置
redo log實(shí)際上記錄數(shù)據(jù)頁(yè)的變更,而這種變更記錄是沒(méi)必要全部保存,因此redo log實(shí)現(xiàn)上采用了大小固定,循環(huán)寫入的方式,當(dāng)寫到結(jié)尾時(shí),會(huì)回到開(kāi)頭循環(huán)寫日志。
總結(jié):確保事務(wù)的持久性。防止在發(fā)生故障的時(shí)間點(diǎn),尚有臟頁(yè)未寫入磁盤,在重啟mysql服務(wù)的時(shí)候,根據(jù)redo log進(jìn)行重做,從而達(dá)到事務(wù)的持久性這一特性。
2. binlog
2.1 binlog基本概念
binlog是屬于MySQL Server層面 的,又稱為歸檔日志,屬于邏輯日志,是以二進(jìn)制的形式記錄的,用于記錄數(shù)據(jù)庫(kù)執(zhí)行的寫入性操作(不包括查詢)信息,依靠binlog是沒(méi)有crash-safe能力的
啥是邏輯日志啥是物理日志:
- 邏輯日志:可以簡(jiǎn)單理解為記錄的就是sql語(yǔ)句
- 物理日志:因?yàn)閙ysql數(shù)據(jù)最終是保存在數(shù)據(jù)頁(yè)中的,物理日志記錄的就是數(shù)據(jù)頁(yè)變更
另外,binlog是通過(guò)追加的方式進(jìn)行寫入的,可以通過(guò)max_binlog_size參數(shù)設(shè)置每個(gè)binlog文件的大小,當(dāng)文件大小達(dá)到給定值之后,會(huì)生成新的文件來(lái)保存日志。
2.2 binlog使用場(chǎng)景
在實(shí)際應(yīng)用中,binlog的主要使用場(chǎng)景有兩個(gè),分別是主從復(fù)制和數(shù)據(jù)恢復(fù)。
1)、主從復(fù)制:在Master端(主父節(jié)點(diǎn))開(kāi)啟binlog,然后將binlog發(fā)送到各個(gè)(子)Slave端,Slave端重放binlog從而達(dá)到主從數(shù)據(jù)一致。
2)、 數(shù)據(jù)恢復(fù):通過(guò)使用mysql binlog工具來(lái)恢復(fù)數(shù)據(jù)。
2.3 binlog日志格式
binlog日志有三種格式,分別為STATMENT、ROW 和 MIXED。
在 MySQL 5.7.7之前,默認(rèn)的格式是 STATEMENT,MySQL 5.7.7之后,默認(rèn)值是 ROW。日志格式通過(guò)binlog-format指定。
STATMENT 基于SQL語(yǔ)句的復(fù)制(statement-based replication, SBR),每一條會(huì)修改數(shù)據(jù)的sql語(yǔ)句會(huì)記錄到binlog中。 優(yōu)點(diǎn):不需要記錄每一行的變化,減少了binlog日志量,節(jié)約了IO, 從而提高了性能; 缺點(diǎn):在某些情況下會(huì)導(dǎo)致主從數(shù)據(jù)不一致,比如執(zhí)行sysdate()、slepp()等。
ROW 基于行的復(fù)制(row-based replication, RBR),不記錄每條sql語(yǔ)句的上下文信息,僅需記錄哪條數(shù)據(jù)被修改了。 優(yōu)點(diǎn):不會(huì)出現(xiàn)某些特定情況下的存儲(chǔ)過(guò)程、或function、或trigger的調(diào)用和觸發(fā)無(wú)法被正確復(fù)制的問(wèn)題; 缺點(diǎn):會(huì)產(chǎn)生大量的日志,尤其是alter table的時(shí)候會(huì)讓日志暴漲
MIXED 基于STATMENT和ROW兩種模式的混合復(fù)制(mixed-based replication, MBR),一般的復(fù)制使用STATEMENT模式保存binlog,對(duì)于STATEMENT模式無(wú)法復(fù)制的操作使用ROW模式保存binlog
3. redolog和binlog區(qū)別
redo log是屬于innoDB層面,binlog屬于MySQL Server層面的,這樣在數(shù)據(jù)庫(kù)用別的存儲(chǔ)引擎時(shí)可以達(dá)到一致性的要求。
redo log是物理日志,記錄該數(shù)據(jù)頁(yè)更新的內(nèi)容;binlog是邏輯日志,記錄的是這個(gè)更新語(yǔ)句的原始邏輯
redo log是循環(huán)寫,日志空間大小固定;binlog是追加寫,是指一份寫到一定大小的時(shí)候會(huì)更換下一個(gè)文件,不會(huì)覆蓋。
binlog可以作為恢復(fù)數(shù)據(jù)使用,主從復(fù)制搭建,redo log作為異常宕機(jī)或者介質(zhì)故障后的數(shù)據(jù)恢復(fù)使用。
redo log是InnoDB存儲(chǔ)引擎層的日志,binlog是MySQL Server層記錄的日志, 兩者都是記錄了某些操作的日志(不是所有)自然有些重復(fù)(但兩者記錄的格式不同)。
4. undo log
數(shù)據(jù)庫(kù)事務(wù)四大特性中有一個(gè)是原子性,具體來(lái)說(shuō)就是 原子性是指對(duì)數(shù)據(jù)庫(kù)的一系列操作,要么全部成功,要么全部失敗,不可能出現(xiàn)部分成功的情況。
實(shí)際上,原子性底層就是通過(guò)undo log實(shí)現(xiàn)的。
undo log主要記錄了數(shù)據(jù)的邏輯變化,比如一條INSERT語(yǔ)句,對(duì)應(yīng)一條DELETE的undo log,對(duì)于每個(gè)UPDATE語(yǔ)句,對(duì)應(yīng)一條相反的UPDATE的undo log,這樣在發(fā)生錯(cuò)誤時(shí),就能回滾到事務(wù)之前的數(shù)據(jù)狀態(tài)。
undo log保存了事務(wù)發(fā)生之前的數(shù)據(jù)的一個(gè)版本,可以用于回滾,同時(shí)可以提供多版本并發(fā)控制下的讀(MVCC),也即非鎖定讀
總結(jié)
到此這篇關(guān)于MySQL三大日志之binlog、redoLog、undoLog的文章就介紹到這了,更多相關(guān)MySQL日志binlog、redoLog、undoLog內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
linux環(huán)境下安裝mysql數(shù)據(jù)庫(kù)的詳細(xì)教程
這篇文章主要介紹了linux環(huán)境下安裝mysql數(shù)據(jù)庫(kù)的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06利用phpmyadmin設(shè)置mysql的權(quán)限方法
這篇文章主要介紹了如何利用phpmyadmin設(shè)置mysql的權(quán)限方法,需要的朋友可以參考下2018-03-03MySQL安裝常見(jiàn)報(bào)錯(cuò)處理方法總結(jié)大全
MySQL數(shù)據(jù)庫(kù)在安裝或卸載的過(guò)程中,常常會(huì)出現(xiàn)一些錯(cuò)誤,這是件讓我們頭疼的事,下面這篇文章主要給大家介紹了關(guān)于MySQL安裝常見(jiàn)報(bào)錯(cuò)處理方法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07Navicat工具中設(shè)置MySQL允許外部訪問(wèn)
默認(rèn)情況下MySQL只允許本地登錄,即只能在安裝MySQL環(huán)境所在的主機(jī)下訪問(wèn),這篇文章主要給大家介紹了關(guān)于Navicat工具中設(shè)置MySQL允許外部訪問(wèn)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04MySQL動(dòng)態(tài)SQL拼接實(shí)例詳解
動(dòng)態(tài)SQL呢?首先是SQL語(yǔ)句,是根據(jù)條件來(lái)拼接SQL,下面這篇文章主要給大家介紹了關(guān)于MySQL動(dòng)態(tài)SQL拼接的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12MySQL: mysql is not running but lock exists 的解決方法
下面可以參考下面的方法步驟解決。最后查到一個(gè)網(wǎng)友說(shuō)可能和log文件有關(guān),于是將log文件給移除了,再重啟MySQL終于OK了2009-06-06MySQL中order by在子查詢中失效的問(wèn)題解決方案
這篇文章主要介紹了MySQL中order by在子查詢中失效的問(wèn)題解決,文中補(bǔ)充介紹了Mysql 5.7版本導(dǎo)致的子查詢order by排序無(wú)效問(wèn)題的探究,需要的朋友可以參考下2023-07-07mysql創(chuàng)建外鍵報(bào)錯(cuò)的原因及解決(can't?not?create?table)
這篇文章主要介紹了mysql創(chuàng)建外鍵報(bào)錯(cuò)的原因及解決方案(can't?not?create?table),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09