日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

今天想和大家聊一聊 MySQL 中的 redo log,其實最早我是想聊兩階段提交的,后來想想可能有小伙伴還不了解 binlog,所以就先整了一篇 binlog:

  • 手把手教你玩 MySQL 刪庫不跑路,直接把 MySQL 的 binlog 玩溜!
  • MySQL刪庫不跑路(視頻版)

binlog 大家懂了之后,接下來還差個 redo log,redo log 大家也懂了,那么再講兩階段提交相信小伙伴們就很容易懂了,咱們一步一步來。

1. 誰的 redo log

學(xué)習(xí) redo log,我覺得首先要搞明白一個問題,就是是誰的 redo log?

我們知道,MySQL 架構(gòu)整體上分為兩層:Server 層和存儲引擎層,如下圖:

MySQL 為什么需要 redo log?

 

前面松哥文章+視頻跟大家聊的 binlog,是 MySQL 自己提供的 binlog,而 redo log 則不是 MySQL 提供的,而是存儲引擎 InnoDB 自己提供的。所以在 MySQL 中就存在兩類日志 binlog 和 redo log,存在兩類日志既有歷史原因(InnoDB 最早不是 MySQL 官方存儲引擎)也有技術(shù)原因,這個咱們以后再細聊。

先把這個問題搞清楚,后面很多地方就容易懂了。

2. buffer pool

在正式介紹 redo log 之前,還有一個 buffer pool 需要大家了解。

小伙伴們知道,InnoDB 引擎存儲數(shù)據(jù)的時候,是以頁為單位的,每個數(shù)據(jù)頁的大小默認是 16KB,我們可以通過如下命令來查看頁的大小:

MySQL 為什么需要 redo log?

 

16384/1024=16

剛好是 16KB。

計算機在存儲數(shù)據(jù)的時候,最小存儲單元是扇區(qū),一個扇區(qū)的大小是 512 字節(jié),而文件系統(tǒng)(例如 XFS/EXT4)最小單元是塊,一個塊的大小是 4KB,也就是四個塊組成一個 InnoDB 中的頁。我們在 MySQL 中針對數(shù)據(jù)庫的增刪改查操作,都是操作數(shù)據(jù)頁,說白了,就是操作磁盤。

但是大家想想,如果每一次操作都操作磁盤,那么就會產(chǎn)生海量的磁盤 IO 操作,如果是傳統(tǒng)的機械硬盤,還會涉及到很多隨機 IO 操作,效率低的令人發(fā)指。這嚴重影響了 MySQL 的性能。

為了解決這一問題,MySQL 引入了 buffer pool,也就是我們常說的緩沖池。

buffer pool 的主要作用就是緩存索引和表數(shù)據(jù),以避免每一次操作都要進行磁盤 IO,通過 buffer pool 可以提高數(shù)據(jù)的訪問速度。

通過如下命令可以查看 buffer pool 的默認大小:

MySQL 為什么需要 redo log?

 

134217728/1024/1024=128

默認大小是 128MB,因為松哥這里的 MySQL 是安裝在 Docker 中,所以這個分配的小一些。一般來說,如果一個服務(wù)器只是運行了一個 MySQL 服務(wù),我們可以設(shè)置 buffer pool 的大小為服務(wù)器內(nèi)存大小的 75%~80%。

3. change buffer

在正式介紹 redo log 之前,還有一個 change buffer 需要大家了解。

前面我們說的 buffer pool 雖然提高了訪問速度,但是增刪改的效率并沒有因此提升,當涉及到增刪改的時候,還是需要磁盤 IO,那么效率一樣低的令人發(fā)指。

為了解決這個問題,MySQL 中引入了 change buffer。change buffer 以前并不叫這個名字,以前叫 insert buffer,即只針對 insert 操作有效,現(xiàn)在改名叫 change buffer 了,不僅僅針對 insert 有效,對 delete 和 update 操作也是有效的,change buffer 主要是對非唯一的索引有效,如果字段是唯一性索引,那么更新的時候要去檢查唯一性,依然無法避免磁盤 IO。

change buffer 就是說,當我們需要更改數(shù)據(jù)庫中的數(shù)據(jù)的時候,我們把更改記錄到內(nèi)存中,等到將來數(shù)據(jù)被讀取的時候,再將內(nèi)存中的數(shù)據(jù) merge 到 buffer pool 然后返回,此時 buffer pool 中的數(shù)據(jù)和磁盤中的數(shù)據(jù)就會有差異,有差異的數(shù)據(jù)我們稱之為臟頁,在滿足條件的時候(redo log 寫滿了、內(nèi)存寫滿了、其他空閑時候),InnoDB 會把臟頁刷新回磁盤。這種方式可以有效降低寫操作的磁盤 IO,提升數(shù)據(jù)庫的性能。

通過如下命令我們可以查看 change buffer 的大小以及哪些操作會涉及到 change buffer:

MySQL 為什么需要 redo log?

 

  • innodb_change_buffer_max_size:這個配置表示 change buffer 的大小占整個緩沖池的比例,默認值是 25%,最大值是 50%。
  • innodb_change_buffering:這個操作表示哪些寫操作會用到 change buffer,默認的 all 表示所有寫操作,我們也可以自己設(shè)置為 none/inserts/deletes/changes/purges 等。

不過 change buffer 和 buffer pool 都涉及到內(nèi)存操作,數(shù)據(jù)不能持久化,那么,當存在臟頁的時候,MySQL 如果突然掛了,就有可能造成數(shù)據(jù)丟失(因為內(nèi)存中的數(shù)據(jù)還沒寫到磁盤上),但是我們在實際使用 MySQL 的時候,其實并不會有這個問題,那么問題是怎么解決的?那就得靠 redo log 了。

4. redo log 的誕生

在正式介紹 redo log 之前,還需要給大家普及一個概念:WAL。

WAL 全稱是 Write-Ahead Logging 中文譯作預(yù)寫日志。啥意思呢?就是說 MySQL 的寫操作并不是立刻更新到磁盤上,而是先記錄在日志上,然后在合適的時間再更新到磁盤上,這樣的好處是錯開高峰期的磁盤 IO,提高 MySQL 的性能。

配合上前面的 buffer pool 和 change buffer,WAL 就是說在操作 buffer pool 和 change buffer 之前,會先把記錄寫到 redo log 日志中,然后再去更新 buffer pool 或者 change buffer,這樣,即使系統(tǒng)突然崩了,將來也可以通過 redo log 恢復(fù)數(shù)據(jù)。當然,redo log 本身又分為:

  • 日志緩沖(redo log buffer),該部分日志是易失性的。
  • 重做日志(redo log file),這是磁盤上的日志文件,該部分日志是持久的。

那有人說,寫 redo log 不就是磁盤 IO 嗎?而寫數(shù)據(jù)到磁盤也是磁盤 IO,既然都是磁盤 IO,那干嘛不把直接把數(shù)據(jù)寫到磁盤呢?還費這事!

此言差矣。

寫 redo log 跟寫數(shù)據(jù)有一個很大的差異,那就是 redo log 是順序 IO,而寫數(shù)據(jù)涉及到隨機 IO,寫數(shù)據(jù)需要尋址,找到對應(yīng)的位置,然后更新/添加/刪除,而寫 redo log 則是在一個固定的位置循環(huán)寫入,是順序 IO,所以速度要高于寫數(shù)據(jù)。

如前文所說,redo log 涉及到兩個東西:redo log buffer 和 redo log file,這兩個東西我們分別來介紹。

4.1 redo log buffer

先來說 redo log buffer。

我們說數(shù)據(jù)的變化先寫入 redo log 中,并不是上來就寫磁盤,也是先寫到內(nèi)存中,即 redo log buffer,在時機成熟時,再寫入磁盤,也就是 redo log file。

我們先來看看 redo log buffer 有多大:

MySQL 為什么需要 redo log?

 

16777216 ÷ 1024 ÷ 1024 = 16MB

可以看到,這個 redo log buffer 大小剛好是 16MB,如果你覺得這個值有點小,也可以自行修改其大小。

數(shù)據(jù)的變更都會首先記錄在這塊內(nèi)存中。小伙伴們知道,MySQL 的增刪改,如果我們沒有顯式的開啟事務(wù),MySQL 內(nèi)部也是有一個事務(wù)存在的,當內(nèi)部這個事務(wù) commit 的時候,redo log buffer 會持久化到磁盤中。

具體來說,有如下幾個持久化時機:

  1. innodb_flush_log_at_trx_commit

通過
innodb_flush_log_at_trx_commit 參數(shù)來控制持久化時機,該參數(shù)默認值為 1,如下圖:

MySQL 為什么需要 redo log?

 

當然開發(fā)者可根據(jù)自己的實際需求修改該參數(shù)。該參數(shù)有三種取值,含義分別如下:

  • 0:每秒一次,將 redo log buffer 中的數(shù)據(jù)刷新到磁盤中。
  • 1:每次 commit 時,將 redo log buffer 中的數(shù)據(jù)刷新到磁盤中,即只要 commit 成功,磁盤上就有對應(yīng)的 redo log 日志,這是最安全的情況,也是推薦使用的參數(shù)
  • 2:每次 commit 時,將 redo log buffer 中的數(shù)據(jù)刷新到操作系統(tǒng)緩存中,操作系統(tǒng)緩存中的數(shù)據(jù)每秒刷新一次,會持久化到磁盤中。

這是第一種 redo log buffer 持久化的時機。

  1. 當 redo log buffer 的使用量達到 innodb_log_buffer_size 的一半時,將其寫入磁盤成為 redo log file。
  2. MySQL 關(guān)閉時,將 redo log buffer 寫入磁盤成為 redo log file。

那如果 redo log buffer 中的數(shù)據(jù)還沒有磁盤,MySQL 就掛了該怎么辦?沒寫入磁盤,說明你還沒 commit,既然沒 commit,那就數(shù)據(jù)修改操作都還沒有完成,那只能丟了就丟了,如果已經(jīng) commit 了,那么數(shù)據(jù)就會持久化到 redo log file 中,此時即使 MySQL 掛了,將來 MySQL 重啟恢復(fù)了,數(shù)據(jù)也是可以被恢復(fù)的。具體的恢復(fù)邏輯,就涉及到兩階段提交了,這個松哥在后面的文章中再和大家詳細介紹。

4.2 redo log 落盤

還有一個需要大家注意的問題就是 redo log 落盤,落盤的數(shù)據(jù)從哪里來?是從 redo log 日志中來還是從 buffer pool 中來?

在前面的文章中我們說過:binlog 是一種邏輯日志,他里邊所記錄的是一條 SQL 語句的原始邏輯,例如給某一個字段 +1,這區(qū)別于 redo log 的物理日志,物理日志記錄的是在某個數(shù)據(jù)頁上做了什么修改。

由于 redo log 并沒有記錄數(shù)據(jù)頁的完整數(shù)據(jù),所以正常的落盤其實用不到 redo log,數(shù)據(jù)落盤的時機到了時,直接拿著將臟頁(buffer pool)持久化到磁盤中即可。

好啦,今天就和大家分享這么多,redo log 還有一些內(nèi)容,我們在后面的文章中再繼續(xù)聊~

參考資料:

  • https://www.cnblogs.com/ZhuChangwu/p/14096575.html

分享到:
標簽:redo log
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定