mysql 之 主从binlog格式详解

binlog文件记录格式statement、row、rixed三种,5.7之前默认为statement模式,到5.7开始默认为row模式。

statement就是语句模式,binlog记录对数据做变动的所有语句,要看binlog记录详细内容可以用mysqlbing查看,现在来对statement模式进行测试:

这里事先创建一个t2表做测试

mysql> show create table t2\G

*************************** 1. row ***************************

Table: t2

Create Table: CREATE TABLE `t2` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(100) DEFAULT NULL,

`date_time` datetime DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4

1 row in set (0.00 sec)

mysql> select @@binlog_format;

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

| @@binlog_format |

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

| STATEMENT

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

mysql> insert into t2(name,date_time) values(uuid(),now());

Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from t2\G;

*************************** 1. row ***************************

id: 1

name: 7ba7e11e-f6eb-11e5-a293-000c29fa3584

date_time: 2016-03-31 10:51:35

1 row in set (0.00 sec)

现在来查看binlog日志记录

# at 6450

# at 6482

#160331 10:51:35 server id 249  end_log_pos 6482 CRC32 0xa3e29747       Intvar

SET INSERT_ID=1/*!*/;

#160331 10:51:35 server id 249  end_log_pos 6611 CRC32 0x9fc70343       Query   thread_id=14    exec_time=0     error_code=0

SET TIMESTAMP=1459392695/*!*/;

insert into t2(name,date_time) values(uuid(),now())

/*!*/;

# at 6611

#160331 10:51:35 server id 249  end_log_pos 6642 CRC32 0xdff2aeb8       Xid = 170

COMMIT/*!*/;

binlog日志是有一个个的event组成,所以一条sql就会产生数行记录数据,由上面红色部分可以看到有个SET INSERT_ID=1和SET TIMESTAMP,经过对时间戳转换正好是我们插入数据的时间,表结构中ID其实是自增的,在这可以看出binlog在执行语句之前对ID和now()函数的值进行了记录保证从数据库数据一致,然而并未记录uuid()函数的值,这就会导致主从不一致。

row模式顾名思义就是对每个变更的行数据进行记录,下面就对它进行测试:

mysql> insert into t2(name,date_time) values(uuid(),now());

Query OK, 1 row affected (0.00 sec)

mysql> select * from t2 order by id desc limit 1;

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

| id | name                      | date_time        |

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

|  7 | 00e3a5b8-f6ed-11e5-86fc-000c29fa3584 | 2016-03-31 11:02:28 |

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

1 row in set (0.00 sec)

产看binlog日志记录,因为是row模式记录的是MySQL内部识别的编码所以需要加-v参数转换为我们能认识的行数据

BEGIN

/*!*/;

# at 337

#160331 11:02:28 server id 249  end_log_pos 385 CRC32 0xff339393        Table_map: `mc`.`t2` mapped to number 109

# at 385

#160331 11:02:28 server id 249  end_log_pos 468 CRC32 0x1560b09c        Write_rows: table id 109 flags: STMT_END_F

BINLOG ‘

RJP8VhP5AAAAMAAAAIEBAAAAAG0AAAAAAAEAAm1jAAJ0MgADAw8SA5ABAAaTkzP/

RJP8Vh75AAAAUwAAANQBAAAAAG0AAAAAAAEAAgADB/gHAAAAJAAwMGUzYTViOC1mNmVkLTExZTUt

ODZmYy0wMDBjMjlmYTM1ODSZmP6wnJywYBU=

‘/*!*/;

### INSERT INTO `mc`.`t2`

### SET

###   @1=7

###   @2=‘00e3a5b8-f6ed-11e5-86fc-000c29fa3584‘

###   @3=‘2016-03-31 11:02:28‘

# at 468

#160331 11:02:28 server id 249  end_log_pos 499 CRC32 0x17f01cac        Xid = 9

COMMIT/*!*/;

上面绿色部分就是MySQL记录的行记录变更的编码,红色部分就是转化出来的数据,由红色部分看出其实是按我们表结构中字段的顺序定义为了1、2、3的变量进行了直接赋值,这样只要主从数据结构一样就能保证对函数产生的数据的一致性。

插入记录方式了解了,那现在来看下row模式的update、delete语句操作是怎样记录的。

mysql> select * from t2 where date_time=‘2016-03-31 11:09:11‘;

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

| id | name                      | date_time        |

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

|  8 | f0cac692-f6ed-11e5-86fc-000c29fa3584 | 2016-03-31 11:09:11 |

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

1 row in set (0.00 sec)

mysql> update t2 set name=‘a‘ where date_time=‘2016-03-31 11:09:11‘;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

BEGIN

/*!*/;

# at 939

#160331 11:19:03 server id 249  end_log_pos 987 CRC32 0x7ad2c2f9        Table_map: `mc`.`t2` mapped to number 109

# at 987

#160331 11:19:03 server id 249  end_log_pos 1032 CRC32 0x30d090d0       Update_rows: table id 109 flags: STMT_END_F

BINLOG ‘

J5f8VhP5AAAAMAAAANsDAAAAAG0AAAAAAAEAAm1jAAJ0MgADAw8SA5ABAAb5wtJ6

J5f8Vh/5AAAALQAAAAgEAAAAAG0AAAAAAAEAAgADAQL+CAAAAP4BAGHQkNAw

‘/*!*/;

### UPDATE `mc`.`t2`

### WHERE

###   @1=8

### SET

###   @2=‘a‘

# at 1032

#160331 11:19:03 server id 249  end_log_pos 1063 CRC32 0x9f1f68e7       Xid = 17

COMMIT/*!*/;

绿色部分就是要在从数据库执行的记录,可以看出来是用的where @1=8,按字段顺序@1为我们的主键ID,但是我们不是用date_time做的条件吗,不急........下面再看下

mysql> alter table t2 modify id int,drop primary key;

Query OK, 8 rows affected (0.06 sec)

Records: 8  Duplicates: 0  Warnings: 0

mysql> select * from t2 where date_time=‘2016-03-31 11:09:11‘;

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

| id   | name | date_time           |

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

|    8 | a    | 2016-03-31 11:09:11 |

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

1 row in set (0.00 sec)

mysql> update t2 set name=‘aaa‘ where date_time=‘2016-03-31 11:09:11‘;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

BEGIN

/*!*/;

# at 1378

#160331 11:23:05 server id 249  end_log_pos 1426 CRC32 0x603c2455       Table_map: `mc`.`t2` mapped to number 110

# at 1426

#160331 11:23:05 server id 249  end_log_pos 1481 CRC32 0x5edd4f26       Update_rows: table id 110 flags: STMT_END_F

BINLOG ‘

GZj8VhP5AAAAMAAAAJIFAAAAAG4AAAAAAAEAAm1jAAJ0MgADAw8SA5ABAAdVJDxg

GZj8Vh/5AAAANwAAAMkFAAAAAG4AAAAAAAEAAgAD/wL4CAAAAAEAYZmY/rJL/gMAYWFhJk/dXg==

‘/*!*/;

### UPDATE `mc`.`t2`

### WHERE

###   @1=8

###   @2=‘a‘

###   @3=‘2016-03-31 11:09:11‘

### SET

###   @2=‘aaa‘

# at 1481

#160331 11:23:05 server id 249  end_log_pos 1512 CRC32 0x8f9b33cb       Xid = 20

COMMIT/*!*/;

这次我们把主键删掉对记录做的update操作,看出绿色部分where条件对我们所有字段都做了匹配的,delete操作也是一样,由此可以看出在row模式下从服务器做数据更改时是根据主键对数据查找进行更新,如果没有主键就是全部扫描。

现在来对最后一个mixed混合模式进行测试:

mysql> insert into t2(name,date_time) values(uuid(),now());

Query OK, 1 row affected (0.00 sec)

mysql> insert into t2(name,date_time) values(‘a‘,now());

Query OK, 1 row affected (0.00 sec)

mysql> select * from t2 order by id desc limit 2;

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

| id | name                      | date_time       |

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

| 14 | a                        | 2016-03-31 11:31:11 |

| 13 | f4bb52a8-f6f0-11e5-a33c-000c29fa3584 | 2016-03-31 11:30:46 |

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

2 rows in set (0.00 sec)

BEGIN

/*!*/;

# at 337

#160331 11:30:46 server id 249  end_log_pos 385 CRC32 0xfb29d460        Table_map: `mc`.`t2` mapped to number 109

# at 385

#160331 11:30:46 server id 249  end_log_pos 468 CRC32 0x93c87ab6        Write_rows: table id 109 flags: STMT_END_F

BINLOG ‘

5pn8VhP5AAAAMAAAAIEBAAAAAG0AAAAAAAEAAm1jAAJ0MgADAw8SA5ABAAZg1Cn7

5pn8Vh75AAAAUwAAANQBAAAAAG0AAAAAAAEAAgADB/gNAAAAJABmNGJiNTJhOC1mNmYwLTExZTUt

YTMzYy0wMDBjMjlmYTM1ODSZmP63rrZ6yJM=

‘/*!*/;

### INSERT INTO `mc`.`t2`

### SET

###   @1=13

###   @2=‘f4bb52a8-f6f0-11e5-a33c-000c29fa3584‘

###   @3=‘2016-03-31 11:30:46‘

# at 468

#160331 11:30:46 server id 249  end_log_pos 499 CRC32 0xa8544a3c        Xid = 9

COMMIT/*!*/;

# at 499

#160331 11:31:11 server id 249  end_log_pos 564 CRC32 0x04029a22        GTID    last_committed=1        sequence_number=2

SET @@SESSION.GTID_NEXT= ‘81570ee3-e47e-11e5-a7cd-000c29fa3584:17‘/*!*/;

# at 564

#160331 11:31:11 server id 249  end_log_pos 647 CRC32 0x0741bd22        Query   thread_id=2     exec_time=0     error_code=0

SET TIMESTAMP=1459395071/*!*/;

BEGIN

/*!*/;

# at 647

# at 679

#160331 11:31:11 server id 249  end_log_pos 679 CRC32 0xe4ca7495        Intvar

SET INSERT_ID=14/*!*/;

#160331 11:31:11 server id 249  end_log_pos 805 CRC32 0x01e84a88        Query   thread_id=2     exec_time=0     error_code=0

use `mc`/*!*/;

SET TIMESTAMP=1459395071/*!*/;

insert into t2(name,date_time) values(‘a‘,now())

/*!*/;

# at 805

#160331 11:31:11 server id 249  end_log_pos 836 CRC32 0xf9959f9c        Xid = 10

COMMIT/*!*/;

有表查询结果限制我们第一次使用uuid插入时id值为13,在binlog中可以看出是使用了row模式记录,第二次未使用uuid函数时就直接记录的语句,由此可以得出mixed模式是当语句中含有uuid这种不安全的函数时就会使用row模式记录。

经过上面反复的的测试可以得出三种模式各自的优缺点:

statement

优点:直接记录操作的语句,binlog产生量小,易于网络传送

缺点:对uuid这种不安全的函数产生的数据不能保证主从一致

row

优点:记录每行的数据,在数据结构一致的情况下能很好的保证主从数据一致性

缺点:因为记录每行数据,产生数据量相对来说比较大,增加网络传输量(binlog_row_image=minimal 可以减少一部分日志量),每行的变更都会在从查找执行,增加从的执行压力,假如表未设置主键情况不容乐观

mixed

优点:根据情况自动判断采用什么模式,可以减少binlog日志量

缺点:增加一次判断也就增加了主机的压力,而且对不安全的因素不一定能完全正确

在隔离级别为RC的情况下,采用statement格式不使用不安全的函数也有可能导致主从数据不一致,大家都知道MySQL binlog是按事物的commit顺序记录,在一个事物对数据进行更新,为及时提交,另外一个事物插入满足前一个事物更新的条件,因为RC并没有间隙锁机制,就会引起从数据和主数据不一致。

时间: 2024-10-07 06:52:54

mysql 之 主从binlog格式详解的相关文章

CentOS 6.5 MySQL/MariaDB数据备份与恢复备份详解

MySQL/MariaDB数据备份与恢复备份 数据对我们来说再重要不过了,那我们如何做到对数据尽可能的安全呢,当我们的数据丢失了那又该怎么做呢,所以说数据备份对我们的数据安全性来说太重要了. 数据对我们来说再熟悉不过了,也最平常不过了,我们每天都在接触各色各样的数据,数据记录了我们平常相关的业务信息,所以数据对于我们来说是很重要的,这么重要的数据如果我们的数据丢失了那我们是不是相关的业务都没法进行了呢,这应该是个很麻烦的问题,那我们怎么保护我们的数据的安全呢,这就要用到我们的数据备份了. 如何执

mysql中event的用法详解

一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存储过程使用,在某一特定的时间点,触发相关的SQL语句或存储过程. 二.适用范围对于每隔一段时间就有固定需求的操作,如创建表,删除数据等操作,可以使用event来处理. 例如:使用event在每月的1日凌晨1点自动创建下个月需要使用的三张表. 三.使用权限单独使用event调用SQL语句时,查看和创建

深入MySQL用户自定义变量:使用详解及其使用场景案例

一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连续第n(n即计数器的值)次进行转发帖子时,将会获得与n相关的分数.然而,在第一次改进后问题依然存在.所以,这次在之前的基础上,通过使用MySQL变量的途径来解决该问题. 二.到底MySQL的变量分哪几类? MySQL变量一共分为两大类:用户自定义变量和系统变量.如下: 用户自定义变量 局部变量 会话

mysql TIMESTAMP(时间戳)详解

TIMESTAMP的变体 1,TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP  在创建新记录和修改现有记录的时候都对这个数据列刷新 2,TIMESTAMP DEFAULT CURRENT_TIMESTAMP  在创建新记录的时候把这个字段设置为当前时间,但以后修改时,不再刷新它 3,TIMESTAMP ON UPDATE CURRENT_TIMESTAMP  在创建新记录的时候把这个字段设置为0,以后修改时刷新它 4

MySql 安装及初级使用详解

1. sudo apt-get install mysql-server, input administrator password , '123' 2. enter mysql promot in command line, 'mysql -u root -p', input password 3. create database "CREATE DATABASE xoops:" 4. 允许root远程登陆: 从所有主机:grant all privileges on *.* to

MySQL数据类型以及基本使用详解

MySQL数据类型以及基本使用详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL服务器的主要组件 我们知道MySQL的主要组件主要是由服务端(mysqld)和客户端(mysql)组成的.它们都共用一个配置文件(通常叫做my.cnf),这个配置文件很独特,它需要使用中括号括起来标明是为哪种组件使用的,例如[mysql]下面的指令就表示为客户端配置的参数,如果[mysqld]下面的指令就表示为服务端配置的参数.其实MySQL的客户端组件有很多个,本篇博客是用的my

图解MYSQL JOIN ON,SQL JOIN 详解,数据库sql join语句

对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams 解释了SQL的Join.我觉得清楚易懂,转过来. 假设我们有两张表. Table A 是左边的表. Table B 是右边的表. 其各有四条记录,其中有两条记录是相同的,如下所示

BMP格式详解

BMP格式详解 BMP文件格式详解(BMP file format) BMP文件格式,又称为Bitmap(位图)或是DIB(Device-Independent Device,设备无关位图),是Windows系统中广泛使用的图像文件格式.由于它可以不作任何变换地保存图像像素域的数据,因此成为我们取得RAW数据的重要来源.Windows的图形用户界面(graphical user interfaces)也在它的内建图像子系统GDI中对BMP格式提供了支持. 下面以Notepad++为分析工具,结合

多媒体开发之---h264格式详解

http://blog.csdn.net/bluebirdssh/article/details/6533501 http://blog.csdn.net/d_l_u_f/article/details/7260772 http://blog.csdn.net/sunnylgz/article/details/7680262 http://blog.csdn.net/heanyu/article/details/6204414 多媒体开发之---h264格式详解,布布扣,bubuko.com