亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談MySQL中是如何實(shí)現(xiàn)事務(wù)提交和回滾的

 更新時(shí)間:2022年02月11日 09:50:17   作者:果子爸聊技術(shù)  
本文主要介紹了MySQL中是如何實(shí)現(xiàn)事務(wù)提交和回滾的,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

什么是事務(wù)

事務(wù)是由數(shù)據(jù)庫(kù)中一系列的訪問(wèn)和更新組成的邏輯執(zhí)行單元

事務(wù)的邏輯單元中可以是一條SQL語(yǔ)句,也可以是一段SQL邏輯,這段邏輯要么全部執(zhí)行成功,要么全部執(zhí)行失敗

舉個(gè)最常見(jiàn)的例子,你早上出去買早餐,支付寶掃碼付款給早餐老板,這就是一個(gè)簡(jiǎn)單的轉(zhuǎn)賬過(guò)程,會(huì)包含兩步

  • 從你的支付寶賬戶扣款10元
  • 早餐老板的賬戶增加10元

這兩步其中任何一部出現(xiàn)問(wèn)題,都會(huì)導(dǎo)致整個(gè)賬務(wù)出現(xiàn)問(wèn)題

  • 假如你的支付寶賬戶扣款10元失敗,早餐老板的賬戶增加成功,那你就Happy了,相當(dāng)于馬云請(qǐng)你吃早餐了,O(∩_∩)O哈哈~
  • 假如你的支付寶賬戶扣款10元成功,早餐老板的賬戶增加失敗,那你就悲劇了,早餐老板不會(huì)放過(guò)你,會(huì)讓你重新付款,相當(dāng)于你請(qǐng)馬云吃早餐了-_-?

事務(wù)就是用來(lái)保證一系列操作的原子性,上述兩步操作,要么全部執(zhí)行成功,要么全部執(zhí)行失敗

數(shù)據(jù)庫(kù)為了保證事務(wù)的原子性和持久性,引入了redo log和undo log

redo log

redo log是重做日志,通常是物理日志,記錄的是物理數(shù)據(jù)頁(yè)的修改,它用來(lái)恢復(fù)提交后的物理數(shù)據(jù)頁(yè)

在這里插入圖片描述

如上圖所示,redo log分為兩部分:

  • 內(nèi)存中的redo log Buffer是日志緩沖區(qū),這部分?jǐn)?shù)據(jù)是容易丟失的
  • 磁盤上的redo log file是日志文件,這部分?jǐn)?shù)據(jù)已經(jīng)持久化到磁盤,不容易丟失

SQL操作數(shù)據(jù)庫(kù)之前,會(huì)先記錄重做日志,為了保證效率會(huì)先寫到日志緩沖區(qū)中(redo log Buffer),再通過(guò)緩沖區(qū)寫到磁盤文件中進(jìn)行持久化,既然有緩沖區(qū)說(shuō)明數(shù)據(jù)不是實(shí)時(shí)寫到redo log file中的,那么假如redo log寫到緩沖區(qū)后,此時(shí)服務(wù)器斷電了,那redo log豈不是會(huì)丟失?

在MySQL中可以自已控制log buffer刷新到log file中的頻率,通過(guò)innodb_flush_log_at_trx_commit參數(shù)可以設(shè)置事務(wù)提交時(shí)log buffer如何保存到log file中,innodb_flush_log_at_trx_commit參數(shù)有3個(gè)值(0、1、2),表示三種不同的方式

  • 為1表示事務(wù)每次提交都會(huì)將log buffer寫入到os buffer,并調(diào)用操作系統(tǒng)的fsync()方法將日志寫入log file,這種方式的好處是就算MySQL崩潰也不會(huì)丟數(shù)據(jù),redo log file保存了所有已提交事務(wù)的日志,MySQL重新啟動(dòng)后會(huì)通過(guò)redo log file進(jìn)行恢復(fù)。但這種方式每次提交事務(wù)都會(huì)寫入磁盤,IO性能較差
  • 為0表示事務(wù)提交時(shí)不會(huì)將log buffer寫入到os buffer中,而是每秒寫入os buffer然后調(diào)用fsync()方法將日志寫入log file,這種方式在MySQL系統(tǒng)崩潰時(shí)會(huì)丟失大約1秒鐘的數(shù)據(jù)
  • 為2表示事務(wù)每次提交僅將log buffer寫入到os buffer中,然后每秒調(diào)用fsync()方法將日志寫入log file,這種方式在MySQL崩潰時(shí)也會(huì)丟失大約1秒鐘的數(shù)據(jù)

undo log

undo log是回滾日志,用來(lái)回滾行記錄到某個(gè)版本,undo log一般是邏輯日志,根據(jù)行的數(shù)據(jù)變化進(jìn)行記錄

undo log跟redo log一樣也是在SQL操作數(shù)據(jù)之前記錄的,也就是SQL操作先記錄日志,再進(jìn)行操作數(shù)據(jù)

在這里插入圖片描述

如上圖所示,SQL操作之前會(huì)先記錄redo log、undo log到日志緩沖區(qū),日志緩沖區(qū)的數(shù)據(jù)會(huì)記錄到os buffer中,再通過(guò)調(diào)用fsync()方法將日志記錄到log file中

undo log記錄的是邏輯日志,可以簡(jiǎn)單的理解為:當(dāng)insert一條記錄時(shí),undo log會(huì)記錄一條對(duì)應(yīng)的delete語(yǔ)句;當(dāng)update一條語(yǔ)句時(shí),undo log記錄的是一條與之操作相反的語(yǔ)句

當(dāng)事務(wù)需要回滾時(shí),可以從undo log中找到相應(yīng)的內(nèi)容進(jìn)行回滾操作,回滾后數(shù)據(jù)恢復(fù)到操作之前的狀態(tài)

undo日志還有一個(gè)用途就是用來(lái)控制數(shù)據(jù)的多版本(MVCC),在《InnoDB存儲(chǔ)引擎中的鎖》一文中講到MVCC是通過(guò)讀取undo日志中數(shù)據(jù)的快照來(lái)進(jìn)行多版本控制的

undo log是采用段(segment)的方式來(lái)記錄的,每個(gè)undo操作在記錄的時(shí)候占用一個(gè)undo log segment。

另外,undo log也會(huì)產(chǎn)生redo log,因?yàn)閡ndo log也要實(shí)現(xiàn)持久性保護(hù)

總結(jié)一下

MySQL中是如何實(shí)現(xiàn)事務(wù)提交和回滾的?

  • 為了保證數(shù)據(jù)的持久性,數(shù)據(jù)庫(kù)在執(zhí)行SQL操作數(shù)據(jù)之前會(huì)先記錄redo log和undo log
  • redo log是重做日志,通常是物理日志,記錄的是物理數(shù)據(jù)頁(yè)的修改,它用來(lái)恢復(fù)提交后的物理數(shù)據(jù)頁(yè)
  • undo log是回滾日志,用來(lái)回滾行記錄到某個(gè)版本,undo log一般是邏輯日志,根據(jù)行的數(shù)據(jù)變化進(jìn)行記錄
  • redo/undo log都是寫先寫到日志緩沖區(qū),再通過(guò)緩沖區(qū)寫到磁盤日志文件中進(jìn)行持久化保存
  • undo日志還有一個(gè)用途就是用來(lái)控制數(shù)據(jù)的多版本(MVCC)

簡(jiǎn)單理解就是:

  • redo log是用來(lái)恢復(fù)數(shù)據(jù)的,用于保障已提交事務(wù)的持久性
  • undo log是用來(lái)回滾事務(wù)的,用于保障未提交事務(wù)的原子性

到此這篇關(guān)于淺談MySQL中是如何實(shí)現(xiàn)事務(wù)提交和回滾的的文章就介紹到這了,更多相關(guān)MySQL 事務(wù)提交和回滾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論