日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

mysql write rows_解析MYSQL BINLOG 二进制格式(5)--WRITE_ROW_EVENT

發布時間:2024/9/27 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql write rows_解析MYSQL BINLOG 二进制格式(5)--WRITE_ROW_EVENT 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

展開閱讀全文

原創:轉載請說明出處謝謝!

上接

http://blog.itpub.net/7728585/viewspace-2133188/ 解析MYSQL BINLOG 二進制格式(1)--準備工作

http://blog.itpub.net/7728585/viewspace-2133189/ 解析MYSQL BINLOG 二進制格式(2)--FORMAT_DESCRIPTION_EVENT

http://blog.itpub.net/7728585/viewspace-2133321/ 解析MYSQL BINLOG 二進制格式(3)--QUERY_EVENT

http://blog.itpub.net/7728585/viewspace-2133429/ 解析MYSQL BINLOG 二進制格式(4)--TABLE_MAP_EVENT

class:Write_rows_log_event

event:WRITE_ROW_EVENT

event_code:30

自從5.1.18開始,row模式下的insert的event,為什么要叫write不叫insert

呢無賴...

這部分在internals文檔中有點小的問題,我也是看了源碼的描述才找到,

在文檔中也寫到[TODO:following needs verification;it's guesswork]

就是fixed data中有2 bytes的m_extra_row_data其值當前為

uint16 vhlen= 2;

uint16 vhpayloadlen= 0;

下面有部分源碼截取。如果不知道這兩個字節讀取就會有問題。至少5.6,5.7都有的

老版本我也沒有驗證。

--fixed data ?10字節(5.6,5.7中描述為 ROWS_HEADER_LEN_V2)

6 bytes 表ID

2 bytes 保留

2 bytes 文檔中并沒有描述

源碼中描述為:

uchar ? ?*m_extra_row_data; ? /* Pointer to extra row data if any */

/* If non null, first byte is length */

源碼中是這樣寫入的:

if (likely(!log_bin_use_v1_row_events))

{

/*

v2 event, with variable header portion.

Determine length of variable header payload

*/

uint16 vhlen= 2;

uint16 vhpayloadlen= 0;

uint16 extra_data_len= 0;

if (m_extra_row_data)

{

extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];

vhpayloadlen= RW_V_TAG_LEN + extra_data_len;

}

/* Var-size header len includes len itself */

int2store(buf + RW_VHLEN_OFFSET, vhlen + vhpayloadlen);

rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V2);

/* Write var-sized payload, if any */

if ((vhpayloadlen > 0) &&

(rc == 0))

{

/* Add tag and extra row info */

uchar type_code= RW_V_EXTRAINFO_TAG;

rc= wrapper_my_b_safe_write(file, &type_code, RW_V_TAG_LEN);

if (rc==0)

rc= wrapper_my_b_safe_write(file, m_extra_row_data, extra_data_len);

}

}

else

{

rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V1);

}

可以看到實際上寫入的就是

uint16 vhlen= 2;

uint16 vhpayloadlen= 0;

有興趣可以參考源碼:

Rows_log_event::write_data_header(IO_CACHE *file)

--variable data part

packed integer:表中字段個數,這個地方為packed integer自行參考源碼

uchar *net_store_length

var-size:文檔解釋為每一位代表是否字段用到了 長度為INT((n+7)/8) n代表字段數量

源碼描述為 m_cols;/* Bitmap denoting columns available */

測試表現這一字節和binlog_row_image設置有關,默認為FULL每一個字節始終為

0XFF

var-size:每一位代表的字段的值是否為NULL,長度為INT((n+7)/8) n代表字段數量,

他采用一個位圖的方式。

1:NULL

0:NOT NULL

var-size:這部分就是真正的數據了。

為了驗證我做了如下的測試表:

mysql> create table testnull2 (id int,name1 varchar(20),name2 varchar(20));

Query OK, 0 rows affected (0.09 sec)

mysql> insert into testnull2 values(NULL,'test',NULL);

Query OK, 1 row affected (0.01 sec)

可以看到我只是插入的數據第一個字段第三個字段都是NULL,好我們看是解析,這次試用

mysqlbinlog 自帶的--hexdump方式和自己開發的工具./infobin,這個工具就是通過自己

對binlog event的認知進行解析的,做這個工具的目的在于簡化和友好的輸出,方便我以后

的測試使用,同時也驗證了我的全部說法,有時候mysqlbinlog的輸出有點過于繁多,不便于

描述和測試,關于XID_EVENT和GTID_EVENT在后面描述

關于工具我放到了百度云盤

http://pan.baidu.com/s/1jHIWUN0

[root@testmy data]# ./infobin ?test.000183

Check is Little_endian

Author: gaopeng QQ:22389860 Mail: gaopp_200217@163.com

Waring: This tool only Little_endian platform!

Little_endian check ok!!!

-------------Now begin--------------

Check Mysql Version is:5.7.13-log

Check Mysql binlog format ver is:V4

------------Detail now--------------

>Gtid Event:Pos:194(0Xc2) N_pos:259(0X103) Time:1486946663 Event_size:65(bytes)

Gtid:4a6f2a67-5d87-11e6-a6bd-0c29a879a3:1000448

-->Query Event:Pos:259(0X103) N_Pos:400(0X190) Time:1486946663 Event_size:141(bytes)

Exe_time:0 ?Use_db:test Statment(35b-trun):create table testnull2 (id int,name

>Gtid Event:Pos:400(0X190) N_pos:465(0X1d1) Time:1486946680 Event_size:65(bytes)

Gtid:4a6f2a67-5d87-11e6-a6bd-0c29a879a3:1000449

-->Query Event:Pos:465(0X1d1) N_Pos:537(0X219) Time:1486946680 Event_size:72(bytes)

Exe_time:0 ?Use_db:test Statment(35b-trun):BEGIN

---->Map Event:Pos537(0X219) N_pos:595(0X253) Time:1486946680 Event_size:58(bytes)

TABLE_ID:210 DB_NAME:test TABLE_NAME:testnull2

------>Insert Event:Pos:595(0X253) N_pos:636(0X27c) Time:1486946680 Event_size:41(bytes)

Dml on table: test.testnull2 ?table_id:210 Gno:1000449

>Xid Event:Pos:636(0X27c) N_Pos:667(0X29b) Time:1486946680 Event_size:31(bytes)

COMMIT 1000449 /*!add by tool*/

這里找到了insert event:

------>Insert Event:Pos:595(0X253) N_pos:636(0X27c) Time:1486946680 Event_size:41(bytes)

Dml on table: test.testnull2 Gno:1000449

這里這個event的開始位置為595

進行使用mysqlbinlog --hexdump格式

# at 595

#170213 ?8:44:40 server id 93157 ?end_log_pos 636 CRC32 0x32dd470a

# Position ?Timestamp ? Type ? Master ID ? ? ? ?Size ? ? ?Master Pos ? ?Flags

# ? ? ?253 78 01 a1 58 ? 1e ? e5 6b 01 00 ? 29 00 00 00 ? 7c 02 00 00 ? 00 00

# ? ? ?266 d2 00 00 00 00 00 01 00 ?02 00 03 ff fd 04 74 65 |..............te|

# ? ? ?276 73 74 0a 47 dd 32 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|st.G.2|

# ? ? ? Write_rows: table id 210 flags: STMT_END_F

下面是-vv的輸出

### INSERT INTO `test`.`testnull2`

### SET

### ? @1=NULL /* type=3 meta=0 nullable=1 is_null=1 */

### ? @2='test' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */

### ? @3=NULL /* VARSTRING(60) meta=60 nullable=1 is_null=1 */

分解:

--event header 部分就不解析了table id 210,

--hexdump也明確的解析了,不理解參考前面的文章

# Position ?Timestamp ? Type ? Master ID ? ? ? ?Size ? ? ?Master Pos ? ?Flags

# ? ? ?253 78 01 a1 58 ? 1e ? e5 6b 01 00 ? 29 00 00 00 ? 7c 02 00 00 ? 00 00

--fixed data

d2 00 00 00 00 00:表ID就是./infobin中的TABLE_ID:210 也是mysqlbinlog中的Write_rows: table id 210

01 00:保留

02 00:m_extra_row_data,這部分是我看源碼找到的。

--variable data part

03:表中字段個數,當然我建表就是3個字段

ff: 源碼描述為 m_cols;/* Bitmap denoting columns available */

fd: 11111101 代表字段@1=NULL和@3=NULL,但是字段@2不為空這和mysqlbinlog解析的一致

@1=NULL /* type=3 meta=0 nullable=1 is_null=1 */

@2='test' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */

@3=NULL /* VARSTRING(60) meta=60 nullable=1 is_null=1 */

04:var 長度04 就是數據'test'的長度為4,當然為4

74 65 73 74:字符串'test'

ca 3f c1 05:crc 32校驗

到此為止WRITE_ROW_EVENT解析完畢

本文首發在云棲社區,遵循云棲社區版權聲明:本文內容由互聯網用戶自發貢獻,版權歸用戶作者所有,云棲社區不為本文內容承擔相關法律責任。云棲社區已在2020年6月升級到阿里云開發者社區。如果您發現有涉嫌抄襲的內容,請填寫侵權投訴表單進行舉報,一經查實,阿里云開發者社區將協助刪除涉嫌侵權內容。

網友評論

登錄后評論

0/500

評論

總結

以上是生活随笔為你收集整理的mysql write rows_解析MYSQL BINLOG 二进制格式(5)--WRITE_ROW_EVENT的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。