MySQL之undo日志頁結(jié)構(gòu)詳解
1、背景
之前講過undo日志類型,本篇文章再來具體講解一下undo日志頁結(jié)構(gòu)。
2、undo日志頁結(jié)構(gòu)
【1】FIL_PAGE_UNDO_LOG頁
InnoDB中最基本的存儲(chǔ)單位是頁,undo日志也是存儲(chǔ)在頁上的,頁的類型為FIL_PAGE_UNDO_LOG,其頁面結(jié)構(gòu)如下:
其中Undo Page Header是undo日志所特有的,其結(jié)構(gòu)如下:
字段含義為:
字段 | 字節(jié)大小 | 含義 |
---|---|---|
TRX_UNDO_PAGE_TYPE | 2 | 本頁存儲(chǔ)undo日志類型,分為兩大類:TRX_UNDO_INSET和TRX_UNDO_UPDATE,一個(gè)頁面只能存儲(chǔ)一種類型 |
TRX_UNDO_PAGE_START | 2 | 本頁中第一條undo日志地址 |
TRX_UNDO_PAGE_FREE | 2 | 本頁可以寫入undo日志的空閑地址 |
TRX_UNDO_PAGE_NODE | 12 | 鏈表節(jié)點(diǎn) |
【2】undo頁面組成的鏈表
通過Undo Page Header的TRX_UNDO_PAGE_NODE屬性能讓undo頁組成一個(gè)鏈表,鏈表中的第一個(gè)頁被稱為first undo page,第二個(gè)頁被稱為normal undo page,上面講過有兩大類undo日志類型,一個(gè)頁只能存儲(chǔ)相同的頁類型,所以一個(gè)事務(wù)的所有插入操作可以組成一個(gè)insert undo鏈表,所有刪除和更新操作可以組成一個(gè)update undo鏈表,臨時(shí)表也需要記錄undo日志,所以一個(gè)事務(wù)可能產(chǎn)生四個(gè)undo頁組成的鏈表,這些鏈表是用到的時(shí)候再分配。
【3】Undo Log Segment
每個(gè)undo日志頁組成的鏈表都對(duì)應(yīng)一個(gè)段,叫Undo Log Segment,這個(gè)段存儲(chǔ)在鏈表的第一個(gè)頁也就是first undo page頁中,其結(jié)構(gòu)如下:
其中Undo Log Segment header用來存儲(chǔ)段結(jié)構(gòu)信息,其結(jié)構(gòu)如下:
字段含義如下:
字段 | 字節(jié)大小 | 含義 |
---|---|---|
TRX_UNDO_STATE | 2 | 鏈表對(duì)應(yīng)的段狀態(tài): TRX_UNDO_ACTIVE:活躍狀態(tài),一個(gè)活躍的事務(wù)正在往這個(gè)段里面寫入undo日志 TRX_UNDO_CACHED:被緩存的狀態(tài),該undo頁面對(duì)應(yīng)的來吧等待被其它實(shí)物重用 TRx_UNOD_To_FREE:對(duì)insert undo鏈表來說,在它對(duì)應(yīng)的事務(wù)提交之后,該鏈表不能被重用就處于這種狀態(tài) TRX_UNDO_TO_PURGE:對(duì)update undo鏈表來說,在它對(duì)應(yīng)的事務(wù)提交之后,該鏈表不能被重用就處于這種狀態(tài) TRX_UNDO_PREPARED:包含處于PREPARE階段的事務(wù)產(chǎn)生的undo日志 |
TRX_UNDO_LAST_LOG | 2 | 本undo頁面鏈表中最后一個(gè)Undo Log header的位置 |
TRX_UNDO_FSEG_HEADER | 10 | 本undo頁鏈表對(duì)應(yīng)的段信息 |
TRX_UNDO_PAGE_LIST | 16 | undo頁鏈表基節(jié)點(diǎn),這個(gè)基節(jié)點(diǎn)就存在于first undo page頁中 |
【4】Undo Log Header
同一個(gè)事務(wù)向同一個(gè)undo頁面鏈表中寫入的undo日志算一個(gè)組,組信息存儲(chǔ)在鏈表第一個(gè)頁的Undo Log Header屬性中,first undo page頁可以這樣表示:
Undo Log Header結(jié)構(gòu)如下:
字段含義如下:
字段 | 字節(jié)大小 | 含義 |
---|---|---|
TRX_UNDO_TRX_ID | 8 | 生成本組undo日志的事務(wù)id |
TRX_UNDO_TRX_NO | 8 | 事務(wù)提交后生成的序號(hào),用來標(biāo)記事務(wù)的提交順序 |
TRX_UNDO_DEL_MARKS | 2 | 標(biāo)記本組undo日志是否包含由于Delete mark操作產(chǎn)生的undo日志 |
TRX_UNDO_LOG_START | 2 | 本組undo日志第一條undo日志在頁面中的地址 |
TRX_UNDO_XID_EXISTS | 1 | 本組undo日志是否包含XID信息 |
TRX_UNDO_DICT_TRANS | 1 | 標(biāo)記本組undo日志是不是由DDL語句產(chǎn)生 |
TRX_UNDO_TABLE_ID | 8 | DDL語句操作的表table_id |
TRX_UNDO_NEXT_LOG | 2 | 下一組undo日志在頁面中開始的偏移量 |
TRX_UNDO_PREV_LOG | 2 | 上一組undo日志在頁面中開始的偏移量 |
TRX_UNDO_HISTORY_NODE | 12 | History鏈表的節(jié)點(diǎn) |
【5】重用undo頁面
為了節(jié)省空間就有了重用undo頁面,重用undo頁面需要滿足以下條件:
- 1、undo頁面鏈表只包含一個(gè)undo頁面
- 2、該undo頁面鏈表使用空間超過該頁面空間的3/4
- 3、insert undo鏈表是覆蓋寫入
- 4、update undo鏈表是追加寫入
3、總結(jié)
通過undo日志能保證事務(wù)回滾,也就是原子性,上面講過insert操作對(duì)應(yīng)的undo日志可以直接刪除,update和delete操作的不能,就是為了MVCC,多版本并發(fā)控制,后面再來講解MVCC。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql8報(bào)錯(cuò):ERROR?1410?(42000):?You?are?not?allowed?to?
電腦新裝的mysql,版本為8.0以上,分配權(quán)限時(shí)直接帶密碼和賬號(hào)會(huì)報(bào)錯(cuò),這篇文章主要給大家介紹了關(guān)于mysql8報(bào)錯(cuò):ERROR?1410?(42000):?You?are?not?allowed?to?create?a?user?with?GRANT的解決辦法,需要的朋友可以參考下2022-06-06dubbo中zookeeper請(qǐng)求超時(shí)問題:mybatis+spring連接mysql8.0.15的配置
這篇文章主要介紹了dubbo中zookeeper請(qǐng)求超時(shí)問題:mybatis+spring連接mysql8.0.15的配置,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01MySQL索引底層數(shù)據(jù)結(jié)構(gòu)詳情
這篇文章主要介紹了MySQL索引底層數(shù)據(jù)結(jié)構(gòu)詳情,下面文章圍繞MySQL索引底層數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料展開全篇文章,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2021-12-12在MySQL中使用子查詢和標(biāo)量子查詢的基本操作教程
這篇文章主要介紹了在MySQL中使用子查詢和標(biāo)量子查詢的基本操作教程,子查詢的使用時(shí)MySQL入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-12-12MySQL如何對(duì)數(shù)據(jù)進(jìn)行排序圖文詳解
我們知道從MySQL表中使用SQL SELECT語句來讀取數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于MySQL如何對(duì)數(shù)據(jù)進(jìn)行排序的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08mysql命令行中執(zhí)行sql的幾種方式總結(jié)
下面小編就為大家?guī)硪黄猰ysql命令行中執(zhí)行sql的幾種方式總結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11Mysql數(shù)據(jù)庫從5.6.28版本升到8.0.11版本部署項(xiàng)目時(shí)遇到的問題及解決方法
這篇文章主要介紹了Mysql數(shù)據(jù)庫從5.6.28版本升到8.0.11版本過程中遇到的問題及解決方法,解決辦法有三種,每種方法給大家介紹的都很詳細(xì),感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05