MySQL實現事務的提交和回滾
什麼是事務?
事務是資料庫中一系列的訪問和更新組成的邏輯執行單元,事務的邏輯單元中可以是一條SQL語句,也可以是一段SQL邏輯,這段邏輯要麼全部執行成功,要麼全部執行失敗。
也就是說事務就是用來保證一系列操作的原子性,
資料庫為了保證事務的原子性和永續性,引入了redo log 和 undo log
redo log
redo log是重做日誌,是物理日誌,記錄的是物理資料頁的修改,它用來恢復叫後的物理資料頁,
redo log 分為兩部分:
-
記憶體中的redo log buffer是日誌緩衝區,這部分資料容易丟失
-
磁碟中的redo log file是日誌檔案,這部分資料已經持久化磁碟,不容易丟失
SQL運算元據庫之前,會先記錄重做日誌,為了保證效率會先寫到日誌緩衝區中(redo log buffer),再通過緩衝區寫到磁碟檔案中進行持久化,存在緩衝區就說明資料不是實時的寫到redo log file 中,在這時伺服器突然斷電,那麼redo log會丟失資料。
在MySQL中可以自己控制 redo log buffer 重新整理到log file中的頻率,通過innodb_flush_log_trx_commit引數可以設定事務提交的log buffer 如何儲存到log file中,innodb_flush_log_trx_commit引數有三個值(0,1,2) -
為1表示事務每次提交都會將log buffer寫入到os buffer,並呼叫作業系統的fsync()方法將日誌寫入log file,這種方式的好處是就算MySQL崩潰也不會丟資料,redo log file儲存了所有已提交事務的日誌,MySQL重新啟動後會通過redo log file進行恢復。但這種方式每次提交事務都會寫入磁碟,IO效能較差
-
為0表示事務提交時不會將log buffer寫入到os buffer中,而是每秒寫入os buffer然後呼叫fsync()方法將日誌寫入log file,這種方式在MySQL系統崩潰時會丟失大約1秒鐘的資料
-
為2表示事務每次提交僅將log buffer寫入到os buffer中,然後每秒呼叫fsync()方法將日誌寫入log file,這種方式在MySQL崩潰時也會丟失大約1秒鐘的資料
undo log
undo log 是回滾日誌,用來回滾行記錄到一個版本,undo log一般是邏輯日誌,根據行的資料變化進行記錄
undo log 跟redo log一樣也是在SQL運算元據之前記錄的,也就是SQL操作先記錄日誌,在進行運算元據
如上圖所示,SQL操作之前會先記錄redo log、undo log到日誌緩衝區,日誌緩衝區的資料會記錄到os buffer中,再通過呼叫fsync()方法將日誌記錄到log file中
undo log記錄的是邏輯日誌,可以簡單的理解為:當insert一條記錄時,undo log會記錄一條對應的delete語句;當update一條語句時,undo log記錄的是一條與之操作相反的語句
當事務需要回滾時,可以從undo log中找到相應的內容進行回滾操作,回滾後資料恢復到操作之前的狀態
undo日誌還有一個用途就是用來控制資料的多版本(MVCC),在《InnoDB儲存引擎中的鎖》一文中講到MVCC是通過讀取undo日誌中資料的快照來進行多版本控制的
undo log是採用段(segment)的方式來記錄的,每個undo操作在記錄的時候佔用一個undo log segment。
另外,undo log也會產生redo log,因為undo log也要實現永續性保護
總結一下
MySQL中如何實現事務提交和回滾的?
- 為了保證資料的持久化,資料庫在執行SQL運算元據之前會先記錄redo log和undo log
- redo log 是重做日誌,通常物理日誌,記錄的是物理資料頁的修改,它用來恢復提交後的物理資料頁
- undo log是回滾日誌,用來會滾滾行記錄到一個版本,undo log一般是邏輯日誌,根據行的資料變化進行記錄
- redo、undo log 都是寫先寫到日誌緩衝區,在通過緩衝區寫到磁碟日誌檔案中進行持久化儲存
- undo日誌還有一個用途就是用來控制資料的多版本
簡單的理解:
redo log是用來恢復資料的,用於保障已提交事務的持久化
undo log是用來回滾事務的,使用者保障未提交事務的原子性
相關文章
- MySql事務無法回滾的原因有哪些MySql
- sqlserver遇到回滾事務的操作策略SQLServer
- MySQL事務兩段式提交MySql
- 不能回滾的Redis事務還能用嗎Redis
- 關於事務回滾註解@Transactional
- T-SQL——關於事務回滾的方式SQL
- Spring事務不能回滾的深層次原因Spring
- MySQL事務實現原理MySql
- 事務單獨提交和
- MySQl事務建立,開始以及提交MySql
- Spring Data JPA中事務回滾意外RollbackExceptionSpringException
- 關於ORACLE大型事務回滾的幾個點Oracle
- mysql複製那點事(2)-binlog組提交原始碼分析和實現MySql原始碼
- MySQL是如何實現事務的ACIDMySql
- 客戶端登陸logout操作,事務回滾客戶端Go
- MySQL事務提交的三個階段介紹MySql
- sourceTree“重置提交”和“提交回滾”的區別
- IDEA程式碼不想提交了,如何回滾Idea
- Git回滾本地已提交未推送的程式碼Git
- MySQL 的索引和事務MySql索引
- MySQL:begin後事務為什麼不提交MySql
- openGauss 子事務併發回滾流程最佳化
- 如何實現跨Mysql、Redis和Mongo分散式事務? - dongfuMySqlRedisGo分散式
- 利用oracle的日誌挖掘實現回滾Oracle
- 事務可見性的判斷和事務隔離級別,PostgreSQL和MySQL實現上有啥區別MySql
- 面試題:MySQL事務的ACID如何實現?面試題MySql
- 【Mysql核心技術】聊聊事務的實現原理MySql
- 搞懂MySQL InnoDB事務ACID實現原理MySql
- 命令(XA ROLLBACK) 讓儲存叢集回滾GT 的事務分支
- mysql隱式提交事務transaction一點筆記MySql筆記
- spring事務增強,事務回滾如何判斷?希望在前端上有個提示Spring前端
- MySQL中的事務和MVCCMySqlMVC
- MySQL 事務和鎖MySql
- MySQL事務和鎖MySql
- Spring中的事務提交事件Spring事件
- Oracle vs PostgreSQL,研發注意事項(3)- 事務回滾之UPDATE操作解析OracleSQL
- MySQL資料庫事務隔離性的實現MySql資料庫
- MySQL 中基於 XA 實現的分散式事務MySql分散式