1、undo log
undo log 是為了實現事務的原子性,在mysql資料庫innodb儲存引擎中,還用undo log來實現多版本併發控制(簡稱:mvcc)。
事務的原子性(atomicity)
事務中的所有操作,要麼全部完成,要麼不做任何操作,不能只做部分操作。如果在執行的過程中發生了錯誤,要回滾(rollback)到事務開始前的狀態,就像這個事務從來沒有執行過。
原理簡介
undo log的原理很簡單,為了滿足事務的原子性,在操作任何資料之前,首先將資料備份到乙個地方(這個儲存資料備份的地方稱為undo log)。然後進行資料的修改。如果出現了錯誤或者使用者執行了rollback語句,系統可以利用undo log中的備份將資料恢復到事務開始之前的狀態。
除了可以保證事務的原子性,undo log也可以用來輔助完成事務的持久化。
事務的永續性(durability)
事務一旦完成,該事務對資料庫所做的所有修改都會持久的儲存到資料庫中。為了保證永續性,資料庫系統會將修改後的資料完全的記錄到持久的儲存上。
用undo log實現原子性和持久化的事務的簡化過程,假設有a、b兩個資料,值分別為1,2,事務過程如下:
a.事務開始.
b.記錄a=1到undo log.
c.修改a=3.
d.記錄b=2到undo log.
e.修改b=4.
f.將undo log寫到磁碟。
g.將資料寫到磁碟。
h.事務提交
這裡有乙個隱含的前提條件:『資料都是先讀到記憶體中,然後修改記憶體中的資料,最後將資料寫回磁碟』。
之所以能同時保證原子性和持久化,是因為以下特點:
a. 更新資料前記錄undo log。
b. 為了保證永續性,必須將資料在事務提交前寫到磁碟。只要事務成功提交,資料必然已經持久化。
c. undo log必須先於資料持久化到磁碟。如果在g,h之間系統崩潰,undo log是完整的,可以用來回滾事務。
d. 如果在a-f之間系統崩潰,因為資料沒有持久化到磁碟。所以磁碟上的資料還是保持在事務開始前的狀態。
缺陷:每個事務提交前將資料和undo log寫入磁碟,這樣會導致大量的磁碟io,因此效能很低。
如果能夠將資料快取一段時間,就能減少io提高效能。但是這樣就會喪失事務的永續性。因此引入了另外一種機制來實現持久化,即redo log.
2、redo log
原理
和undo log相反,redo log記錄的是新資料的備份。在事務提交前,只要將redo log持久化即可,不需要將資料持久化。當系統崩潰時,雖然資料沒有持久化,但是redo log已經持久化。系統可以根據redo log的內容,將所有資料恢復到最新的狀態。
undo + redo事務的簡化過程,假設有a、b兩個資料,值分別為1,2.
a.事務開始.
b.記錄a=1到undo log.
c.修改a=3.
d.記錄a=3到redo log.
e.記錄b=2到undo log
f.修改b=4.
g.記錄b=4到redo log.
h.將redo log寫入磁碟。
i.事務提交
undo + redo事務的特點
a. 為了保證永續性,必須在事務提交前將redo log持久化。
b. 資料不需要在事務提交前寫入磁碟,而是快取在記憶體中。
c. redo log保證事務的永續性。
d. undo log保證事務的原子性。
e. 有乙個隱含的特點,資料必須要晚於redo log寫入持久儲存。
io效能簡介:
undo + redo的設計主要考慮的是提公升io效能。雖說通過快取資料,減少了寫資料的io。但是卻引入了新的io,即寫redo log的io。如果redo log的io效能不好,就不能起到提高效能的目的。
為了保證redo log能夠有比較好的io效能,innodb 的 redo log的設計有以下幾個特點:
a. 盡量保持redo log儲存在一段連續的空間上。因此在系統第一次啟動時就會將日誌檔案的空間完全分配。以順序追加的方式記錄redo log,通過順序io來改善效能。
b. 批量寫入日誌。日誌並不是直接寫入檔案,而是先寫入redo log buffer.當需要將日誌重新整理到磁碟時 (如事務提交),將許多日誌一起寫入磁碟.
c. 併發的事務共享redo log的儲存空間,它們的redo log按語句的執行順序,依次交替的記錄在一起,以減少日誌占用的空間。例如,redo log中的記錄內容可能是這樣的
記錄1:
記錄2:
記錄3:
記錄4:
記錄5:
d. 因為c的原因,當乙個事務將redo log寫入磁碟時,也會將其他未提交的事務的日誌寫入磁碟。
e. redo log上只進行順序追加的操作,當乙個事務需要回滾時,它的redo log記錄也不會從redo log中刪除掉。
3、恢復(recovery)
恢復策略
前面說到未提交的事務和回滾了的事務也會記錄redo log,因此在進行恢復時,這些事務要進行特殊的的處理。有2中不同的恢復策略:
a. 進行恢復時,只重做已經提交了的事務。
b. 進行恢復時,重做所有事務包括未提交的事務和回滾了的事務。然後通過undo log回滾那些未提交的事務。
innodb儲存引擎的恢復機制
mysql資料庫innodb儲存引擎使用了b策略, innodb儲存引擎中的恢復機制有幾個特點:
a. 在重做redo log時,並不關心事務性。 恢復時,沒有begin,也沒有commit,rollback的行為。也不關心每個日誌是哪個事務的。儘管事務id等事務相關的內容會記入redo log,這些內容只是被當作要操作的資料的一部分。
b. 使用b策略就必須要將undo log持久化,而且必須要在寫redo log之前將對應的undo log寫入磁碟。
undo和redo log的這種關聯,使得持久化變得複雜起來。為了降低複雜度,innodb將undo log看作資料,因此記錄undo log的操作也會記錄到redo log中。這樣undo log就可以象資料一樣快取起來, 而不用在redo log之前寫入磁碟了。
包含undo log操作的redo log,看起來是這樣的:
記錄1: >
記錄2:
記錄3: >
記錄4:
記錄5: >
記錄6:
c. 到這裡,還有乙個問題沒有弄清楚。既然redo沒有事務性,那豈不是會重新執行被回滾了的事務?
確實如此,同時innodb也會將事務回滾時的操作也記錄到redo log中。回滾操作本質上也是對資料進行修改,因此回滾時對資料的操作也會記錄到redo log中。
乙個回滾了的事務的redo log,看起來是這樣的:
記錄1: >
記錄2:
記錄3: >
記錄4:
記錄5: >
記錄6:
記錄7:
記錄8:
記錄9:
乙個被回滾了的事務在恢復時的操作就是先redo再undo,因此不會破壞資料的一致性。
innodb引擎redo檔案維護
如果要對innodb的redo日誌檔案的大小與個數進行調整可以採用如下步驟 1 關閉mysql mysqladmin h127.0.0.1 p3306 uroot p shutdown 2 修改配置檔案中的innodb log file size innodb log files in group ...
InnoDB和MyISAM儲存引擎
mysql在檔案系統中將每個資料庫 也可以叫 schema 儲存為資料庫目錄下的乙個子目錄。建立表時,mysql會在資料庫子目錄下建立乙個和表同名的.frm檔案儲存表的定義。而 mysql會在資料庫子目錄下建立乙個和表同名的.frm檔案儲存表的定義。如 建立乙個名為a的表,mysql會在a.frm檔...
InnoDB 儲存引擎
innodb是事務型資料庫的首選引擎,支援事務安全表 acid 支援行鎖定和外來鍵。mysql 5.5.5 之後,innodb作為預設儲存引擎。innodb的主要特性有一下幾項。a.innodb給mysql提供了具有提交 回滾和崩潰恢復能力的事務安全 acid相容 儲存引擎。innodb鎖定在行級並...