事務的實現是基於資料庫的儲存引擎。不同的儲存引擎對事務的支援程度不一樣。mysql中支援事務的儲存引擎有innodb和ndb。innodb是mysql預設的儲存引擎,預設的隔離級別是rr,並且在rr的隔離級別下更進一步,通過多版本併發控制(mvcc,multiversion concurrency control )解決不可重複讀問題,加上間隙鎖(也就是併發控制)解決幻讀問題。因此innodb的rr隔離級別其實實現了序列化級別的效果,而且保留了比較好的併發效能。
事務的隔離性是通過鎖實現,而事務的原子性、一致性和永續性則是通過事務日誌實現。說到事務日誌,不得不說的就是redo和undo。
在innodb的儲存引擎中,事務日誌通過重做(redo)日誌和innodb儲存引擎的日誌緩衝(innodb log buffer)實現。事務開啟時,事務中的操作,都會先寫入儲存引擎的日誌緩衝中,在事務提交之前,這些緩衝的日誌都需要提前重新整理到磁碟上持久化,這就是dba們口中常說的「日誌先行」(write-ahead logging)。當事務提交之後,在buffer pool中對映的資料檔案才會慢慢重新整理到磁碟。此時如果資料庫崩潰或者宕機,那麼當系統重啟進行恢復時,就可以根據redo log中記錄的日誌,把資料庫恢復到崩潰前的乙個狀態。未完成的事務,可以繼續提交,也可以選擇回滾,這基於恢復的策略而定。
在系統啟動的時候,就已經為redo log分配了一塊連續的儲存空間,以順序追加的方式記錄redo log,通過順序io來改善效能。所有的事務共享redo log的儲存空間,它們的redo log按語句的執行順序,依次交替的記錄在一起。如下乙個簡單示例:
記錄1:
記錄2:
記錄3:
記錄4:
記錄5:
undo log主要為事務的回滾服務。在事務執行的過程中,除了記錄redo log,還會記錄一定量的undo log。undo log記錄了資料在每個操作前的狀態,如果事務執行過程中需要回滾,就可以根據undo log進行回滾操作。單個事務的回滾,只會回滾當前事務做的操作,並不會影響到其他的事務做的操作。
以下是undo+redo事務的簡化過程
假設有2個數值,分別為a和b,值為1,2
1. start transaction;
2. 記錄 a=1 到undo log;
3. update a = 3;
4. 記錄 a=3 到redo log;
5. 記錄 b=2 到undo log;
6. update b = 4;
7. 記錄b = 4 到redo log;
8. 將redo log重新整理到磁碟
9. commit
在1-8的任意一步系統宕機,事務未提交,該事務就不會對磁碟上的資料做任何影響。如果在8-9之間宕機,恢復之後可以選擇回滾,也可以選擇繼續完成事務提交,因為此時redo log已經持久化。若在9之後系統宕機,記憶體對映中變更的資料還來不及刷回磁碟,那麼系統恢復之後,可以根據redo log把資料刷回磁碟。
所以,redo log其實保障的是事務的永續性和一致性,而undo log則保障了事務的原子性。
參考連線:
mysql 事務的日誌
redo 重做 記錄的是,記憶體資料頁的變化過程1 作用在事務acid過程中,實現的是 d 持久化的作用。2 工作原理 1.修改資料時 1 首先資料會從磁碟取出,載入到記憶體的data buffer page 2 運算元據,使用update語句修改資料,資料 2 變成 1 3 id 2變成id 1的...
MySQL 事務日誌
首先,事務日誌分為redo log和undo log兩種。它兩的職責主要是負責保證事務的acid特性。mysql innodb引擎借助重做日誌redo和回滾日誌undoinnodb,通過force log at commit機制實現事務的永續性。即在事務提交的時候,必須先將該事務的所有事務日誌寫入到...
mysql 日誌 事務日誌
事務性引擎依靠事務日誌保證acid 原子性,一致性,隔離性,永續性 因此事務日誌,最主要是保證事務可靠性的 事務日誌工作原理 事務日誌的每一行都是一條資訊,一般記錄事務id號,用於記錄哪個事務產生的id資訊,其次,他影響了哪個庫的哪個表,再次他原始資料,和新的資料。一般對於刪除表的操作drop ta...