日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL日志:binlog、事务日志(redo、undo)

發(fā)布時間:2023/12/3 数据库 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL日志:binlog、事务日志(redo、undo) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

事務(wù)的隔離性是通過鎖實現(xiàn),而事務(wù)的原子性、一致性和持久性則是通過日志實現(xiàn)。Mysql的日志可以分為:

  • binlog:server層實現(xiàn)
  • 事務(wù)日志:包括redo log、undo log,引擎層(innodb)實現(xiàn)

redo log

redo log是用于備份事務(wù)中操作得到的最新數(shù)據(jù)的地方,記錄數(shù)據(jù)頁的物理修改。

redo log通常是物理日志,記錄的是數(shù)據(jù)頁的物理修改,而不是記錄某一行或某幾行的修改,它用來恢復(fù)提交后的物理數(shù)據(jù)頁(恢復(fù)數(shù)據(jù)頁,且只能恢復(fù)到最后一次提交的位置)。

在innoDB的存儲引擎中,事務(wù)日志通過重做日志(redo log)和innoDB存儲引擎的日志緩沖(redo Log Buffer)實現(xiàn)。事務(wù)開啟時,事務(wù)中的操作,都會先寫入存儲引擎的日志緩沖中,在事務(wù)提交之前,這些緩沖的日志都需要提前刷新到磁盤上持久化,這就是DBA們口中常說的“日志先行”(Write-Ahead Logging)。當(dāng)事務(wù)提交之后,在Buffer Pool中映射的數(shù)據(jù)文件才會慢慢刷新到磁盤。此時如果數(shù)據(jù)庫崩潰或者宕機(jī),那么當(dāng)系統(tǒng)重啟進(jìn)行恢復(fù)時,就可以根據(jù)redo log中記錄的日志,把數(shù)據(jù)庫恢復(fù)到崩潰前的一個狀態(tài)。未完成的事務(wù),可以繼續(xù)提交,也可以選擇回滾,這基于恢復(fù)的策略而定。

即事務(wù)在修改數(shù)據(jù)時,innodb只修改數(shù)據(jù)的內(nèi)存拷貝,然后把修改行為記錄到持久在磁盤的事務(wù)日志(redo log)中,在事務(wù)日志持久化后,內(nèi)存中被修改的數(shù)據(jù)在后臺慢慢刷回磁盤。
即修改數(shù)據(jù)時需要寫兩次磁盤:

  • 先將操作記錄到redo log buffer,然后持久化redo log到磁盤
  • 將redo log中記錄的數(shù)據(jù)持久化到磁盤

為什么需要redo log(為什么采用兩次寫磁盤,而不直接持久化新數(shù)據(jù)?)

既然redo log是將數(shù)據(jù)持久化到磁盤上,那么必然也對應(yīng)一次IO操作,那么每次修改數(shù)據(jù)直接將其刷新到磁盤的話,也是一次IO操作,按道理說效率應(yīng)該一樣,那么為什么還要引入redo log?
事實上,redo log寫入文件尾是順序?qū)戇^程,雖然也是一次IO操作但磁頭不需要移動(即事務(wù)日志采用追加的方式,因此是順序IO)。而每次都將數(shù)據(jù)更新到磁盤其實是將 buffer pool中的數(shù)據(jù)緩存頁寫入磁盤的數(shù)據(jù)也中,其中涉及到要尋找數(shù)據(jù)頁在哪的操作,這是一個隨機(jī)寫過程,需要移動磁頭,磁盤的隨機(jī)寫過程更耗時,耗資源,因此引入redo log是很有必要的。

undo log

undo log是用于事務(wù)中,在操作數(shù)據(jù)之前,備份需操作的數(shù)據(jù)的地方,undo log 記錄數(shù)據(jù)的邏輯修改。

undo log用來實現(xiàn)事務(wù)的原子性,在innodb引擎中還用來實現(xiàn)事務(wù)的多版本并發(fā)控制。
undo log記錄了數(shù)據(jù)在每個操作前的狀態(tài),如果事務(wù)執(zhí)行過程中需要回滾,就可以根據(jù)undo log進(jìn)行回滾操作。單個事務(wù)的回滾,只會回滾當(dāng)前事務(wù)做的操作,并不會影響到其他的事務(wù)做的操作。
在操作數(shù)據(jù)庫之前先將數(shù)據(jù)備份到一個地方,這個存儲數(shù)據(jù)備份的地方就是undo log。然后再進(jìn)行數(shù)據(jù)的修改,如果中途發(fā)生錯誤或者用戶執(zhí)行的rollback語句,系統(tǒng)就可以利用undo log中的備份將數(shù)據(jù)回復(fù)到事務(wù)開始前的狀態(tài)。

undo log 是邏輯日志,可以理解為每次操作之前都會記錄相反反操作:

  • 當(dāng)delect一條語句時,undo log 中會記錄一條對應(yīng)的insert語句
  • 當(dāng)insert一條語句時,undo log 中會記錄一條對應(yīng)的delect語句
  • 當(dāng)update一條語句時,undo log 中會記錄一條相反的update語句

undo+redo事務(wù)的簡化過程

假設(shè)有2個數(shù)值,分別為A和B,值為1,2

1. start transaction;2. 記錄 A=1 到undo log;3. update A = 3;4. 記錄 A=3 到redo log buffer;5. 記錄 B=2 到undo log;6. update B = 4;7. 記錄B = 4 到redo log buffer;8. 將redo log buffer 刷新到磁盤9. 執(zhí)行器(Server層)生成寫操作的binlog日志,并將binlog寫入磁盤(通過XA事務(wù)保證redo log 和 binlog的一致性)10. commit

在1-8的任意一步系統(tǒng)宕機(jī),事務(wù)未提交,該事務(wù)就不會對磁盤上的數(shù)據(jù)做任何影響。如果在8-10之間宕機(jī),恢復(fù)之后可以選擇回滾,也可以選擇繼續(xù)完成事務(wù)提交,因為此時redo log已經(jīng)持久化。若在10之后系統(tǒng)宕機(jī),內(nèi)存映射中變更的數(shù)據(jù)還來不及刷回磁盤,那么系統(tǒng)恢復(fù)之后,可以根據(jù)redo log把數(shù)據(jù)刷回磁盤。
所以,redo log其實保障的是事務(wù)的持久性和一致性,而undo log則保障了事務(wù)的原子性

binlog

binlog是server層的日志,記錄所有數(shù)據(jù)庫表結(jié)構(gòu)變更(例如CREATE、ALTER TABLE…)以及表數(shù)據(jù)修改(INSERT、UPDATE、DELETE…)的二進(jìn)制日志。
當(dāng)執(zhí)行寫操作的SQL(INSERT、UPDATE、DELETE…)時,會把相應(yīng)的SQL寫入到對應(yīng)的binlog,可以簡單理解為binlog是記錄數(shù)據(jù)庫增刪改,不記錄查詢的二進(jìn)制日志,可以利用binlog進(jìn)行備份、數(shù)據(jù)恢復(fù)。

binlog的三種模式

(1)Row Level 行模式

日志中會記錄每一行數(shù)據(jù)被修改的形式,然后在slave端再對相同的數(shù)據(jù)進(jìn)行修改

  • 優(yōu)點:在row level模式下,bin-log中可以不記錄執(zhí)行的sql語句的上下文相關(guān)的信息,僅僅只需要記錄那一條被修改。所以rowlevel的日志內(nèi)容會非常清楚的記錄下每一行數(shù)據(jù)修改的細(xì)節(jié)。不會出現(xiàn)某些特定的情況下的存儲過程或function,以及trigger的調(diào)用和觸發(fā)無法被正確復(fù)制的問題
  • 缺點:row level,所有的執(zhí)行的語句當(dāng)記錄到日志中的時候,都將以每行記錄的修改來記錄,會產(chǎn)生大量的日志內(nèi)容。

(2)Statement Level(默認(rèn))

每一條會修改數(shù)據(jù)的sql都會記錄到master的bin-log中。slave在復(fù)制的時候sql進(jìn)程會解析成和原來master端執(zhí)行過的相同的sql來再次執(zhí)行

  • 優(yōu)點:statement level下的優(yōu)點首先就是解決了row level下的缺點,不需要記錄每一行數(shù)據(jù)的變化,減少bin-log日志量,節(jié)約IO,提高性能,因為它只需要在Master上鎖執(zhí)行的語句的細(xì)節(jié),以及執(zhí)行語句的上下文的信息。
  • 缺點:由于只記錄語句,所以,在statement level下 已經(jīng)發(fā)現(xiàn)了有不少情況會造成Mysql的復(fù)制出現(xiàn)問題,主要是修改數(shù)據(jù)的時候使用了某些定的函數(shù)或者功能的時候會出現(xiàn)。

(3) Mixed 自動模式

在Mixed模式下,MySQL會根據(jù)執(zhí)行的每一條具體的sql語句來區(qū)分對待記錄的日志格式,也就是在Statement和Row之間選擇一種。如果sql語句確實就是update或者delete等修改數(shù)據(jù)的語句,那么還是會記錄所有行的變更。

binlog與redolog 的區(qū)別

  • binlog主要用于備份、主從同步;redo log用于實現(xiàn)事務(wù)的一致性和持久性,防止數(shù)據(jù)丟失。
  • redo log 是innodb引擎特有的,而binlog由服務(wù)層實現(xiàn)是所有存儲引擎都可以使用的
  • redo log是物理日志,記錄的是某頁上具體的做的修改。binlog是邏輯日志,記錄的是這個語句的原始邏輯。
  • redo log是循環(huán)寫過程,空間有限,空間不夠時會覆蓋之前的信息。binlog是追加寫過程不會覆蓋之前的信息。

執(zhí)行器(Server)和InnoDB引擎在執(zhí)行update內(nèi)部流程

1、執(zhí)行器先找到ID=2這一行,ID是主鍵,引擎用樹搜索找到這一行,如果ID=2這一行所在的數(shù)據(jù)頁本來就在內(nèi)存中,就直接返回給執(zhí)行器。否則需要從磁盤中讀入磁盤中,然后再返回。

2、執(zhí)行器拿到引擎給的行數(shù)據(jù),把這個值加上1,得到一行新的數(shù)據(jù),再調(diào)用引擎接口,寫入這行數(shù)據(jù)。

3、引擎將這行新的數(shù)據(jù)寫入到內(nèi)存中,同時將這個更新操作記錄到redo log里面,此時redo log處于prepare狀態(tài),然后告知執(zhí)行器執(zhí)行完成了,隨時可以提交事務(wù)。

4、執(zhí)行器生成這個操作的binlog日志,并將binlog寫入磁盤。

5、執(zhí)行器調(diào)用引擎的提交事務(wù)的接口,引擎把剛剛寫入的redo log改成提交(commit)狀態(tài),更新完成。

binlog 和 redo log一致性

此部分為引用,詳細(xì)請閱讀:MySQL中binlog和redo log的一致性問題

在MySQL內(nèi)部,在事務(wù)提交時利用兩階段提交(內(nèi)部XA的兩階段提交)很好地解決了binlog和redo log的一致性問題:

  • 第一階段: InnoDB Prepare階段。此時SQL已經(jīng)成功執(zhí)行,并生成事務(wù)ID(xid)信息及redo和undo的內(nèi)存日志。此階段InnoDB會寫事務(wù)的redo log,但要注意的是,此時redo log只是記錄了事務(wù)的所有操作日志,并沒有記錄提交(commit)日志,因此事務(wù)此時的狀態(tài)為Prepare。此階段對binlog不會有任何操作。
  • 第二階段:commit 階段,這個階段又分成兩個步驟。第一步寫binlog(先調(diào)用write()將binlog內(nèi)存日志數(shù)據(jù)寫入文件系統(tǒng)緩存,再調(diào)用fsync()將binlog文件系統(tǒng)緩存日志數(shù)據(jù)永久寫入磁盤);第二步完成事務(wù)的提交(commit),此時在redo log中記錄此事務(wù)的提交日志(增加commit 標(biāo)簽)。

可以看出,此過程中是先寫redo log再寫binlog的。但需要注意的是,在第一階段并沒有記錄完整的redo log(不包含事務(wù)的commit標(biāo)簽),而是在第二階段記錄完binlog后再寫入redo log的commit 標(biāo)簽。還要注意的是,在這個過程中是以第二階段中binlog的寫入與否作為事務(wù)是否成功提交的標(biāo)志。

通過上述MySQL內(nèi)部XA的兩階段提交就可以解決binlog和redo log的一致性問題。數(shù)據(jù)庫在上述任何階段crash,主從庫都不會產(chǎn)生不一致的錯誤。

參考

  • 推薦閱讀:MYSQL中的事務(wù)日志
  • 推薦閱讀:日志系統(tǒng):redo log和binlog
  • 好文:MySQL中的事務(wù)日志
  • 詳細(xì)分析MySQL事務(wù)日志(redo log和undo log)
  • MySQL binlog三種模式
  • 深入理解MySQL之redo日志

總結(jié)

以上是生活随笔為你收集整理的MySQL日志:binlog、事务日志(redo、undo)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。