前言
MySQL 日志包含了錯(cuò)誤日志、查詢?nèi)罩?、慢查詢?nèi)罩尽⑹聞?wù)日志、二進(jìn)制日志等,如果存儲(chǔ)引擎使用的是 InnoDB ,二進(jìn)制日志(binlog)和事務(wù)日志(包括redo log和undo log) 是肯定繞不過(guò)去的,本篇接下來(lái)詳細(xì)為大家介紹這三種日志。
redo log
為什么要有 redo log ?
我們都清楚,事務(wù)的四大特性其中有一個(gè)是持久性,簡(jiǎn)單的說(shuō)就是只要事務(wù)提交成功,對(duì)數(shù)據(jù)庫(kù)做的修改就會(huì)被永久保存下來(lái),不會(huì)因?yàn)槿魏卧蛟倩氐皆瓉?lái)的狀態(tài)。
MySQL 是怎么樣保證持久性的呢?最簡(jiǎn)單的做法是在每次事務(wù)提交的時(shí)候,將該事務(wù)涉及修改的數(shù)據(jù)頁(yè)全部刷新回磁盤(pán)中,可是這么做存在嚴(yán)重的性能問(wèn)題:
單個(gè)事務(wù)可能涉及修改多個(gè)數(shù)據(jù)頁(yè),并且數(shù)據(jù)頁(yè)在物理上并不連續(xù),使用隨機(jī)IO寫(xiě)入性能太差。
Innodb是以頁(yè)為單位進(jìn)行磁盤(pán)交互的,一個(gè)事務(wù)有可能只會(huì)修改一個(gè)數(shù)據(jù)頁(yè)中的幾個(gè)字節(jié),如果這時(shí)候?qū)⑼暾臄?shù)據(jù)頁(yè)刷回磁盤(pán)的話,很浪費(fèi)資源。
因此 MySQL 設(shè)計(jì)出了redo log,當(dāng)一條記錄更新的時(shí)候, InnoDB 引擎會(huì)先把記錄寫(xiě)到 redo log 里面去,同時(shí)更新內(nèi)存,這樣就算這條數(shù)據(jù)更新成功了,完美地解決了性能問(wèn)題(文件更小并且是順序IO)。
注意此時(shí)數(shù)據(jù)并沒(méi)有更新到磁盤(pán)上,InnoDB 會(huì)在恰當(dāng)?shù)臅r(shí)候把這條記錄更新到磁盤(pán)上去。這種先寫(xiě)日志然后再將數(shù)據(jù)刷盤(pán)的機(jī)制,有個(gè)專有名詞——WAL(Write-ahead logging)。
redo log 如何刷到磁盤(pán)的呢?
redo log包含兩部分:
內(nèi)存中的日志緩沖(redo log buffer)
磁盤(pán)上的日志文件(redo log file)
每執(zhí)行一條DML語(yǔ)句,數(shù)據(jù)庫(kù)先將記錄寫(xiě)入redo log buffer,然后后續(xù)某個(gè)時(shí)間點(diǎn)再一次性將多個(gè)操作記錄寫(xiě)到redo log file。MySQL 一共支持三種寫(xiě)入redo log file的時(shí)機(jī),通過(guò)參數(shù)innodb_flush_log_at_trx_commit進(jìn)行配置,如下圖所示:
bin log
bin log 是 MySQL 的邏輯日志,由Server層進(jìn)行記錄,用于記錄數(shù)據(jù)庫(kù)執(zhí)行的寫(xiě)入性操作(不包括查詢)信息,以二進(jìn)制的形式保存在磁盤(pán)中。無(wú)論你使用的是任何的存儲(chǔ)引擎,mysql數(shù)據(jù)庫(kù)都會(huì)記錄binlog日志。
與redo log日志一樣,binlog也有自己的刷盤(pán)策略,通過(guò)sync_binlog參數(shù)控制:
0 :每次提交事務(wù)前將binlog寫(xiě)入os cache,由操作系統(tǒng)控制什么時(shí)候刷到磁盤(pán)
1 :采用同步寫(xiě)磁盤(pán)的方式來(lái)寫(xiě)binlog,不使用os cache來(lái)寫(xiě)binlog
N :當(dāng)每進(jìn)行n次事務(wù)提交之后,調(diào)用一次fsync() os cache中的binlog強(qiáng)制刷到磁盤(pán)
bin log 和 redo log 都用于記錄的修改之后的值,那么它們之間究竟有什么區(qū)別呢?
redo log 和 binlog 的區(qū)別
主要有以下三方面:
binlog 是 MySQL 的 Server 層實(shí)現(xiàn)的,所有的引擎都是可以的。redo log是InnoDB的日志。如果不使用InnoDB引擎,是沒(méi)有redo log的。
binlog是邏輯日志,記錄的是對(duì)哪一個(gè)表的哪一行做了什么修改;redo log是物理日志,記錄的是對(duì)哪個(gè)數(shù)據(jù)頁(yè)中的哪個(gè)記錄做了什么修改,可以理解為對(duì)磁盤(pán)上的哪個(gè)數(shù)據(jù)做了修改。
redo log 是有固定大小的,所以它的空間會(huì)用完,如果用完的話,一定要進(jìn)行一些寫(xiě)入磁盤(pán)的操作才可以繼續(xù); binlog 是可以追加寫(xiě)入的,也就是 binlog 沒(méi)有空間的概念,一直寫(xiě)就行了
undo log
數(shù)據(jù)庫(kù)事務(wù)四大特性中有一個(gè)是原子性,原子性指對(duì)數(shù)據(jù)庫(kù)的一系列操作,要么全部成功,要么全部失敗,不可能出現(xiàn)部分成功的情況。實(shí)際上,原子性底層就是通過(guò)undo log實(shí)現(xiàn)的。
undo log主要記錄了數(shù)據(jù)的邏輯變化,比如一條UPDATE語(yǔ)句,對(duì)應(yīng)一條相反UPDATE的undo log,一條INSERT語(yǔ)句,對(duì)應(yīng)一條DELETE的undo log,這樣在發(fā)生錯(cuò)誤時(shí),就能回滾到事務(wù)之前的數(shù)據(jù)狀態(tài)。
undo log 同時(shí)也是MVCC(多版本并發(fā)控制)實(shí)現(xiàn)的關(guān)鍵。
總結(jié)
redo log是InnoDB存儲(chǔ)引擎的一種日志,主要作用是崩潰恢復(fù),刷盤(pán)策略參數(shù) innodb_flush_log_at_trx_commit 推薦設(shè)置成2。
binlog是MySQL Server層的一種日志,主要作用是歸檔。
undo log是InnoDB存儲(chǔ)引擎的一種日志,主要作用是回滾。
審核編輯:湯梓紅
-
磁盤(pán)
+關(guān)注
關(guān)注
1文章
361瀏覽量
25154 -
MySQL
+關(guān)注
關(guān)注
1文章
797瀏覽量
26399 -
日志
+關(guān)注
關(guān)注
0文章
138瀏覽量
10626 -
binlog
+關(guān)注
關(guān)注
0文章
6瀏覽量
1243
原文標(biāo)題:還分不清bin log 、redo log 跟 undo log?
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論