总体来说:在 tx_isolation= READ-COMMITTED 、binlog_format =statement 的情况下,mysql 没有gap 锁,这样binlog 记录的数据修改的顺序可能会导致 复制环境的 slave 数据和master 数据不一致。

模拟步骤

数据初始化

 CREATE TABLE `gapt` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ind_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
mysql> select * from gapt;
+----+------+
| id | name |
+----+------+
| 1 | 1 |
| 10 | 10 |
| 11 | 11 |
| 15 | 15 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 8 | 8 |
| 9 | 9 |
+----+------+

session1 和 session2 模拟

@session 1:
mysql> show variables like '%tx_isolation%';
+---------------+----------------+
| Variable_name | Value |
+---------------+----------------+
| tx_isolation | READ-COMMITTED |
+---------------+----------------+
1 row in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update gapt set id=name+20 where name between 5 and 11;
Query OK, 6 rows affected (0.00 sec)
Rows matched: 6 Changed: 6 Warnings: 0 @session2
mysql> show variables like '%tx_isolation%';
+---------------+----------------+
| Variable_name | Value |
+---------------+----------------+
| tx_isolation | READ-COMMITTED |
+---------------+----------------+
1 row in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into gapt select 24,5;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> system date
Fri Jun 19 10:55:38 CST 2015 @session1
mysql> select * from gapt where name between 5 and 11;
+----+------+
| id | name |
+----+------+
| 30 | 10 |
| 31 | 11 |
| 24 | 5 |
| 25 | 5 |
| 26 | 6 |
| 28 | 8 |
| 29 | 9 |
+----+------+
7 rows in set (0.00 sec) #你会发现 6行变成7行了,
mysql> system date;
Fri Jun 19 10:55:50 CST 2015
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

重点: 两个 session 执行完 commit,并且按照 binlog_format = statement 日志模式的话,那么最终的binlog日志记录应该是按照事务 commit 的顺序记录的。

#binlog 实际存储的执行顺序
@session2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into gapt select 24,5;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec) #session1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update gapt set id=name+20 where name between 5 and 11;
Query OK, 6 rows affected (0.00 sec)
mysql> commit;

如果是这样记录的话你会发现这个 @session1 的 update 语句会把 session2 刚刚插入的 name='5',id=24 数据也会更新掉了!!这也就导致了(如果有复制)从库从库的数据就会和复制的主库不一样了!!

问题来了,我是如何模拟的呢?我是设置 tx_isolation=READ-COMMITTED binlog_format= MIXED 的时候,上面的操作可以正确执行,这是因为 MySQL 识别到了这个可能存在不一致的复制情况,就把上面的操作转换成了 binlog_format=row 的二进制日志。

#150619 10:55:00 server id 4306  end_log_pos 283        Table_map: `repl`.`gapt` mapped to number 52
#150619 10:55:00 server id 4306 end_log_pos 319 Write_rows: table id 52 flags: STMT_END_F
BINLOG '
hISDVRPSEAAALgAAABsBAAAAADQAAAAAAAEABHJlcGwABGdhcHQAAgMPAmAAAg==
hISDVRfSEAAAJAAAAD8BAAAAADQAAAAAAAEAAv/8GAAAAAE1
'/*!*/;
# at 319
#150619 10:55:09 server id 4306 end_log_pos 346 Xid = 447 #session2 的 commit
COMMIT/*!*/;
# at 346
#150619 10:57:04 server id 4306 end_log_pos 414 Query thread_id=16 exec_time=0 error_code=0
SET TIMESTAMP=1434682624/*!*/;
BEGIN
/*!*/;
# at 414
# at 460
#150619 10:54:14 server id 4306 end_log_pos 460 Table_map: `repl`.`gapt` mapped to number 52
#150619 10:54:14 server id 4306 end_log_pos 578 Update_rows: table id 52 flags: STMT_END_F
BINLOG '
VoSDVRPSEAAALgAAAMwBAAAAADQAAAAAAAEABHJlcGwABGdhcHQAAgMPAmAAAg==
VoSDVRjSEAAAdgAAAEICAAAAADQAAAAAAAEAAv///AUAAAABNfwZAAAAATX8BgAAAAE2/BoAAAAB
NvwIAAAAATj8HAAAAAE4/AkAAAABOfwdAAAAATn8CgAAAAIxMPweAAAAAjEw/AsAAAACMTH8HwAA
AAIxMQ==
'/*!*/;
# at 578
#150619 10:57:04 server id 4306 end_log_pos 605 Xid = 443 #session1 的 commit
COMMIT/*!*/;

binlog_format 为什么转化为 row 就可以呢,因为 row 格式的日志记录的是底层数据真正的变化,这样就不会导致复制环境的主从数据不一致了。

ps: 如果有什么理解错误的,或者模拟的不合理的地方,麻烦纠正指出来,谢谢。

mysql rc模式时binlog_format=row的解释【转】的更多相关文章

  1. mysql 5.7配置项最详细的解释

    配置样例 首先提供一个我使用的配置样例 [client] #password=88888888 socket=/data/var/mysql/mysql.sock [mysqld_safe] pid- ...

  2. mysql 主从模式总结(一)

    1. 主从模式的部署步骤 目标:部署一个有3台主机的单主模式的MySQL分组. Primary:192.168.197.110. Secondary:192.168.197.111. Secondar ...

  3. MySQL Binlog--MIXED模式下数据更新

    在 Mixed 模式下,MySQL 会根据执行的每一条具体的 SQL 语句来区分对待记录的日志形式,也就是在 statement 和 row 之间选择一种.如果SQL语句为UPDATE/DELETE等 ...

  4. mysql查询更新时的锁表机制分析

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(t ...

  5. RR模式下利用区间锁防止幻读,RC模式没有区间锁会出现幻读

    Session 1: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from ...

  6. mysql READ-COMMITTED 模式下 行锁不会升级到表级锁

    mysql> select sn,id,info from s100 group by id; +-----+------+------+ | sn | id | info | +-----+- ...

  7. mysql bin-logrow模式,base64转正常sql

    可以通过以下命令查看日志是否开启查看 show global variables like '%log%'; 当bin-log的模式设置为row时 不仅日志长得快 , 并且查看执行的sql时 , 也稍 ...

  8. mysql查询更新时的锁表机制分析(只介绍了MYISAM)

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(t ...

  9. MySql 严格模式相关配置

    目录 MySql 严格模式 MySQL的sql_mode合理设置 sql model 常用来解决下面几类问题 sql_mode常用值 注意 改为严格模式后可能会存在的问题 模式设置和修改(以解决上述问 ...

随机推荐

  1. 关于封装Dll为Web Service技术方案的讨论

    关于web架构技术方案的讨论整理 Sonictl 2014年1月25日10:05:52 本着"三人行必有我师"的学习态度,我在近期跟x老师做了大量沟通,结合我们单位对于" ...

  2. aix-syslog

    收集网络内路由器的日志信息,同时把本地日志信息与路由器信息分开. /etc/syslog.conf我写成: ## 本地日志处理 *.notice;*.err;*.warn<tab>;< ...

  3. 用python登录远程salt,并执行命令

    用python操作saltstack,如果是在本地,则可以用python的salt模块,但如果要操作远程saltstack,则不行,今天就来看看怎么操作. 用python操作远程的saltstack, ...

  4. 0_Simple__UnifiedMemoryStreams

    使用 OpenMP 和 pthreads 两种环境,利用实现统一内存编址,计算基本的矩阵乘法 result = α * A * x + β * result . ▶ 源代码 #include < ...

  5. Mysql数据库查询数据文件大小

    参考网站:https://zhidao.baidu.com/question/201227796936321525.html 用SQL命令查看Mysql数据库大小 要想知道每个数据库的大小的话,步骤如 ...

  6. CSS 3栏自适应布局

    绝对定位 css html,body{margin: 0px;height:100%;} div{height: 100%;} .left,.right {top: 0px;position: abs ...

  7. 迭代器iter()

    from collections import Iterable print(isinstance({},iterable)) # 判断是否可迭代 from collections import It ...

  8. style css

    Title 语文 用户名 用户名 数学 英语 <!DOCTYPE html><html lang="en"><head> <meta ch ...

  9. vue深入了解组件——Prop

    一.Prop的大小写(camelCase vs kebab-case) HTML中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符.这意味着当你使用DOM中的模板时,cameCase ...

  10. ubuntu16.04设置电池充电阈值

    thinkpad在安装ubuntu16.04之后,设置充电阈值: 方法一: 使用双系统,在windows下使用联想的Lenovo setting center设置之后,在ubuntu之下也可以保持相同 ...