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

迷茫中守候 發表於 2021-05-03

問題:請講下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中,如下圖

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

從上圖可以看到當前資料記錄的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。

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