mysql undo詳談
1 簡介:undo是MVCC機制的基礎部分之一
2 做用:爲了實現可重複性讀,存儲歷史數據
3 存儲:5.6之前undo都存儲在內存和ibdata1中,5.6之後undo能夠獨立成單獨的文件,更能夠進行truncate表空間,減小磁盤容量
5 回滾段三階段mysql
0 回滾段分類 sql
update_undo: 只用於事務內的update語句 這裏會加入到其對應rollback segment的history list數據頁列表上,history list長度加1 佈局
insert_undo:只用於事務內的insert語句 新插入的記錄產生的Undo不會被任何查詢語句所引用,所以能夠直接釋放undo,這裏的undo log不會累加到history list上spa
1 事務開始後,針對讀寫事務,會預先在內存中分配一個回滾段
2 事務進行中,將歷史數據寫入undo page中
1 事務commit
2 事務rollback
1:對於標記刪除的記錄清理標記刪除標記;
2:對於in-place更新,將數據回滾到最老版本;
3:對於插入操做,直接刪除彙集索引和二級索引記錄(row_undo_ins)。
6 purge清理undo段
1 清理事務提交後不須要的undo信息 從回滾段的HISTORY 文件鏈表上開始遍歷釋放Undo log segment,因爲history 鏈表是按照trx no有序的,所以遍歷truncate直到徹底清除,或者遇到一個還未purge的undo log(trx no比當前purge到的位置更大)時才中止。
2 清理已經被打上delete標記的數據實現物理刪除
相關參數變量 innodb_purge_threads=1(默認值)
7 相關 innodb status信息
Purge done for trx's n:o < 219761368 undo n:o < 0 state: running but idle
History list length 3228
purge done 表明已經完成的事務量
n:0< 表明正在執行的purge
state:表明線程是否繁忙
history-list-length 表明存在的undo個數 16KX3228 表明使用的undo大小 一頁是16K線程
這裏要注意 通常狀況下history-list不可能爲零,由於 update_undo有一部分會進行cache重用,而這部分也算在沒有清理的列表之中
8 關於ibdata1暴漲的緣由
1 共享表空間=>改用獨立表空間
2 大量undo暴漲了ibdata的空間
1 存在未完成的事務,能夠經過hsitory list觀察計算
2 執行過大事務(通常都是這種緣由形成的)
9 補充
當咱們delete數據行時,是對數據頁中要刪除的數據行作標記「deleted」,事務提交(速度快);對象
10 undo的構成和佈局索引
1 128個回滾段構成,32個回滾段用於系統的臨時表空間,96個回滾段用於事務事務
2 每一個回滾段維護了一個段頭頁,在該page中又劃分了1024個slot,每一個slot又對應到一個undo log對象,所以理論上InnoDB最多支持 96 * 1024個普通事務。內存
3 獨立表空間的space id都是從1 開始,0被預留在ibdata中.space id必須是連續分配的,不能斷檔it
4 8.0以前的版本默認只能建立128個回滾段