龙空技术网

编程大牛阿锐的MySql Binlog 初识教程

程序猿阿锐 883

前言:

如今各位老铁们对“mysqlbinlog d”大概比较看重,咱们都需要了解一些“mysqlbinlog d”的相关文章。那么小编在网上搜集了一些有关“mysqlbinlog d””的相关资讯,希望我们能喜欢,我们一起来学习一下吧!

Mysql日志

MySQL 的日志包括错误日志(ErrorLog),更新日志(Update Log),二进制日志(Binlog),查询日志(Query Log),慢查询日志(Slow Query Log)等;

更新日志是老版本的MySQL 才有的,目前已经被二进制日志替代;在默认情况下,系统仅仅打开错误日志,关闭了其他所有日志,以达到尽可能减少IO损耗提高系统性能的目的,但是在一般稍微重要一点的实际应用场景中,都至少需要打开二进制日志,因为这是MySQL很多存储引擎进行增量备份的基础,也是MySQL实现复制的基本条件;

下面介绍的就是二进制日志–Binlog

Binlog开启

默认Binlog是关闭的,首先要开启才能记录日志;

1.查看是否开启log_bin

1

2

3

4

5

6

mysql>show variables like'log_bin';

+---------------+-------+

|Variable_name|Value|

+---------------+-------+

|log_bin|OFF|

+---------------+-------+

2.开启log_bin

在my.ini中添加配置:

1

log_bin=D:/mysql/bin-log.log

3.重启mysql,再次查看

1

2

3

4

5

6

mysql>show variables like'log_bin';

+---------------+-------+

|Variable_name|Value|

+---------------+-------+

|log_bin|ON|

+---------------+-------+

4.查看Binlog

4.1显示binlog的名称和大小

1

2

3

4

5

6

mysql>show binary logs;

+----------------+-----------+

|Log_name|File_size|

+----------------+-----------+

|bin-log.000001|107|

+----------------+-----------+

4.2查看生成的binlog

想用查看到binlog可以往数据库中更新数据库(包括:插入,更新和删除操作),查询sql是无法生成binlog的

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

mysql>show binlog events;

+----------------+------+-------------+-----------+-------------+---------------

------------------------------------------------+

|Log_name|Pos|Event_type|Server_id|End_log_pos|Info

|

+----------------+------+-------------+-----------+-------------+---------------

------------------------------------------------+

|bin-log.000001|4|Format_desc|1|107|Server ver:5.

5.29-log,Binlog ver:4|

|bin-log.000001|107|Query|1|175|BEGIN

|

|bin-log.000001|175|Intvar|1|203|INSERT_ID=9

|

|bin-log.000001|203|Query|1|315|use`test`;in

sert into user(age,name)values(100,"zhaohui")|

|bin-log.000001|315|Xid|1|342|COMMIT/* xid=

41 */|

+----------------+------+-------------+-----------+-------------+---------------

------------------------------------------------+

Binlog相关参数

通过执行如下命令可以获得关于Binlog 的相关参数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

mysql>show variables like'%binlog%';

+-----------------------------------------+----------------------+

|Variable_name|Value|

+-----------------------------------------+----------------------+

|binlog_cache_size|32768|

|binlog_direct_non_transactional_updates|OFF|

|binlog_format|STATEMENT|

|binlog_stmt_cache_size|32768|

|innodb_locks_unsafe_for_binlog|OFF|

|max_binlog_cache_size|18446744073709547520|

|max_binlog_size|1073741824|

|max_binlog_stmt_cache_size|18446744073709547520|

|sync_binlog|0|

+-----------------------------------------+----------------------+

1.binlog_cache_size

在事务过程中容纳binlog SQL语句的缓存大小;binlog缓存是服务器支持事务存储引擎并且服务器启用了二进制日志(—log-bin选项)的前提下为每个Session分配的内存;

主要是用来提高binlog的写速度;可以通过MySQL的以下个状态变量来判断当前的binlog_cache_size的状况:Binlog_cache_use和Binlog_cache_disk_use

1

2

3

4

5

6

7

mysql>show status like'Binlog_cache%';

+-----------------------+-------+

|Variable_name|Value|

+-----------------------+-------+

|Binlog_cache_disk_use|0|

|Binlog_cache_use|4|

+-----------------------+-------+

Binlog_cache_use:使用缓冲区存放binlog的次数

Binlog_cache_disk_use:使用临时文件存放binlog的次数

2.binlog_stmt_cache_size

发生事务时非事务语句的缓存的大小,可以通过MySQL 的以下个状态变量来判断当前的binlog_stmt_cache_size的状况:Binlog_stmt_cache_use和Binlog_stmt_cache_disk_use

1

2

3

4

5

6

7

mysql>show status like'binlog_stmt_cache%';

+----------------------------+-------+

|Variable_name|Value|

+----------------------------+-------+

|Binlog_stmt_cache_disk_use|0|

|Binlog_stmt_cache_use|1|

+----------------------------+-------+

Binlog_stmt_cache_use:缓冲区存放binlog的次数

Binlog_stmt_cache_disk_use:临时文件存放binlog的次数

3.max_binlog_cache_size

和binlog_cache_size相对应,但是所代表的是binlog能够使用的最大cache内存大小;binlog_cache_size对应的每个Session,max_binlog_cache_size对应所有Session;

当我们执行多语句事务的时候,所有Session的使用的内存超过max_binlog_cache_size的值时,系统可能会报出”Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes of storage”的错误。

4.max_binlog_stmt_cache_size

同max_binlog_cache_size类似,非事务语句binlog能够使用的最大cache内存大小。

5.max_binlog_size

Binlog日志最大值,默认1G,。该大小并不能非常严格控制Binlog大小,尤其是当到达Binlog比较靠近尾部而又遇到一个较大事务的时候,系统为了保证事务的完整性,不可能做切换日志的动作,只能将该事务的所有SQL都记录进入当前日志,直到该事务结束。

6.sync_binlog

同步binlog缓存中数据到磁盘的方式:

sync_binlog=0

当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘;

sync_binlog=n(区间0-4294967295)

当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘;

系统默认设置为0,这种情况下性能最好,风险最大,可能导致binlog_cache中的数据丢失;sync_binlog=1性能最差,风险最小。

7.binlog_format

设置binlog的格式,可选值:STATEMENT, ROW, or MIXED;默认是:STATEMENT

7.1 ROW模式

日志中记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修改;

在ROW模式下bin-log中可以不记录执行的SQL语句的上下文相关的信息,只需要记录哪条数据被修改成什么样了,不会因为某些语法复制出现问题(比如function,trigger等);

缺点是每行数据的修改都会记录,最明显的就是update语句,导致更新多少条数据就会产生多少事件,使bin-log文件很大,而复制要网络传输,影响性能。

7.2 STATEMENT模式

每一条修改数据的sql都会被记录到bin-log中,slave端再根据sql语句重现,解决了ROW模式的缺点,不会产生大量是bin-log数据;

缺点是为了让sql能在slave端正确重现,需要记录sql在执行的上下文信息,另外一个问题就是在复制某些特殊的函数或者功能的时候会出现问题,比如sleep()函数。

7.3 MIXED模式

前面两种模式的结合,根据不同的情况分别使用ROW模式和STATEMENT模式。

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

enumLog_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 */

};

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|timestamp0:4|

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

||type_code4:1|

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

||server_id5:4|

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

||event_length9:4|

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

||next_position13:4|

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

||flags17:2|

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

||extra_headers19:x-19|

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

|event|fixed partx:y|

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

||variable part|

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

名字后面的两个数字表示:offset : length即从第几个字节开始,后面多少个字节用来存放数据

比如:timestamp(0 : 4)表示从第0个字节开始,往后四个字节用来存放timestamp

目前来说x=19,所有extra_headers是空的,y是fixed part的长度,不同的Event长度不一样。

Event简要分析

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

1

2

3

4

5

6

7

8

9

10

CREATE TABLE`btest`(

`id`bigint(20)NOTNULLAUTO_INCREMENT,

`age`int(11)DEFAULTNULL,

`name`varchar(255)DEFAULTNULL,

PRIMARY KEY(`id`)

)ENGINE=InnoDB DEFAULTCHARSET=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|timestamp0:4|

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

||type_code4:1|=FORMAT_DESCRIPTION_EVENT=15

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

||server_id5:4|

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

||event_length9:4|>=91

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

||next_position13:4|

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

||flags17:2|

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

|event|binlog_version19:2|=4

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

||server_version21:50|

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

||create_timestamp71:4|

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

||header_length75:1|

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

||post-header76:n|=arrayofnbytes,one byteper event

||lengths forall|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;

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 thread19:4|

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

||The time inseconds23:4|

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

||The length of the name of the database27:1|

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

||The error code28:2|

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

||The length of the status variable block30:2|

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

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

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,事务提交产生的事件。

总结

本文主要对Mysql Binlog做了一个大体的介绍,包括:Binlog的参数,格式以及最重要的事件;事件数量比较多,从最简单的增删改查入手,介绍了几个比较常见的事件;

后续会继续学习其他事件,对Binlog有更加详细的了解。

标签: #mysqlbinlog d