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是用來回滾事務的,使用者保障未提交事務的原子性
相關文章
- java 事務提交/回滾Java
- 在SQL SERVER中實現事務的部分回滾SQLServer
- MySql事務無法回滾的原因有哪些MySql
- ORACLE 死事務的回滾Oracle
- SQL Server 事務及回滾事務SQLServer
- 【web】Spring中使用DataSourceTransactionManager手動提交或回滾事務WebSpring
- 探究MySQL的DML提交事務的意義和DQL是否有必要提交事務MySql
- Oracle提交和回滾處理Oracle
- oracle檢視回滾的事務Oracle
- sqlserver遇到回滾事務的操作策略SQLServer
- Spring事務回滾情況Spring
- MySQL事務兩段式提交MySql
- MySQL 事務提交過程MySql
- 不能回滾的Redis事務還能用嗎Redis
- DBUNITS的單元測試事務回滾
- WebForm中C#事務回滾的例子WebORMC#
- 檢視mysql沒提交的事務MySql
- MySQL innodb 事務的實現MySql
- 關於事務回滾註解@Transactional
- MySQL事務提交流程概述MySql
- 關於Spring事務回滾的問題Spring
- long長事務回滾的模擬與定位
- T-SQL——關於事務回滾的方式SQL
- MySQL事務實現原理MySql
- JDBC 事務(二)回滾到儲存點JDBC
- MySQl事務建立,開始以及提交MySql
- Spring事務不能回滾的深層次原因Spring
- 關於ORACLE大型事務回滾的幾個點Oracle
- Spring Transaction詳解 – 手動回滾事務Spring
- zt_Oracle事務rollback回滾時間估算Oracle
- Spring Data JPA中事務回滾意外RollbackExceptionSpringException
- Spring分散式事務XA事務(兩段提交2PC)實現Spring分散式
- MySQL事務提交的三個階段介紹MySql
- MySQL是如何實現事務的ACIDMySql
- 使用FLASHBACK_TRANSACTION_QUERY查詢回滾事務SQLSQL
- MySQL 的索引和事務MySql索引
- mysql複製那點事(2)-binlog組提交原始碼分析和實現MySql原始碼
- sourceTree“重置提交”和“提交回滾”的區別