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

Mysql之DELETE操作對應(yīng)的undo日志方式

 更新時間:2025年08月18日 09:38:46   作者:小志的博客  
InnoDB通過正常記錄鏈表和垃圾鏈表管理數(shù)據(jù)頁,刪除記錄先標(biāo)記為deletemark,后由purge線程移入垃圾鏈表回收空間,PAGE_FREE指向垃圾鏈表頭,PAGE_GARBAGE記錄可重用空間大小,Undo日志保存trx_id和roll_pointer,用于版本控制和回滾

一、正常記錄鏈表

記錄的頭信息中的next_record屬性組成一個單向鏈表,我們把這個鏈表稱為正常記錄鏈表。

二、垃圾鏈表

被刪除的記錄其實也會根據(jù)記錄頭信息中的next_record屬性組成一個鏈表,只不過這個鏈表中的記錄所占用的存儲空間可以被重新利用,所以也稱這個鏈表為垃圾鏈表。

三、PAGE_FREE的作用

Page Header部分中有一個名為PAGE_FREE的屬性,它指向由被刪除記錄組成的垃圾鏈表中的頭節(jié)點。每刪除一條記錄,則該記錄都會插入到垃圾鏈表的頭節(jié)點處。

示例:有3條正常記錄和2條被刪除記錄,他們在頁中的記錄分布情況如下圖所示: 

注:在垃圾鏈表中,這些記錄占用的存儲空間可以被重新利用。

四、刪除一條記錄的步驟

delete mark階段

僅僅將記錄的deleted_flag標(biāo)識位設(shè)置為1,但是這條記錄并沒有加入到垃圾鏈表中。

也就是說,這條記錄即不是正常記錄,也不是已刪除記錄。

在刪除語句所在的事務(wù)提交之前,被刪除的記錄一直都處于這種中間狀態(tài)(其實主要是為了實現(xiàn)MVCC的功能才這樣處理的)。

  • 如下圖所示:

purge階段

當(dāng)該刪除語句所在的事務(wù)提交后,會有專門的線程來把該記錄從正常記錄鏈表中移除,并加入到垃圾鏈表中作為頭節(jié)點。

  • 如下圖所示:

五、關(guān)于垃圾鏈的重用空間的知識點了解

1、PAGE_GARBAGE是做什么的

Page Header部分有一個名為PAGE_GARBAGE的屬性。該屬性記錄著當(dāng)前頁面中可重用存儲空間占用的總字節(jié)數(shù)。

每當(dāng)有已刪除記錄加入到垃圾鏈表后,都會把這個PAGE_GARBAGE屬性的值加上已刪除記錄占用的存儲空間大小。

2、如何重用垃圾鏈表的存儲空間

  • PAGE_FREE指向垃圾鏈表的頭節(jié)點,每當(dāng)新插入數(shù)據(jù)的時候:
  • 首先:判斷垃圾鏈表頭節(jié)點記錄的存儲空間是否足夠容納這條新插入的記錄。如果可以容納則直接重用這條已刪除記錄的存儲空間。
  • 其次:如果不能容納,則直接向頁面申請新的空間來存儲這條記錄。(是的,你沒看錯!并不會嘗試遍歷垃圾鏈表,以找到可以容納新記錄的節(jié)點)

3、如果新插入的那條記錄記錄小于重用的記錄空間,那么會有一部分空間用不到,怎么處理?是否可以直接浪費掉?

這種情況會頻繁發(fā)生,也就會隨著記錄越插越多而產(chǎn)生越來越多的空間碎片。只有當(dāng)頁面塊滿的時候,如果再插入一條新記錄,無法分配一條完整的記錄空間時,會先查看PAGE_GARBAGE的空間和剩余空間相加是否可以容納這條新的記錄,如果可以,InnoDB則會嘗試重新組織頁內(nèi)的記錄。即:先開辟一個臨時頁面,把原頁面內(nèi)的記錄依次挨著插入一遍到臨時頁,之后,再把臨時頁的內(nèi)容復(fù)制到本頁面,這樣就可以把那些碎片空間都釋放出來了。但是該操作比較耗費性能。

由于一旦事務(wù)提交,我們也就不需要再回滾這個事務(wù)了,所以在設(shè)計undo日志時,只需要考慮delete mark這個階段所做的影響進(jìn)行回滾就可以了。

  • TRX_UNDO_DEL_MARK_REC類型的undo日志結(jié)構(gòu)如下圖所示:

上圖解釋:

  • info bits:記錄頭信息的前4個比特的值。
  • trx_id:舊記錄的trx_id值。
  • roll_pointer:舊記錄的roll_pointer值。
  • len of index_col_info:也就是下邊的【索引列各列信息】部分和本部分占用的存儲空間總和。
  • 索引列各列信息 <pos, len, value>列表:凡是被索引的列的各列信息。

4、什么TRX_UNDO_DEL_MARK_REC類型的undo日志保存舊記錄的trx_id值和roll_pointer值

保存舊記錄的trx_id值——為了采用事務(wù)id作為版本號,記錄每個undo日志所對應(yīng)的版本是多少。

保存舊記錄的roll_pointer值——可以通過undo日志的roll_pointer屬性找到上一次對該記錄進(jìn)行改動時產(chǎn)生的undo日志,因此可以將日志串成鏈表。這個鏈表就是版本鏈。

  • 示例:新增一條記錄,然后再刪除這條記錄的完整操作過程,如下所示:

六、刪除操作生成undo日志的示例

1、 先插入兩條記錄

BEGIN; # 顯示開啟一個事務(wù),假設(shè)該事務(wù)的事務(wù)id為100
# 插入兩條記錄
INSERT INTO sys_user(id, name, city) VALUES(1, 'xz','北京市'), (2, 'tom','天津市');
# 刪除一條記錄
DELETE FROM sys_user WHERE id = 1;

2、上圖字段說明

(1)、索引列各列信息 <pos, len, value>列表<0, 4, 1>:

  • 由于id列是主鍵,所以pos=0;
  • 由于id列的類型是INT,所以len=4;
  • 由于id=1,所以value=1;

(2)、索引列各列信息 <pos, len, value>列表<3, 4, ‘xz’>:

  • 由于name列是二級索引,它排在id列、trx_id列、roll_pointer列之后,所以pos=3;
  • 由于id列的類型是INT,所以len=4;
  • 由于name=‘xz’,所以value=‘xz’;

(3)、len of index_col_info

  • pos使用1字節(jié)來存儲。
  • len使用1字節(jié)來存儲。
  • value根據(jù)具體值,來判斷。比如:id=1,主鍵是INT占4個字節(jié),所以value使用4字節(jié)存儲。name=‘xz’,VARCHAR類型,所以value用4字節(jié)存儲。
  • len of index_col_info本身占2個字節(jié)。

(4)、綜上所述,<0, 4, 1><3, 4, ‘xz’>占用空間等于:(1+1+4)+(1+1+4) =12,如下圖所示:

(5)、最后,再加上len of index_col_info屬性本身占2個字節(jié),所以總共14字節(jié)。即:len of index_col_info=14。

總結(jié)

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

相關(guān)文章

最新評論

遂溪县| 铁力市| 朔州市| 巴林右旗| 忻州市| 从化市| 镇雄县| 陈巴尔虎旗| 固阳县| 新建县| 肇庆市| 新竹县| 高清| 右玉县| 东丽区| 阿坝| 克什克腾旗| 中方县| 沾化县| 张家界市| 贵州省| 曲水县| 桃江县| 磐安县| 常山县| 阿拉善左旗| 嘉祥县| 延寿县| 凤冈县| 上林县| 锡林郭勒盟| 五家渠市| 安顺市| 七台河市| 榆中县| 乐安县| 民权县| 孟连| 卓尼县| 丹江口市| 镇宁|