mysql_bin log

binlog基本认识

MySQL中的binlog是一个二进制文件,它记录了所有的增删改操作。节点之间的复制就是依靠binlog来完成的。binlog具有三种模式:

  • Row模式
    日志中会记录成每一行数据被修改的日志,然后在slave端再对相同的数据进行修改。例如:update xxx where id in(1,2,3,4,5);采用该模式则会记录5条记录。
  • statement模式
    每一条会修改数据的sql都会记录到 master的binlog中。slave在复制的时候sql Thread会解析成和原来master端执行过的相同的sql来再次执行.
  • mixed模式
    Mixed即混合模式,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。
    新版本中的Statment level还是和以前一样,仅仅记录执行的语句。而新版本的MySQL中队row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。

Binlog结构和内容
日志由一组二进制日志文件(Binlog),加上一个索引文件(index);Binlog是一个二进制文件集合,每个Binlog以一个4字节的魔数开头,接着是一组Events;
1.魔数:0xfe62696e对应的是0xfebin;
2.Event:每个Event包含header和data两个部分;header提供了Event的创建时间,哪个服务器等信息,data部分提供的是针对该Event的具体信息,如具体数据的修改;
3.第一个Event用于描述binlog文件的格式版本,这个格式就是event写入binlog文件的格式;
4.其余的Event按照第一个Event的格式版本写入;
5.最后一个Event用于说明下一个binlog文件;
6.Binlog的索引文件是一个文本文件,其中内容为当前的binlog文件列表,比如:

1

D:\mysql\bin-log.000001

参考:https://dev.mysql.com/doc/internals/en/binary-log-structure-and-contents.html

Binlog的Event类型
官方提供的可能Event类型有36种,具体看下面的枚举:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

enum Log_event_type {

  UNKNOWN_EVENT= 0,

  START_EVENT_V3= 1,

  QUERY_EVENT= 2,

  STOP_EVENT= 3,

  ROTATE_EVENT= 4,

  INTVAR_EVENT= 5,

  LOAD_EVENT= 6,

  SLAVE_EVENT= 7,

  CREATE_FILE_EVENT= 8,

  APPEND_BLOCK_EVENT= 9,

  EXEC_LOAD_EVENT= 10,

  DELETE_FILE_EVENT= 11,

  NEW_LOAD_EVENT= 12,

  RAND_EVENT= 13,

  USER_VAR_EVENT= 14,

  FORMAT_DESCRIPTION_EVENT= 15,

  XID_EVENT= 16,

  BEGIN_LOAD_QUERY_EVENT= 17,

  EXECUTE_LOAD_QUERY_EVENT= 18,

  TABLE_MAP_EVENT = 19,

  PRE_GA_WRITE_ROWS_EVENT = 20,

  PRE_GA_UPDATE_ROWS_EVENT = 21,

  PRE_GA_DELETE_ROWS_EVENT = 22,

  WRITE_ROWS_EVENT = 23,

  UPDATE_ROWS_EVENT = 24,

  DELETE_ROWS_EVENT = 25,

  INCIDENT_EVENT= 26,

  HEARTBEAT_LOG_EVENT= 27,

  IGNORABLE_LOG_EVENT= 28,

  ROWS_QUERY_LOG_EVENT= 29,

  WRITE_ROWS_EVENT = 30,

  UPDATE_ROWS_EVENT = 31,

  DELETE_ROWS_EVENT = 32,

  GTID_LOG_EVENT= 33,

  ANONYMOUS_GTID_LOG_EVENT= 34,

  PREVIOUS_GTIDS_LOG_EVENT= 35,

  ENUM_END_EVENT

  /* end marker */

};

参考:https://dev.mysql.com/doc/internals/en/event-classes-and-types.html

Event结构官网提供了3个版本,分别是v1,v3,v4:
v1:用在MySQL 3.23
v3:用在MySQL 4.0.2-4.1
v4:用在MySQL 5.0之后

现在MySQL的版本基本都使用5.0之后的版本,可以直接看v4,具体如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

+=====================================+

| event  | timestamp         0 : 4    |

| header +----------------------------+

|        | type_code         4 : 1    |

|        +----------------------------+

|        | server_id         5 : 4    |

|        +----------------------------+

|        | event_length      9 : 4    |

|        +----------------------------+

|        | next_position    13 : 4    |

|        +----------------------------+

|        | flags            17 : 2    |

|        +----------------------------+

|        | extra_headers    19 : x-19 |

+=====================================+

| event  | fixed part        x : y    |

| data   +----------------------------+

|        | variable part              |

+=====================================+

名字后面的两个数字表示:offset : length即从第几个字节开始,后面多少个字节用来存放数据
比如:timestamp(0 : 4)表示从第0个字节开始,往后四个字节用来存放timestamp
目前来说x=19,所有extra_headers是空的,y是fixed part的长度,不同的Event长度不一样。

参考:https://dev.mysql.com/doc/internals/en/event-structure.html

Event简要分析
1.从一个最简单的实例来分析其中的Event,包括创建表,插入数据,更新数据,删除数据;binlog_format使用的是默认的STATEMENT;

1

2

3

4

5

6

7

8

9

10

CREATE TABLE `btest` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `age` int(11) DEFAULT NULL,

  `name` varchar(255) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

insert into btest values(1,100,'zhaohui');

update btest set name='zhaohui_new' where id=1;

delete from btest where id=1;

2.查看所有的Events

1

show binlog events;

上图中一共出现了3中类型的Event,分别是Format_desc,Query和Xid,下面进行简单的分析

2.1Format_desc_Event
官网格式如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

+=====================================+

| event  | timestamp         0 : 4    |

| header +----------------------------+

|        | type_code         4 : 1    | = FORMAT_DESCRIPTION_EVENT = 15

|        +----------------------------+

|        | server_id         5 : 4    |

|        +----------------------------+

|        | event_length      9 : 4    | >= 91

|        +----------------------------+

|        | next_position    13 : 4    |

|        +----------------------------+

|        | flags            17 : 2    |

+=====================================+

| event  | binlog_version   19 : 2    | = 4

| data   +----------------------------+

|        | server_version   21 : 50   |

|        +----------------------------+

|        | create_timestamp 71 : 4    |

|        +----------------------------+

|        | header_length    75 : 1    |

|        +----------------------------+

|        | post-header      76 : n    | = array of n bytes, one byte per event

|        | lengths for all            |   type that the server knows about

|        | event types                |

+=====================================+

使用十六进制方式打开文件bin-log.000001,以下是Format_desc_Event的十六进制代码:

可以先看前面的4+103=107个字节,4字节是binlog的魔数,103字节是Format_desc_Event,其中有19字节是header;
注:Binlog日志是小端字节顺序
0x5A0504AA四个字节是timestamp;0x0F一个字节表示type_code;0x00000001四个字节为server_id;0x00000067四个字节是event_length,对应的十进制就是103;
0x0000006b四个字节是next_position,即下一个Event的开始位置为107;ox0001两个字节是flags;header总计19字节。
data总字节数=103-19即84字节,排除掉前面的57个字节,剩余27字节表示post-header lengths for all event types;
post-header lengths:从START_EVENT_V3开始到第27个Event,每个Event的fixed part lengths;
Format_desc_Event位置是15,可以在图中找到15的位置是0x54,对应十进制是84,即fixed part lengths=84,而这个值刚好是57+27=84,所以Format_desc_Event不存在variable part;

参考:https://dev.mysql.com/doc/internals/en/binary-log-versions.html

2.2Query_Event

以下的create table产生的Query_Event的十六进制代码:

header共19字节,0x02一个字节表示type_code(Query_Event=2);0x00000101四个字节是event_length,对应的十进制就是257(pos=107,End_log_pos=364);
Query_Event在post-header的第二个位置0x0d,所有fix part lengths=13;
variable part=257-19-13=225字节
具体fix data和variable data:

1

2

3

4

5

6

7

8

9

10

11

+==============================================================+

| fix    | The ID of the thread                      19 : 4    |

| data   +-----------------------------------------------------+

|        | The time in seconds                       23 : 4    |

|        +-----------------------------------------------------+

|        | The length of the name of the database    27 : 1    |

|        +-----------------------------------------------------+

|        | The error code                            28 : 2    |

|        +-----------------------------------------------------+

|        | The length of the status variable block   30 : 2    |

+==============================================================+

在创建表产生一个Query_Event,insert、update以及delete执行之后分别产生了2个Query_Event和一个Xid_Event。

更多详细:https://dev.mysql.com/doc/internals/en/event-data-for-specific-event-types.html

2.3Xid_Event

以下的更新数据产生的Xid_Event的十六进制代码:

header共19字节,0x10一个字节表示type_code(XID_EVENT=16);0x0000001b四个字节是event_length,对应的十进制就是27(pos=536,End_log_pos=563);
2Xid_Event在post-header的第十六个位置0x00,所有fix part lengths=0;
variable part=27-19=8字节
8字节:The XID transaction number。

insert、update以及delete执行之后分别产生了Xid_Event,事务提交产生的事件。

更多详细:https://dev.mysql.com/doc/internals/en/event-data-for-specific-event-types.html

总结
本文主要对Mysql Binlog做了一个大体的介绍,包括:Binlog的参数,格式以及最重要的事件;事件数量比较多,从最简单的增删改查入手,介绍了几个比较常见的事件;
后续会继续学习其他事件,对Binlog有更加详细的了解。

作者:jerrik
链接:https://www.jianshu.com/p/e19d9312d1b5
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

猜你喜欢

转载自blog.csdn.net/u010325193/article/details/86586802