java面試一日一題:講下mysql中的undolog

問題:請講下mysql中undo log的作用

分析:mysql中有很多日誌,例,bin log undo log redo log,要弄清楚這些日誌的作用,就要了解這些日誌出現的背景及要解決的問題;

回答要點:

主要從以下幾點去考慮

1、undo log產生的背景;

2、undo log的作用;

 

開發中經常使用到mysql數據庫,用mysql數據庫時在新建庫或表的時候,最常使用的存儲引擎是innodb,在innodb中經常提到事務,那麼事務是怎麼實現的,可參見:《java面試一日一題:mysql事務是如何實現的》,事務實現的基礎是undo log,由於常用的引擎有innodb和myIsam,在這兩種引擎中innodb支持事務,而myIsam不支持事務,所以undo log是innodb特有的(redo log也是innodb特有)。

既然undo log和事務有關,那麼undo log是什麼那,顧名思義,undo是不做的意思,在mysql中叫做回滾日誌,回滾的意思是撤銷之前的操作,那麼對應到mysql中就是一條insert語句對應到undo log就是一條delete語句,delete語句就是insert語句,update語句還是update只不過數據是之前的數據,這就是undo log中記錄的日誌內容。

上面了解到undo log是回滾日誌,和回滾相干,既然是回滾那麼必然要回退到之前的版本,所以在undo log中記錄的就是和要執行的操作相反的操作。undo中就是記錄了如果事務需要回滾的情況下要執行的操作,這是undo log的第一個作用

我們知道在innodb下會為每條記錄生成三列,trasaction_id、roll_pointer、row_id(如果表中沒有主鍵的情況下),其中roll_pointer會指向當前記錄的下個版本的地址,這個版本的數據會存儲在undo log中,如下圖

從上圖可以看到當前數據記錄的score值為90,在undo log中還有兩個版本的數據分別是45和87,在mysql默認的隔離級別可重複讀中,就可以利用undo log中保存的版本記錄,做到讀寫並發,提高性能,這種技術叫做MVCC,在可重複讀級別下,同一個事務中多次讀取操作,都是使用的第一次select語句開始時的traction_id,做到可重複讀。針對普通的查詢操作,例,select c1 from t where c2=” 這種都是快照讀,快照讀就是讀取某個數據版本;像select c1 from t where c2 for update 這種屬於當前讀,會讀取當前最新的版本。

 

綜上,undo log有兩個作用,事務回滾和MVCC。

Tags: