最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL?InnoDB?undo?log數(shù)據(jù)結(jié)構(gòu)用法詳解

 更新時(shí)間:2025年07月22日 09:19:26   作者:BestRivenCHN  
InnoDB的undolog用于事務(wù)回滾與MVCC,存于共享/獨(dú)立表空間,包含insert和update兩種類(lèi)型,通過(guò)參數(shù)配置,由purge線程清理

一、概念解析

1、undo log基本

undo log是InnoDB事務(wù)中特有的結(jié)構(gòu),它的作用有兩個(gè):

  • 一是進(jìn)行事務(wù)回滾(原子性),舊數(shù)據(jù)先放到undo log中,等rollback時(shí)再將舊數(shù)據(jù)里的數(shù)據(jù)回滾回來(lái);
  • 二是MVCC(隔離性),非阻塞讀。

undo能夠避免臟讀:在操作數(shù)據(jù)之前,將數(shù)據(jù)備份到undo頁(yè)中,然后在進(jìn)行數(shù)據(jù)的修改,不能看到其他回話(huà)未提交的數(shù)據(jù),當(dāng)要讀取被修改頁(yè)數(shù)據(jù)行時(shí),會(huì)指向備份在undo頁(yè)中的數(shù)據(jù),避免臟讀。

  • undo回滾段頭物理存儲(chǔ)在ibdata1文件中第6個(gè)頁(yè)位置。
  • undo log存放在數(shù)據(jù)庫(kù)內(nèi)部的一個(gè)特殊段中,這個(gè)段稱(chēng)為undo段。undo段位于共享表空間中。回滾段實(shí)際上是一種 undo 文件組織方式。

在InnoDB存儲(chǔ)引擎中有rollback segment,每個(gè)回滾段記錄了1024個(gè)undo log segment(slot),每個(gè)undo log segment段中進(jìn)行undo頁(yè)的申請(qǐng)。

從1.1版本開(kāi)始InnoDB支持最大128個(gè)rollback segment,所以理論上可以支持的最大的事務(wù)上限為128*1024。

在1.2版本開(kāi)始,可以通過(guò)參數(shù)對(duì)rollback segment進(jìn)行設(shè)置,參數(shù)有:

參數(shù)名稱(chēng)

含義

innodb_undo_directory

設(shè)置回滾段文件所在的路徑

innodb_undo_logs

設(shè)置回滾段的個(gè)數(shù)

innodb_undo_tablespaces

設(shè)置構(gòu)成回滾段文件的數(shù)量

也就是說(shuō):

回滾段可以存放在共享表空間以外的地方,即可以設(shè)置獨(dú)立表空間,innodb_undo_directory的默認(rèn)值為“.”,表示當(dāng)前InnoDB存儲(chǔ)引擎的目錄。

回滾段的個(gè)數(shù)默認(rèn)值為128。

設(shè)置回滾段文件的數(shù)量后,回滾段可以較為平均地分布在多個(gè)文件中,在路徑下可以看到undo為前綴的文件,該文件代表回滾段文件。

可用show variables like “innodb_undo%”;查詢(xún):

重新初始化時(shí)指定innodb_undo_tablespaces=N來(lái)設(shè)置,設(shè)置好后會(huì)在data目錄下生成undo獨(dú)立表空間(大小10M):

2、事務(wù)系統(tǒng)頭transactionsystemheader

回滾段的管理,在InnoDB共享表空間中,用第6個(gè)頁(yè)面(5號(hào))來(lái)管理的,這個(gè)頁(yè)面專(zhuān)門(mén)用來(lái)存儲(chǔ)事務(wù)系統(tǒng)相關(guān)信息的,源代碼位于trx0sys.h,它的格式如下:

這三個(gè)參數(shù)的含義分別為:

參數(shù)名稱(chēng)

含義

TRX_SYS_TRX_ID_STORE

存儲(chǔ)事務(wù)號(hào)

TRX_SYS_FSEG_HEADER

存儲(chǔ)事務(wù)段信息

TRX_SYS_RSEGS

數(shù)組,InnoDB有128個(gè)rollback segment

3、回滾段頭rollbacksegmentheader

對(duì)于每一個(gè)回滾段,即上面TRX_SYS_RSEGS數(shù)組中的一個(gè)元素,也有其自己的存儲(chǔ)格式,代碼中的宏定義位于trx0rseg.h,格式如下:

這五個(gè)信息的含義如下:

參數(shù)名稱(chēng)

含義

TRX_RSEG_MAX_SIZE

所有undo段頁(yè)面之和

TRX_RSEG_HISTORY_SIZE

需要purge的回滾段頁(yè)面數(shù)

TRX_RSEG_HISTORY

存儲(chǔ)history list的鏈表首地址

TRX_RSEG_FSEG_HEADER

存儲(chǔ)回滾段的inode位置信息

TEX_RSEG_UNDO_SLOTS

數(shù)組,1024,每個(gè)元素是一個(gè)頁(yè)面號(hào)

這五個(gè)信息存儲(chǔ)了一個(gè)回滾段的信息,最后一個(gè)位置的數(shù)組,用來(lái)真正存儲(chǔ)回滾段的位置。

這五個(gè)信息是從頁(yè)面偏移38的位置開(kāi)始存儲(chǔ),在TRX_SYS宏定義中可以查看:

4、回滾頁(yè)頭undologpageheader

定義在trx0undo.h,事務(wù)undo日志頁(yè)面頭偏移量:

其中各個(gè)參數(shù)的含義為:

參數(shù)名稱(chēng)

含義

TRX_UNDO_PAGE_TYPE

類(lèi)型,TRX_UNDO_INSERT\UPDATE

TRX_UNDO_PAGE_START

開(kāi)始存儲(chǔ)undo日志的位置

TRX_UNDO_PAGE_FREE

結(jié)束標(biāo)志

TRX_UNDO_PAGE_NODE

雙向鏈表的指針

第一個(gè)頁(yè)在undo log段的回滾日志段頭:

其中各個(gè)參數(shù)的含義為:

參數(shù)名稱(chēng)

含義

TRX_UNDO_STATE

undo段五種狀態(tài),包括TRX_UNDO_ACTIVE\CACHED\TO_FREE\TO_PURGE\PREPARED

TRX_UNDO_LAST_LOG

最后一個(gè)undo日志的偏移位置

TRX_UNDO_FSEG_HEADER

undo段inode信息

TRX_UNDO_PAGE_LIST

段鏈表的首地址

其中undo log段的狀態(tài)有五種:

5、回滾日志頭undologheader

這是回滾日志的頭,在第一頁(yè)的update undo log中有幾個(gè)undo log headers。同樣定義在trx0undo.h中,它的宏定義如下:

整理并解釋其中的含義:

參數(shù)名稱(chēng)

含義

TRX_UNDO_TRX_ID

存儲(chǔ)當(dāng)前undo日志對(duì)應(yīng)事務(wù)的事務(wù)id

TRX_UNDO_TRX_NO

事務(wù)序列號(hào)

TRX_UNDO_DEL_MARKS

刪除記錄標(biāo)記

TRX_UNDO_LOG_START

存儲(chǔ)當(dāng)前頁(yè)面中第一個(gè)undo日志的開(kāi)始位置

TRX_UNDO_XID_EXISTS

標(biāo)記的當(dāng)前日 志中有沒(méi)有包含xid事務(wù)

TRX_UNDO_DICT_TRANS

標(biāo)記當(dāng)前事務(wù)是不是DDL,在回滾時(shí)判斷如何操作

TRX_UNDO_TABLE_ID

表id

TRX_UNDO_NEXT_LOG

鏈接指向下一個(gè)undo日志

TRX_UNDO_PREV_LOG

指向上一個(gè)undo日志,構(gòu)成雙向鏈表

TRX_UNDO_HISTORY_NODE

存儲(chǔ)history list中的雙向鏈表,鏈表首地址

6、兩種undolog格式

undo log格式有兩種:

  • insert undo log
  • update undo log

其中,insert操作會(huì)產(chǎn)生insert undo log。因?yàn)楦綦x性的要求,insert操作只對(duì)事務(wù)本身可見(jiàn),對(duì)其他事務(wù)不可見(jiàn)。并且undo log可以在事務(wù)提交后直接刪除,不需要進(jìn)行purge操作。

update和delete操作都會(huì)產(chǎn)生update undo log。對(duì)于update操作很簡(jiǎn)單,就是將舊版本的值修改為新版本的值,并且將舊版本的記錄保存到undo log中;對(duì)于delete操作完后并不是真正的刪除該行數(shù)據(jù),而是將該行的數(shù)據(jù)存在undo log中,并且將標(biāo)記位delete置為true,以備回滾時(shí)可以根據(jù)標(biāo)記位進(jìn)行逆操作,這樣就能夠找回之前的舊數(shù)據(jù),起到回滾的作用。

在delete中又分為三種情況:

purge線程兩個(gè)主要作用是:清理undo頁(yè)和清除page里面帶有delete_bit標(biāo)識(shí)的數(shù)據(jù)行。在InnoDB中,事務(wù)中的delete操作實(shí)際上并不是真正的刪除掉數(shù)據(jù)行,而是在記錄上標(biāo)識(shí)delete_bit,而不是真正刪除記錄,真正的刪除工作需要后臺(tái)purge線程去完成。

下面是兩種undo log記錄的具體的結(jié)構(gòu):

二、數(shù)據(jù)結(jié)構(gòu)

與undo log相關(guān)的數(shù)據(jù)結(jié)構(gòu)有trx_sys_t、trx_rsegs_t 、trx_t、trx_rseg_t、trx_undo_t、trx_undo_ptr_t等結(jié)構(gòu),其中比較重要的結(jié)構(gòu)有兩個(gè):trx_rseg_t和trx_undo_t。trx_rseg_t保存回滾段的信息,trx_undo_t保存關(guān)于回滾日志的信息。

通過(guò)兩種方式找到回滾日志:

結(jié)論:

1、從全局變量trx_sys中的回滾段數(shù)組rseg_array中的回滾鏈表update-undo_list中指針(trx_sys->rseg_array[N]->update_undo_list->start)以及當(dāng)前事務(wù)trx中的回滾段指針rsegs中的slot槽區(qū)m_redo中的undo log(trx->rsegs->m_redo->update_undo)都可以找到相應(yīng)的回滾段中的回滾日志

2、事務(wù)id、回滾段id、page_no遞增。

1、trx_rseg_t

回滾段的內(nèi)存對(duì)象的類(lèi)型是一個(gè)叫trx_rseg_t的結(jié)構(gòu),它定義在trx0rseg.h文件中,它的各成員有:

成員變量

解釋

ulint id;

回滾段id

RsegMutex mutex;

回滾段mutex,保護(hù)

ulint space;

回滾段頭空間

ulint page_no;

回滾段頁(yè)碼

page_size_t page_size;

頁(yè)面大小

ulint max_size;

允許的最大頁(yè)大小

ulint curr_size;

當(dāng)前頁(yè)的大小

UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_list;

update回滾日志鏈表

UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_cached;

為快速重用而緩存的update回滾日志鏈表

UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_list;

insert回滾日志的字段

UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_cached;

為快速重用而緩存的insert undo log鏈表

ulint last_page_no;

最后一個(gè)尚未清除的日志頁(yè)碼

ulint last_offset;

最后一個(gè)尚未清除的日志頭的字節(jié)偏移量

trx_id_t last_trx_no;

最后一個(gè)尚未清除的日志的事務(wù)號(hào)

ibool last_del_marks;

判斷最后一個(gè)尚未清除的日志是否要清除

ulint trx_ref_count;

跟蹤rseg分配事務(wù)的參考計(jì)數(shù)器

bool skip_allocation;

如果為真,則跳過(guò)分配此rseg

update\insert_undo_list 用于保存產(chǎn)生的回滾日志,update\insert_undo_cached用于快速重用而緩存的回滾日志鏈表。當(dāng)確定回滾日志無(wú)用時(shí),會(huì)將回滾日志從update\insert_undo_list中摘除,放到相應(yīng)的cached鏈表中。

2、trx_undo_t

回滾日志的內(nèi)存對(duì)象的類(lèi)型是一個(gè)叫trx_undo_t的結(jié)構(gòu),它定義在trx0undo.h文件中,它的各成員有:

成員變量

解釋

ulint     id;

回滾段內(nèi)的回滾日志槽號(hào)(slot)

ulint     type;

類(lèi)型。TRX_UNDO_INSERT\UPDATE

ulint     state;

相應(yīng)的回滾日志段的狀態(tài)

ibool del_marks;

刪除標(biāo)記

trx_id_t     trx_id;

事務(wù)id

XID     xid;

open XA事務(wù)識(shí)別

ibool dict_operation;

是否是dict操作

table_id_t table_id;

設(shè)置表ID

trx_rseg_t* rseg;

回滾日志所屬的rseg回滾段

ulint     space;

放置回滾日志的空間id

page_size_t page_size;

回滾日志中標(biāo)題頁(yè)的大小

ulint     hdr_page_no;

回滾日志中標(biāo)題頁(yè)的頁(yè)碼

ulint      hdr_offset;

頁(yè)面上回滾日志的header偏移量

ulint     last_page_no;

登錄日志中最后一頁(yè)的頁(yè)碼

ulint     size;

當(dāng)前頁(yè)的大小

ulint     empty;

回滾日志記錄堆棧當(dāng)前是否為空

ulint     top_page_no;

鏈接最近撤消日志記錄的頁(yè)碼

ulint     top_offset;

最新回滾記錄的偏移量

undo_no_t top_undo_no;

最新的回滾記錄的編號(hào)

buf_block_t* guess_block;

猜測(cè)可能位于首頁(yè)的緩沖區(qū)

ulint     withdraw_clock;

存儲(chǔ)guess_block時(shí)緩沖池的退出時(shí)鐘值

UT_LIST_NODE_T(trx_undo_t) undo_list;

回滾段中的回滾日志對(duì)象鏈表

回滾段指針包括回滾段的id、日志所在的page no、以及page內(nèi)偏移量。通過(guò)回滾段的指針就能夠找到這個(gè)回滾段,通過(guò)回滾日志的槽號(hào)、頁(yè)碼、回滾記錄編號(hào)和偏移量就能定位到這條回滾日志。

undo_list用于將此類(lèi)型的undo log鏈接到undo log list中。

UT_LIST_NODE_T(trx_undo_t) undo_list鏈表中有兩個(gè)指針,分別為prev和next,用于將此undo log鏈接到undo log list中。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

临汾市| 通山县| 郁南县| 商南县| 柳江县| 昌宁县| 蓬莱市| 永州市| 福清市| 巢湖市| 池州市| 泽普县| 乳源| 大城县| 玉田县| 景洪市| 阜城县| 邻水| 右玉县| 玉门市| 社旗县| 平罗县| 德安县| 乡城县| 基隆市| 习水县| 宜君县| 胶南市| 宁武县| 昭通市| 光山县| 广水市| 武山县| 工布江达县| 化州市| 威宁| 仲巴县| 吴堡县| 金堂县| 乌拉特中旗| 德阳市|