mysql rc模式时binlog_format=row的解释【转】
总体来说:在 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的解释【转】的更多相关文章
- mysql 5.7配置项最详细的解释
配置样例 首先提供一个我使用的配置样例 [client] #password=88888888 socket=/data/var/mysql/mysql.sock [mysqld_safe] pid- ...
- mysql 主从模式总结(一)
1. 主从模式的部署步骤 目标:部署一个有3台主机的单主模式的MySQL分组. Primary:192.168.197.110. Secondary:192.168.197.111. Secondar ...
- MySQL Binlog--MIXED模式下数据更新
在 Mixed 模式下,MySQL 会根据执行的每一条具体的 SQL 语句来区分对待记录的日志形式,也就是在 statement 和 row 之间选择一种.如果SQL语句为UPDATE/DELETE等 ...
- mysql查询更新时的锁表机制分析
为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(t ...
- RR模式下利用区间锁防止幻读,RC模式没有区间锁会出现幻读
Session 1: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from ...
- mysql READ-COMMITTED 模式下 行锁不会升级到表级锁
mysql> select sn,id,info from s100 group by id; +-----+------+------+ | sn | id | info | +-----+- ...
- mysql bin-logrow模式,base64转正常sql
可以通过以下命令查看日志是否开启查看 show global variables like '%log%'; 当bin-log的模式设置为row时 不仅日志长得快 , 并且查看执行的sql时 , 也稍 ...
- mysql查询更新时的锁表机制分析(只介绍了MYISAM)
为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(t ...
- MySql 严格模式相关配置
目录 MySql 严格模式 MySQL的sql_mode合理设置 sql model 常用来解决下面几类问题 sql_mode常用值 注意 改为严格模式后可能会存在的问题 模式设置和修改(以解决上述问 ...
随机推荐
- Linux火焰图-centos
centos7.5mini安装 yum install -y yum-utils perf debuginfo-install -y perf #debuginfo-install下载了305MB的文 ...
- 提高solr的搜索速度
之前是使用12台机分布式搜索,1台为主机做索引并分发给子机,8台做大索引搜索服务,3 台做小索引搜索服务,配置基本是内存在4-8G,cpu:2-8core的服务器,索引的大小为8G.搜索的响应时间 是 ...
- nodejs——发送邮件(带附件)
用到的包是 nodemailer,简单,有效. 1.auth 中的 pass,是指“邮箱第三方登录授权码”,如何获取授权码,以QQ邮箱为例,请点击:http://jingyan.baidu.com/a ...
- AJAX相关总结
AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. AJAX = 异步 J ...
- python学习之----初见网络爬虫(输出整个网页html的代码)
from urllib import urlopen html = urlopen('http://www.manluotuo.com') print (html.read()) 控制台输出整个网页h ...
- javascript日期相减,求时间差
//计算时间差 var from_date = new Date(from_time); var end_date = new Date(end_time); var time_different = ...
- Pycharm远程连接服务器(windows下远程修改服务器代码)
1.写在前面 之前一致用putty,ssh,修改代码,或者本地修改,上传到服务器,各种不爽,现在改用xshell,但是有时候还是不方便感觉,于是自己配置了远程连接pycharm,这样不用总是到 ...
- delphi const的用法
unit RadKeygen; interface uses Classes,SysUtils,Windows; function fun1():string; implementation cons ...
- Socket Error # 10013 Access denied
--------------------------- Debugger Exception Notification --------------------------- Project xxx. ...
- time 时间内置模块3种形态的转化
import time print(time.time()) #获得时间戳 1526998642.877814 print(time.sleep(2)) #停止2秒 print(time.gmti ...