- 深入理解MySQL主從原理
- 高鵬
- 969字
- 2021-04-16 16:29:30
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

我們可以觀察到如下情況(輸出做了適當(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是可變的。
- JavaScript百煉成仙
- Learning ROS for Robotics Programming(Second Edition)
- Android項(xiàng)目開(kāi)發(fā)入門(mén)教程
- Python Game Programming By Example
- 青少年美育趣味課堂:XMind思維導(dǎo)圖制作
- Mastering Yii
- MATLAB實(shí)用教程
- 深度學(xué)習(xí):算法入門(mén)與Keras編程實(shí)踐
- Mastering Python Networking
- Flowable流程引擎實(shí)戰(zhàn)
- 創(chuàng)意UI:Photoshop玩轉(zhuǎn)APP設(shè)計(jì)
- Android移動(dòng)應(yīng)用項(xiàng)目化教程
- Mastering Apache Camel
- 現(xiàn)代CPU性能分析與優(yōu)化
- C# 7.1 and .NET Core 2.0:Modern Cross-Platform Development(Third Edition)