浅析MySQL基于ROW格式的二进制日志
上文分析的二进制日志实际上是基于STATEMENT格式的,下面我们来看看基于ROW格式的二进制日志,毕竟,两者对应的binlog事件类型也不一样,同时,很多童鞋反映基于ROW格式的二进制日志无法查到原生的DML语句,关于这个问题,其实官方也给出了解决方案,下面,将一一揭晓。
首先,来几条测试数据
mysql> set binlog_format=row;
Query OK, 0 rows affected (0.00 sec) mysql> flush logs;
Query OK, 0 rows affected (0.01 sec) mysql> insert into test.t1 values(1,'a');
Query OK, 1 row affected (0.00 sec) mysql> use testDatabase changed
mysql> insert into t1 values(2,'b');
Query OK, 1 row affected (0.00 sec) mysql> update t1 set name='c' where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> delete from t1 where id=1;
Query OK, 1 row affected (0.01 sec)
首先通过SHOW BINLOG EVENTS查看二进制日志中的内容
mysql> show binlog events in 'mysql-bin.000025';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000025 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000025 | 120 | Query | 1 | 188 | BEGIN |
| mysql-bin.000025 | 188 | Table_map | 1 | 236 | table_id: 79 (test.t1) |
| mysql-bin.000025 | 236 | Write_rows | 1 | 278 | table_id: 79 flags: STMT_END_F |
| mysql-bin.000025 | 278 | Xid | 1 | 309 | COMMIT /* xid=175 */ |
| mysql-bin.000025 | 309 | Query | 1 | 381 | BEGIN |
| mysql-bin.000025 | 381 | Table_map | 1 | 429 | table_id: 79 (test.t1) |
| mysql-bin.000025 | 429 | Write_rows | 1 | 471 | table_id: 79 flags: STMT_END_F |
| mysql-bin.000025 | 471 | Xid | 1 | 502 | COMMIT /* xid=183 */ |
| mysql-bin.000025 | 502 | Query | 1 | 574 | BEGIN |
| mysql-bin.000025 | 574 | Table_map | 1 | 622 | table_id: 79 (test.t1) |
| mysql-bin.000025 | 622 | Update_rows | 1 | 672 | table_id: 79 flags: STMT_END_F |
| mysql-bin.000025 | 672 | Xid | 1 | 703 | COMMIT /* xid=184 */ |
| mysql-bin.000025 | 703 | Query | 1 | 775 | BEGIN |
| mysql-bin.000025 | 775 | Table_map | 1 | 823 | table_id: 79 (test.t1) |
| mysql-bin.000025 | 823 | Delete_rows | 1 | 865 | table_id: 79 flags: STMT_END_F |
| mysql-bin.000025 | 865 | Xid | 1 | 896 | COMMIT /* xid=185 */ |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
17 rows in set (0.00 sec)
再来通过mysqlbinlog查看
# mysqlbinlog mysql-bin.000025
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at
# :: server id end_log_pos CRC32 0x5b15ac4f Start: binlog v , server v 5.6.-log created ::
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
4MmzVw8BAAAAdAAAAHgAAAABAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAU+s
FVs=
'/*!*/;
# at
# :: server id end_log_pos CRC32 0x005847f0 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
SET @@session.pseudo_thread_id=/*!*/;
SET @@session.foreign_key_checks=, @@session.sql_auto_is_null=, @@session.unique_checks=, @@session.autocommit=/*!*/;
SET @@session.sql_mode=/*!*/;
SET @@session.auto_increment_increment=, @@session.auto_increment_offset=/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/;
SET @@session.lc_time_names=/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x2b8d2069 Table_map: `test`.`t1` mapped to number
# at
# :: server id end_log_pos CRC32 0xadc98fbc Write_rows: table id flags: STMT_END_F BINLOG '
5smzVxMBAAAAMAAAAOwAAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAANpII0r
5smzVx4BAAAAKgAAABYBAAAAAE8AAAAAAAEAAgAC//wBAAAAAWG8j8mt
'/*!*/;
# at
# :: server id end_log_pos CRC32 0x552dc682 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0x17d8173e Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x71a27e19 Table_map: `test`.`t1` mapped to number
# at
# :: server id end_log_pos CRC32 0xefda98ca Write_rows: table id flags: STMT_END_F BINLOG '
8smzVxMBAAAAMAAAAK0BAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAAMZfqJx
8smzVx4BAAAAKgAAANcBAAAAAE8AAAAAAAEAAgAC//wCAAAAAWLKmNrv
'/*!*/;
# at
# :: server id end_log_pos CRC32 0x7bed11c4 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0xd164b750 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x9fa3cabc Table_map: `test`.`t1` mapped to number
# at
# :: server id end_log_pos CRC32 0xb1646398 Update_rows: table id flags: STMT_END_F BINLOG '
9smzVxMBAAAAMAAAAG4CAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAAO8yqOf
9smzVx8BAAAAMgAAAKACAAAAAE8AAAAAAAEAAgAC///8AgAAAAFi/AIAAAABY5hjZLE=
'/*!*/;
# at
# :: server id end_log_pos CRC32 0x91a90c52 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0x5ae24c0b Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x33c52e84 Table_map: `test`.`t1` mapped to number
# at
# :: server id end_log_pos CRC32 0x77e907a2 Delete_rows: table id flags: STMT_END_F BINLOG '
+8mzVxMBAAAAMAAAADcDAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAAOELsUz
+8mzVyABAAAAKgAAAGEDAAAAAE8AAAAAAAEAAgAC//wBAAAAAWGiB+l3
'/*!*/;
# at
# :: server id end_log_pos CRC32 0xb0988385 Xid =
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
额,what is this,竟然没看到一条明文的DML语句
实际上,对于ROW格式的二进制日志,需要使用如下方式查看,这也是STATEMENT和ROW格式的差异之一
# mysqlbinlog mysql-bin.000025 -vv --base64-output=decode-rows
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at
# :: server id end_log_pos CRC32 0x5b15ac4f Start: binlog v , server v 5.6.-log created ::
# Warning: this binlog is either in use or was not closed properly.
# at
# :: server id end_log_pos CRC32 0x005847f0 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
SET @@session.pseudo_thread_id=/*!*/;
SET @@session.foreign_key_checks=, @@session.sql_auto_is_null=, @@session.unique_checks=, @@session.autocommit=/*!*/;
SET @@session.sql_mode=/*!*/;
SET @@session.auto_increment_increment=, @@session.auto_increment_offset=/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/;
SET @@session.lc_time_names=/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x2b8d2069 Table_map: `test`.`t1` mapped to number
# at
# :: server id end_log_pos CRC32 0xadc98fbc Write_rows: table id flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='a' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at
# :: server id end_log_pos CRC32 0x552dc682 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0x17d8173e Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x71a27e19 Table_map: `test`.`t1` mapped to number 79
# at
# :: server id end_log_pos CRC32 0xefda98ca Write_rows: table id flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='b' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at
# :: server id end_log_pos CRC32 0x7bed11c4 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0xd164b750 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x9fa3cabc Table_map: `test`.`t1` mapped to number 79
# at
# :: server id end_log_pos CRC32 0xb1646398 Update_rows: table id flags: STMT_END_F
### UPDATE `test`.`t1`
### WHERE
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='b' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
### SET
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='c' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at
# :: server id end_log_pos CRC32 0x91a90c52 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0x5ae24c0b Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x33c52e84 Table_map: `test`.`t1` mapped to number 79
# at
# :: server id end_log_pos CRC32 0x77e907a2 Delete_rows: table id flags: STMT_END_F
### DELETE FROM `test`.`t1`
### WHERE
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='a' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at
# :: server id end_log_pos CRC32 0xb0988385 Xid =
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
对于STATEMENT格式的binlog,所有的DML操作都记录在QUERY_EVENT中,而对于ROW格式的binlog,所有的DML操作都记录在ROWS_EVENT中,ROWS_EVENT分为三种:WRITE_ROWS_EVENT,UPDATE_ROWS_EVENT,DELETE_ROWS_EVENT,分别对应insert,update和delete操作。
对于insert操作,WRITE_ROWS_EVENT包含了要插入的数据
对于update操作,UPDATE_ROWS_EVENT不仅包含了修改后的数据,还包含了修改前的值。
对于delete操作,仅仅需要指定删除的主键(在没有主键的情况下,会给定所有列)
事实上,在ROW格式的binlog文件中, 每个ROWS_EVENT事件前都会有一个TABLE_MAP_EVENT,用于描述表的内部id和结构定义。
即便上述两个insert操作,一个没有执行use test操作,都不影响TABLE_MAP_EVENT的内容,这也会导致基于ROW格式下的库级别的复制和基于STATEMENT格式下库级别的复制的复制规则不一致。
如何在ROW格式中输出原生的DML语句?
MySQL实际上提供了一个参数,可以用于输出原生的DML语句,但是该语句仅仅是其注释的作用,并不会被应用。
如下所示,
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec) mysql> set binlog_rows_query_log_events=1;
Query OK, 0 rows affected (0.01 sec) mysql> insert into t1 values(3,'c');
Query OK, 1 row affected (0.00 sec)
对应的二进制的内容如下:
mysql> show binlog events in 'mysql-bin.000026';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000026 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000026 | 120 | Query | 1 | 192 | BEGIN |
| mysql-bin.000026 | 192 | Rows_query | 1 | 244 | # insert into t1 values(3,'c') |
| mysql-bin.000026 | 244 | Table_map | 1 | 292 | table_id: 79 (test.t1) |
| mysql-bin.000026 | 292 | Write_rows | 1 | 334 | table_id: 79 flags: STMT_END_F |
| mysql-bin.000026 | 334 | Xid | 1 | 365 | COMMIT /* xid=189 */ |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
6 rows in set (0.00 sec)
实际上,MySQL新增了一个事务类型来输出ROW格式中原生的DML语句,即ROWS_QUERY_EVENT。
自此以后,再也不用顾虑ROW格式的二进制日志中无法查看原生的DML语句了。
参考
1. MariaDB原理与实现
浅析MySQL基于ROW格式的二进制日志的更多相关文章
- MySQL基于ROW格式的数据恢复
大家都知道MySQL Binlog 有三种格式,分别是Statement.Row.Mixd.Statement记录了用户执行的原始SQL,而Row则是记录了行的修改情况,在MySQL 5.6以上的版本 ...
- (4.5)mysql备份还原——深入解析二进制日志(1)binlog的3种工作模式与配置
(4.5)mysql备份还原——深入解析二进制日志(binlog) 关键词:二进制日志,binlog日志 0.建议 (1)不建议随便去修改binlog格式(数据库级别) (2)binlog日志的清理 ...
- (4.7)mysql备份还原——深入解析二进制日志(3)binlog的三种日志记录模式详解
关键词:binlog模式,binlog,二进制日志,binlog日志 目录概述 0.binlog概述 查看binlog日志参数设置: show variables like '%log_bin%'; ...
- (4.6)mysql备份还原——深入解析二进制日志(2)binlog参数配置解析
关键词:binlog配置,binlog参数,二进制日志配置,二进制文件参数配置 关键词:binlog缓存,binlog 刷新 0.bin写入流程 写binlog流程如下:# 数据操作buffer po ...
- mysql导出csv/sql/newTable/txt的方法,mysql的导入txt/sql方法...mysql备份恢复mysqlhotcopy、二进制日志binlog、直接备份文件、备份策略、灾难恢复.....................................................
mysql备份表结构和数据 方法一. Create table new_table_nam备份到新表:MYSQL不支持: Select * Into new_table_name from old_t ...
- 如何开启MySQL 5.7.12 的二进制日志
1. 打开/etc下的my.cnf文件 2. 编辑它,添加内容: log_bin=binary-log #二进制日志的文件名 server_id=1 #必须指定server_id,这是MySQL ...
- my42_Mysql基于ROW格式的主从同步
模拟主从update事务,从库跳过部分update事务后,再次开始同步的现象 主库 mysql> select * from dbamngdb.isNodeOK; +----+--------- ...
- mysql主从复制linux配置(二进制日志文件)
安装mysql,两台机器一主(192.168.131.153),一从(192.168.131.154) 主机配置 修改主/etc/my.cnf文件 添加 #server_id=153 ###服务器id ...
- MySQL基于二进制日志的主从复制
一.什么是MySQL的主从复制? MySQL可以将一个数据库设置为主库,另一个数据库设置为该主库的从库,当主库发生了变更,会同步到从库中.MySQL的主从架构,可以是星型的,也可以是线型的. 星型架构 ...
随机推荐
- 领域驱动和MVVM应用于UWP开发的一些思考
领域驱动和MVVM应用于UWP开发的一些思考 0x00 起因 有段时间没写博客了,其实最近本来是根据梳理的MSDN上的资料(UWP开发目录整理)有条不紊的进行UWP学习的.学习中有了心得体会或遇到了问 ...
- AutoFac在项目中的应用
技能大全:http://www.cnblogs.com/dunitian/p/4822808.html#skill 完整Demo:https://github.com/dunitian/LoTCode ...
- CSS float 浮动属性
本篇主要介绍float属性:定义元素朝哪个方向浮动. 目录: 1. 页面布局方式:介绍文档流.浮动层以及float属性. 2. float:left :介绍float为 left 时的布局方式. 3. ...
- 高频交易算法研发心得--MACD指标算法及应用
凤鸾宝帐景非常,尽是泥金巧样妆. 曲曲远山飞翠色:翩翩舞袖映霞裳. 梨花带雨争娇艳:芍药笼烟骋媚妆. 但得妖娆能举动,取回长乐侍君王. [摘自<封神演义>纣王在女娲宫上香时题的诗] 一首定 ...
- 第一个移动前端开源项目-dailog
你还在为手机上没有忙碌光标而发愁吗?你还在抱怨弹出框组件要依赖zepto/jqery吗?你还在纠结是否要自己写一套还是去网上寻找成现成的UI组件吗?YouA为你轻松解决所有烦恼.YouA是我为移动前端 ...
- Lind.DDD.LindAspects方法拦截的介绍
回到目录 什么是LindAspects 之前写了关于Aspects的文章<Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP>,今天主要在设计思想上进 ...
- iOS开发 适配iOS10
2016年9月7日,苹果发布iOS 10.2016年9月14日,全新的操作系统iOS 10将正式上线. 作为开发者,如何适配iOS10呢? 1.Notification(通知) 自从Notificat ...
- 为什么很多SaaS企业级产品都熬不过第一年
因工作缘由,笔者与周边数位SaaS企业级应用的创始人.运营负责人有过深入接触,发现一个有趣的现象:刚起步时,蓝图远志.规划清晰,但是一路下来,却异常艰难,有些甚至熬不过第一年,就关门歇业. 2015年 ...
- 【开源】专业K线绘制[K线主副图、趋势图、成交量、滚动、放大缩小、MACD、KDJ等)
这是一个iOS项目雅黑深邃的K线的绘制. 实现功能包括K线主副图.趋势图.成交量.滚动.放大缩小.MACD.KDJ,长按显示辅助线等功能 预览图 最后的最后,这是项目的开源地址:https://git ...
- 和我一起看API(一)你所不知道的LinearLayout补充
楼主英语水平差,翻译的不好的话请多多指正,嘿嘿... A Layout that arranges its children in a single column or a single row. T ...