MySQL百問系列:Undo log 做用

問題

  1. undo log是幹什麼用的?
  2. undo log 版本鏈
  3. undo log 存放在那裏,何時會被釋放?

支持回滾和MVCC

咱們知道innodb 支撐事務。那麼事務其中一個功能是須要支持回滾。
事務中可能設計到增,刪,改等操做。那麼回滾如和實現呢?sql

  • 若是事務中新增了一條記錄,那麼咱們記錄下這條新增的主鍵,回滾的時候刪除便可。
  • 若是事務中刪除了一條記錄,那麼咱們記錄下記錄的全部信息,回滾的時候原樣插入便可。
  • 若是事務中修改了一條記錄,那麼咱們要記錄原來的信息,回滾的把原來的信息更新回去就行了。

undo log 就是記錄這些用於回滾的信息。
那麼MVCC 爲何也是靠undo log來實現的呢?
也許你據說過聚簇索引每條記錄有個隱藏字段叫row_id,他的做用是若是不指定主鍵,它就變成了系統內部的自增主鍵。同時其實每條記錄還有兩個字段一個是trx_id,一個是roll_pointer.這個兩個字段就是用來實現MVCC功能。shell

  • trx_id: 修改當前記錄的事務id。
  • roll_pointer:只向一個undo log。

每一條undo log記錄固然也有trx_id, 和roll_pointer字段。服務器

準備工做:

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  `addresss` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `index_age` (`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

INSERT student VALUES (1,'張一',1,'ssss'),(2,'張二',2,'ssss');
複製代碼

聚簇索引內容相似於一下:spa

id name age address trx_id roll_pointer
1 張一 1 ssss 10 insert_undo_log 地址
2 張二 2 ssss 10 insert_undo_log 地址

undo log相似於一下:設計

id name age address trx_id roll_pointer undo id
1 張一 1 ssss 10 0
2 張二 2 ssss 10 1

undo id 的在同一個事務中依次遞增的。code

update set age=10 where id = 1; #更新語句一
update set age=20 where id = 1; #更新語句二
複製代碼
id name age address trx_id roll_pointer undo id
1 張一 1 ssss 20 指向上一條insert log 地址 0
1 張一 10 ssss 21 上一條undo log 地址 0

幾點說明:索引

  • insert log 在上一個插入事務結束後,會被回收,釋放。
  • 更新語句一 ,roll_pointer 會保存上一條插入的insert log。 同時保存更新前的信息。
  • 由於是自動提交事務模式,因此2個update,會產生2個不一樣的trx_id。
  • 真實的update log 記錄的信息結構要複雜的多,會分更新主鍵,和不更新主鍵的狀況。這裏不詳細展開。
  • 這種一條條undo log 依據roll_pointer造成的鏈式結構,就是版本鏈。

undo log 存放在哪?

在MYSQL 5.6 以後,能夠爲undo log 分配獨立的表空間。
默認表空間的數量爲2個,能夠設置innodb_undo_tablespaces 來增長數量。
每一個表空間又被分爲多個回滾段(rollback segment),回滾段的數量能夠查看innodb_undo_logs。
每一個回滾段就存放了undo log 頁。
若是undo log 對應的事務都已是執行完畢,或者回滾結束的。那麼對應的undo log 空間就能夠被回收了。
假設有一個長事務,遲遲未被提交,或回滾,那麼undo log 會愈來愈大。嚴重的會直接致使服務器磁盤空間爆滿。因此若是忽然服務器磁盤空間使用量快速上升,也能夠查看下是否有長事務沒有提交,致使undo log佔用很大磁盤空間。事務

總結

undo log 兩大做用:innodb

  • 保障事務的原子性。事務中的全部更新語句,要麼全被執行,要麼全被回滾。經過將同一個trx_id 的undo log 就能夠實現回滾同一事務的全部更新語句了。
  • 提供版本鏈,支持MVCC。undo log 鏈爲實現MVCC 提供了底層的物質基礎。爲了實現MVCC ,還須要藉助Read View 。後續詳細講解MVCC中會詳細聊到。
相關文章
相關標籤/搜索