目錄
- 背景
- 物理日志和邏輯日志
- 日志模塊:redo log
- redo log產(chǎn)生背景
- redo log基本概念
- redo log記錄形式
- redo log使用場(chǎng)景
- 日志模塊:bin log
- bin log基本概念
- bin log刷盤機(jī)制
- bin log使用場(chǎng)景
- 日志模塊:undo log
- undo log基本概念
- undo log使用場(chǎng)景
- binlog/redo log/undo log區(qū)別
- 閑聊
- 【邁莫coding】
背景
日志是mysql數(shù)據(jù)庫(kù)的重要組成部分,記錄著數(shù)據(jù)庫(kù)運(yùn)行期間各種狀態(tài)信息。mysql日志主要包括錯(cuò)誤日志、查詢?nèi)罩?、慢查詢?nèi)罩尽⑹聞?wù)日志、二進(jìn)制日志幾大類。作為開發(fā),我們重點(diǎn)需要關(guān)注的是二進(jìn)制日志(bin log)和事務(wù)日志(包括redo log和undo log),本文接下來會(huì)詳細(xì)介紹這三種日志。
物理日志和邏輯日志
在說日志模塊前,先劇透一下什么是物理日志和邏輯日志,以防有小伙伴不太熟悉這兩個(gè)詞,所以先學(xué)習(xí)一下,這樣看日志模塊時(shí)見到這兩個(gè)詞不至于生疏。
- 物理日志:通俗的講,就是只有"我"自己可以使用,別人無法共享我的"物理格式,私有化。
- 邏輯日志:可以給別的引擎使用,是所有引擎共享的。
日志模塊:redolog
redo log產(chǎn)生背景
說mysql日志redo log,先說一個(gè)故事。從前有一家酒館,酒館老板常備著一個(gè)粉板,專門記著客人的賒賬記錄,也是他的法寶之一。如果賒賬的人不多,他可以在粉板上記錄下賒賬的人和賬目。如果賒賬人多的話,由于粉板的空間大小有限,所以他又需要額外準(zhǔn)備一本賬本,專門記錄所有賒賬的賬目。
如果有人要賒賬的話,一般老板有兩種做法:
- 打開賬本,找到賒賬人的記錄,進(jìn)行追加賒賬記錄
- 先把賒賬人的記錄寫到粉板上,待客流量少的時(shí)刻,再更新到賒賬賬目上
如果老板使用第一種方法的話,每當(dāng)有人要賒賬的話,首先他需要打開厚厚的賬本,一頁一頁查找該顧客的姓名,然后進(jìn)行登記。你們想啊,如果賒賬的人不多,老板找賒賬人的記錄輕松點(diǎn),如果賒賬本有好幾本的話,一本一本的找,老板看的都頭疼。
方案一的過程想想都頭大。相比第二種方案,對(duì)老板就相對(duì)輕松點(diǎn),老板只需要把賒賬人的信息寫在粉板上,待客流量低的時(shí)候,再更新到賒賬本上。
同樣,mysql里也有同樣的問題,如果每一次數(shù)據(jù)的操作都寫入磁盤中,首先磁盤先要找到對(duì)應(yīng)的記錄,然后再更新,整個(gè)過程io成本,查找成本比較高。所以,mysql為了提高性能,使用了類似老板粉板方式,先把更新數(shù)據(jù)結(jié)果存儲(chǔ)到某個(gè)地方,待空閑時(shí)再寫入磁盤中。
而mysql把更新結(jié)果存儲(chǔ)的地方,就是咱們今天所說的主角之一redo log。接下里,咱們就好好和主角交流交流。
redo log基本概念
redo log是InnoDB存儲(chǔ)引擎層的日志,又被稱為重寫日志,用來記錄事務(wù)操作的變化,記錄的是數(shù)據(jù)修改之后的值,不管事務(wù)提交是否成功,都會(huì)被記錄下來。
而這種先寫日志,后寫磁盤的技術(shù)就是mysql里面經(jīng)常提及到的WAL(Write Ahead Logging)技術(shù)。
具體的來說,就是當(dāng)有一條記錄需要更新的時(shí)候,InnoDB引擎會(huì)把記錄優(yōu)先更新到redo log(粉板)里面,并更新內(nèi)存,這樣更新操作就完成了。同時(shí),InnoDB引擎會(huì)在空閑的時(shí)間將redo log中的記錄存儲(chǔ)到磁盤上。
redo log 記錄方式
由于redo log記錄的是數(shù)據(jù)頁的變更,而這種記錄是沒有必要永久保存的,因此redo log實(shí)現(xiàn)上采用來大小固定,循環(huán)寫入的方式,當(dāng)記錄寫到末尾時(shí),又會(huì)從頭開始寫,如下圖所示。
如圖所示,
write pos是當(dāng)前記錄的位置,一邊寫一邊后移,寫到4號(hào)文件末尾就回到1號(hào)文件開頭。check point是當(dāng)前要把記錄寫入到數(shù)據(jù)文件的位置,也是后移并且循環(huán)的。
如果和上面老板粉板場(chǎng)景結(jié)合起來描述的話,write pos就是老板在粉板上順序?qū)懭胭d賬人記錄位置,對(duì)于mysql來說,write pos后移;而check point就是老板把粉板上記錄寫入到賒賬本上的位置,當(dāng)老板寫入到賒賬本上后,就會(huì)把粉板上該記錄擦除掉,對(duì)于mysql來說,check point后移。
redo log使用場(chǎng)景
- 用于系統(tǒng)奔潰恢復(fù)(crash-safe)
日志模塊:binlog
bin log基本概念
bin log是mysql數(shù)據(jù)庫(kù)service層的,是所有存儲(chǔ)引擎共享的日志模塊,它用于記錄數(shù)據(jù)庫(kù)執(zhí)行的寫入性操作,也就是在事務(wù)commit階段進(jìn)行記錄,以二進(jìn)制的形式保存于磁盤中。
bin log是邏輯日志,并且由mysql數(shù)據(jù)庫(kù)的service層執(zhí)行,也就是說使用所有的存儲(chǔ)引擎數(shù)據(jù)庫(kù)都會(huì)記錄bin log日志。
bin log是以追加的方式進(jìn)行寫入的,可以通過 max_binlog_size 參數(shù)設(shè)置bin log文件大小,當(dāng)文件大小達(dá)到某個(gè)值時(shí),會(huì)生成新的文件來保存日志。
bin log刷盤機(jī)制
對(duì)于InnoDB引擎而言,在每次事務(wù)commit提交時(shí)才會(huì)記錄bin log日志,此時(shí)記錄仍然在內(nèi)存中,那么什么時(shí)候存儲(chǔ)到磁盤中呢?mysql通過 sync_binlog 參數(shù)控制bin log刷盤時(shí)機(jī),取值范圍:0~N:
0:不去強(qiáng)求,由系統(tǒng)自行判斷何時(shí)寫入磁盤;
1:每次事務(wù)commit的時(shí)候都要將bin log寫入磁盤;
N:每N個(gè)事務(wù)commit,才會(huì)將bin log寫入磁盤;
sync_binlog 參數(shù)建議設(shè)置為1,這樣每次事務(wù)commit時(shí)就會(huì)把bin log寫入磁盤中,這樣也可以保證mysql異常重啟之后bin log日志不會(huì)丟失。
bin log使用場(chǎng)景
在實(shí)際場(chǎng)景中, bin log 的主要場(chǎng)景有兩點(diǎn),一點(diǎn)是主從復(fù)制,另一點(diǎn)是數(shù)據(jù)恢復(fù)
主從復(fù)制:在master端開啟 bin log ,然后將 bin log 發(fā)送給各個(gè)slaver端,slaver端讀取 bin log 日志,從而使得主從數(shù)據(jù)庫(kù)中數(shù)據(jù)一致
數(shù)據(jù)恢復(fù):通過 bin log 獲取想要恢復(fù)的時(shí)間段數(shù)據(jù)
日志模塊:undolog
undo log基本概念
undo log 是回滾日志,是記錄每條數(shù)據(jù)的所有版本,比如 update 語句,那么它首先會(huì)將該條記錄的數(shù)據(jù)記錄到undo log日志中,并且將最新版本的roll_pointer指針指向上一個(gè)版本,這樣就可以形成當(dāng)前記錄的所有版本,這也是MVCC的實(shí)現(xiàn)機(jī)制。
MVCC實(shí)現(xiàn)機(jī)制,查看我的另一篇文章<<校招mysql那些事|MVCC原理機(jī)制>>。
校招mysql那些事|MVCC原理機(jī)制
undo log使用場(chǎng)景
- MVCC多版本控制中使用
undo log
binlog/redo log/undo log區(qū)別
| | bin log | redo log | undo log |
|--|--| --| -- | -- |
| | |
|存儲(chǔ)位置 |server層,所有引擎共享| InnoDB引擎獨(dú)有 |
|文件大小| binlog可通過max_binlog_ize設(shè)置每個(gè)binlog文件大小| redo log大小是固定的
|日志名稱 |歸檔日志 |重寫日志 |回滾日志
|記錄方式 |通過追加方式進(jìn)行記錄| 通過循環(huán)寫方式進(jìn)行記錄,寫到末尾又從開頭接著寫
|適用場(chǎng)景 |主從復(fù)制和數(shù)據(jù)恢復(fù)| 奔潰恢復(fù) |MVCC多版本并發(fā)
閑聊
- 讀完文章,自己是不是和mysql日志模塊的cp率又提高了
- 我是邁莫,歡迎大家和我交流
文章也會(huì)持續(xù)更新,可以微信搜索「 邁莫coding 」第一時(shí)間閱讀。