事務的實現-redo log和undo log來完成

事務

InnoDB中的事務完全符合ACID特性:

  • 原子性(atomicity)
  • 一致性(consistency)
  • 隔離性(isolation)
  • 持久性(durability)

通過在事務中使用SAVE WORK函數可以建立保存點。保存點可以通過ROLLBACK WORK: n來回滾。

事務的實現

事務的隔離性由上一章講的鎖來實現。原子性、一致性、持久性通過數據庫的redo log和undo log來完成。redo log稱爲重做日誌,用來保證事務的原子性和持久性;undo log用來保證事務的一致性。

redo log和undo log不是相互的逆過程,redo log是物理日誌,而undo log是操作的逆向操作,是邏輯日誌。

redo

redo log是用來實現事務的持久性,即ACID中的D,由內存中的redo log buffer和磁盤的redo log file組成。

當事務提交時,必須將所有日誌寫入重做日誌文件進行持久化,待事務的COMMIT操作完成纔算完成。重做日誌指的是redo log和undo log,redo log是用來保證事務的喫就行,undo log用來幫助事務回滾及MVCC的功能。redo log基本順序寫,而undo log是需要進行隨機讀寫的。

在每次將重做日誌緩衝寫入重做日誌文件後,InnoDB都調用一次fsync操作,確保日誌寫入重做日誌文件。磁盤性能決定了事務提交的性能。

在數據庫中還有一種二進制日誌(binlog),用來進行POINT-IN-TIME的恢復和主從複製環境的建立。redo log是在InnoDB存儲引擎層產生,bin log是在MySQL數據庫的上層產生,並且不只是對InnoDB引擎的;同時bin log是邏輯日誌,記錄的是對應的SQL語句,redo log是物理格式的日誌,記錄的是每個頁的修改;binlog只在事務提交完成後一次寫入,redo log在事務進行中不斷地被寫入,因此redo log不是隨事務提交的順序進行寫入的。

redo log是物理日誌,因此它是冪等的,而bin log由於是邏輯日誌,如INSERT等操作不是冪等的,所以它不能被重複執行。

undo

在對數據庫進行修改時,InnoDB存儲引擎不但會產生redo,還會產生一定量的undo。這樣如果用戶執行的事務或語句由於某種原因失敗了,又或者用戶用一條ROLLBACK語句請求回滾,就可以利用這些undo信息將數據回滾到修改之前的樣子。

與redo log放在文件不同,undo放在數據庫內部的一個特殊段中,稱爲undo段,位於共享表空間中。

undo是邏輯日誌,回滾時修改會被邏輯地取消,數據結構和頁本身在回滾之後可能不太相同,因爲這個過程中可能有其他併發的事務,因此不能將一個頁回滾到事務開始的樣子。InnoDB回滾時實際上是做與之前相反的工作,例如對於INSERT會回滾一個DELETE操作。

undo除了回滾以外的另一個作用是MVCC,若記錄被其他事務佔用,當前事務可以通過undo讀取之前的行版本信息,以此實現非鎖定讀。

undo log會產生redo log,因爲undo log也需要持久性的保護。

事務提交後不能馬上刪除undo log及undo log所在的頁,因爲可能還有其他事務需要通過undo log得到行記錄之前的版本。事務提交時會將undo log放入一個鏈表,是否可刪除由purge線程來判斷。

purge

DELETE FROM t WHERE a=1;

DELETE操作僅是將主鍵列中等於1的記錄delete flag設爲1,記錄還存在在B+樹上。purge用於最終完成delete和update操作,因爲MVCC所以記錄不能立即處理。若該行記錄已經不被其他任何事務引用,那麼就可以進行真正的DELETE操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章