官术网_书友最值得收藏!

2.4.2 MAP_EVENT

1.MAP_EVENT的作用

MAP_EVENT是行模式特有的,它的主要作用是映射table id和實(shí)際訪問(wèn)表。其中還包含了一些表的定義,如表所在庫(kù)名、表名、字段類(lèi)型、可變字段長(zhǎng)度等。這里的庫(kù)名和QUERY_EVENT的庫(kù)名不一樣,這個(gè)庫(kù)名來(lái)自表的定義,而QUERY_EVENT的庫(kù)名來(lái)自當(dāng)前登錄的數(shù)據(jù)庫(kù),即源碼變量thd->db。

2.源碼重要接口

主庫(kù)

· 初始化構(gòu)造函數(shù):Table_map_log_event::Table_map_log_event(THD *thd_arg,TABLE *tbl,const Table_id& tid,bool is_transactional);

· 寫(xiě)入binlog cache:Table_map_log_event::write_data_header,Table_map_log_event::write_data_body。

從庫(kù)

· 讀取構(gòu)造函數(shù):Table_map_log_event(const char *buf,uint event_len,const Format_description_event *description_event);

· 應(yīng)用函數(shù):Table_map_log_event::do_apply_event。

3.主體格式

MAP_EVENT的主體格式如圖2-6所示。

圖2-6

其中,固定部分如下。

table_id:6字節(jié),這個(gè)table_id和InnoDB層的table_id不一樣,它分配的時(shí)機(jī)是第一次打開(kāi)表定義時(shí)。它不是固定的,重啟MySQL實(shí)例或者執(zhí)行flush table命令都會(huì)導(dǎo)致其改變。下面是table_id更改的代碼:

Reserved:2字節(jié),保留以后使用。

可變部分如下。

db len:表所在數(shù)據(jù)庫(kù)名的長(zhǎng)度。

db name:實(shí)際數(shù)據(jù)庫(kù)名,以0x00結(jié)尾。

table len:表名的長(zhǎng)度。

table name:實(shí)際表名,以0x00結(jié)尾。

no of cols:表中字段數(shù)量。

array of col types:字段的類(lèi)型數(shù)組。

metadata len:metadata block的長(zhǎng)度。

metadata block:對(duì)于可變字段需要記錄字段的長(zhǎng)度,但對(duì)于int這種數(shù)據(jù)類(lèi)型就不需要了,因?yàn)樗拈L(zhǎng)度是固定的。下面代碼是varchar關(guān)于可變長(zhǎng)度的輸出,它占用2字節(jié)。

如果感興趣可以查看do_save_field_metadata函數(shù)。

m_null_bits:一個(gè)位圖,用于表示字段是否可以為空。下面是位圖的獲取方式。

4.實(shí)例解析

執(zhí)行如下語(yǔ)句:

這個(gè)INSERT語(yǔ)句的MAP_EVENT如下:

其中,6c 00 00 00 00 00:表示table_id,即十六進(jìn)制值6c,轉(zhuǎn)換為十進(jìn)制值108。

01 00:保留。

02:表所在的數(shù)據(jù)庫(kù)名長(zhǎng)度為2。

67 70 00:數(shù)據(jù)庫(kù)名gp的ASCII表示,以0x00結(jié)尾。

02:表名的長(zhǎng)度為2。

74 79 00:表名ty的ASCII表示,以0x00結(jié)尾。

03:表?yè)碛?個(gè)字段。

03 03 03:每個(gè)字段的類(lèi)型都是03,實(shí)際就是int。具體可以參考enum_field_types這個(gè)枚舉類(lèi)型。

00:metadata長(zhǎng)度為0,沒(méi)有可變字段。

06:位圖,即二進(jìn)制值110,表示第一個(gè)字段不可以為空,其他兩個(gè)字段可以為空。

5.生成時(shí)機(jī)

本 Event 只會(huì)在行模式下生成。生成時(shí)機(jī)是事務(wù)的每條 DML 語(yǔ)句修改的第一行數(shù)據(jù)在InnoDB 引擎層修改完成,并且在QUERY_EVENT生成之后。通常來(lái)講,每個(gè)語(yǔ)句的每個(gè)表都會(huì)包含這樣一個(gè)MAP_EVENT。

6.table_id的易變性

前面我們說(shuō)過(guò)了,table_id是可變的,現(xiàn)在來(lái)構(gòu)造這種情況,如表2-1所示,還是使用上面的ty表。

表2-1

img

我們可以觀察到如下情況(輸出做了適當(dāng)換行)。

這是一個(gè)事務(wù),其中,相同表的table_id卻不一樣,可以觀察到如下現(xiàn)象。

· at 2434:Table_map:gp.ty mapped to number 133。

· at 2527:Table_map:gp.ty mapped to number 147。

我們發(fā)現(xiàn),這里同樣的ty表對(duì)應(yīng)了兩個(gè)不同的table_id,證明table_id是可變的。

主站蜘蛛池模板: 张北县| 庆云县| 古蔺县| 隆子县| 高碑店市| 贵德县| 壤塘县| 车险| 炉霍县| 乌拉特前旗| 砚山县| 平安县| 山东| 平武县| 土默特左旗| 阿拉尔市| 西畴县| 丽水市| 肃南| 大渡口区| 阿克陶县| 当雄县| 北碚区| 含山县| 司法| 湖南省| 襄垣县| 汝南县| 康保县| 安泽县| 盈江县| 肇州县| 天门市| 尼玛县| 南木林县| 冕宁县| 新巴尔虎右旗| 永吉县| 来宾市| 邯郸县| 青神县|