MySQL 解密 --> 如何查看二进制日志ROW模式下最原始的SQL语句
MySQL的binlog的ROW模式解析
在mysql5.6以后,对主从数据一致性要求变高了,statement格式逐渐不太适合业务的需求了,所以生产环境大家都采用了row模式,row模式是传输最底层的数据变化的insert的模块来进行主从数据的传输,那么在binlog里面就和普通的statement模式有何差别?能否看到最原始的sql语句呢?
1、准备录入数据
mysql> create table test1(id int,c1 varchar(20),type int,address varchar(20),create_time datetime); Query OK, 0 rows affected (0.00 sec) mysql> insert into test1 select 1,'zhangsan','1','zhangsan road No 870,floor 602',now(); ERROR 1406 (22001): Data too long for column 'address' at row 1 mysql> mysql> show create table test1; +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | test1 | CREATE TABLE `test1` ( `id` int(11) DEFAULT NULL, `c1` varchar(20) DEFAULT NULL, `type` int(11) DEFAULT NULL, `address` varchar(20) DEFAULT NULL, `create_time` datetime DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> alter table test1 modify `address` varchar(200) DEFAULT NULL; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> insert into test1 select 1,'zhangsan','1','zhangsan road No 870,floor 602',now(); Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> insert into test1 select 2,'lisi','1','zhangsan road No 870,floor 602',now(); Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> 登录后复制
|
2、Row模式binlog是乱码
Row模式下面,binlog里面的ddl语句是正常显示的,但是dml是乱码,如下所示:
[root@hch_test_dbm1_121_63 binlog]# /usr/local/mysql/bin/mysqlbinlog mysql-bin.000215 …… # 这里前面的省略 #160722 17:02:38 server id 62 end_log_pos 4291 CRC32 0x369e3244 Query thread_id=60 exec_time=4294967271 error_code=0 SET TIMESTAMP=1469178158/*!*/; CREATE DATABASE IF NOT EXISTS `percona` /* pt-table-checksum */ /*!*/; # at 4291 #160722 17:02:38 server id 62 end_log_pos 5079 CRC32 0x8abc6e67 Query thread_id=60 exec_time=4294967271 error_code=0 use `percona`/*!*/; SET TIMESTAMP=1469178158/*!*/; CREATE TABLE IF NOT EXISTS `percona`.`checksums` ( db char(64) NOT NULL, tbl char(64) NOT NULL, chunk int NOT NULL, chunk_time float NULL, chunk_index varchar(200) NULL, lower_boundary text NULL, upper_boundary text NULL, this_crc char(40) NOT NULL, this_cnt int NOT NULL, master_crc char(40) NULL, master_cnt int NULL, ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (db, tbl, chunk), INDEX ts_db_tbl (ts, db, tbl) ) ENGINE=InnoDB /*!*/; # at 5079 #160820 10:21:10 server id 63 end_log_pos 5280 CRC32 0xd147bd8e Query thread_id=16 exec_time=0 error_code=0 SET TIMESTAMP=1471659670/*!*/; SET @@session.sql_mode=1075838976/*!*/; GRANT ALL PRIVILEGES ON *.* TO 'tim'@'192.168%' IDENTIFIED BY PASSWORD '*2976819BD2CCD13612E03F812A2CD297C1A18B23' /*!*/; # at 5280 #160820 10:22:40 server id 63 end_log_pos 5445 CRC32 0x85811be7 Query thread_id=18 exec_time=0 error_code=0 use `test`/*!*/; SET TIMESTAMP=1471659760/*!*/; create table test1(id int,c1 varchar(20),type int,address varchar(20),create_time datetime) /*!*/; # at 5445 #160820 10:24:34 server id 63 end_log_pos 5580 CRC32 0x2626220c Query thread_id=18 exec_time=0 error_code=0 SET TIMESTAMP=1471659874/*!*/; alter table test1 modify `address` varchar(200) DEFAULT NULL /*!*/; # at 5580 #160820 10:24:36 server id 63 end_log_pos 5660 CRC32 0x7b7c645f Query thread_id=18 exec_time=0 error_code=0 SET TIMESTAMP=1471659876/*!*/; SET @@session.time_zone='SYSTEM'/*!*/; BEGIN /*!*/; # at 5660 # at 5764 #160820 10:24:36 server id 63 end_log_pos 5821 CRC32 0x08bc94c3 Table_map: `test`.`test1` mapped to number 74 # at 5821 #160820 10:24:36 server id 63 end_log_pos 5911 CRC32 0x2f577f52 Write_rows: table id 74 flags: STMT_END_F
BINLOG ' ZL+3VxM/AAAAOQAAAL0WAAAAAEoAAAAAAAEABHRlc3QABXRlc3QxAAUDDwMPEgU8AFgCAB/DlLwI ZL+3Vx4/AAAAWgAAABcXAAAAAEoAAAAAAAEAAgAF/+ABAAAACHpoYW5nc2FuAQAAAB4Aemhhbmdz YW4gcm9hZCBObyA4NzAsZmxvb3IgNjAymZoopiRSf1cv '/*!*/; # at 5911 #160820 10:24:36 server id 63 end_log_pos 5942 CRC32 0xb26af81b Xid = 199 COMMIT/*!*/; # at 5942 #160820 10:24:48 server id 63 end_log_pos 6022 CRC32 0x09eab31d Query thread_id=18 exec_time=0 error_code=0 SET TIMESTAMP=1471659888/*!*/; BEGIN /*!*/; # at 6022 # at 6122 #160820 10:24:48 server id 63 end_log_pos 6179 CRC32 0xdc6dc34b Table_map: `test`.`test1` mapped to number 74 # at 6179 #160820 10:24:48 server id 63 end_log_pos 6265 CRC32 0x5f7ad700 Write_rows: table id 74 flags: STMT_END_F
BINLOG ' cL+3VxM/AAAAOQAAACMYAAAAAEoAAAAAAAEABHRlc3QABXRlc3QxAAUDDwMPEgU8AFgCAB9Lw23c cL+3Vx4/AAAAVgAAAHkYAAAAAEoAAAAAAAEAAgAF/+ACAAAABGxpc2kBAAAAHgB6aGFuZ3NhbiBy b2FkIE5vIDg3MCxmbG9vciA2MDKZmiimMADXel8= '/*!*/; # at 6265 #160820 10:24:48 server id 63 end_log_pos 6296 CRC32 0xf6833d28 Xid = 200 COMMIT/*!*/; # at 6296 #160820 10:31:30 server id 63 end_log_pos 6343 CRC32 0xcfcdd344 Rotate to mysql-bin.000216 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; [root@hch_test_dbm1_121_63 binlog]# |
3、通过--base64-output=decode-rows -v来查看dml语句
执行命令是:/usr/local/mysql/bin/mysqlbinlog --base64-output=decode-rows -v mysql-bin.000215
可以看到如下效果,不过都是最原始的dml块sql语句:
[root@hch_test_dbm1_121_63 binlog]# /usr/local/mysql/bin/mysqlbinlog --base64-output=decode-rows -v mysql-bin.000215 /*!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 /*!*/; …… #160820 10:24:36 server id 63 end_log_pos 5821 CRC32 0x08bc94c3 Table_map: `test`.`test1` mapped to number 74 # at 5821 #160820 10:24:36 server id 63 end_log_pos 5911 CRC32 0x2f577f52 Write_rows: table id 74 flags: STMT_END_F ### INSERT INTO `test`.`test1` ### SET ### @1=1 ### @2='zhangsan' ### @3=1 ### @4='zhangsan road No 870,floor 602' ### @5='2016-08-20 10:24:36' # at 5911 #160820 10:24:36 server id 63 end_log_pos 5942 CRC32 0xb26af81b Xid = 199 COMMIT/*!*/; # at 5942 #160820 10:24:48 server id 63 end_log_pos 6022 CRC32 0x09eab31d Query thread_id=18 exec_time=0 error_code=0 SET TIMESTAMP=1471659888/*!*/; BEGIN /*!*/; # at 6022 # at 6122 #160820 10:24:48 server id 63 end_log_pos 6179 CRC32 0xdc6dc34b Table_map: `test`.`test1` mapped to number 74 # at 6179 #160820 10:24:48 server id 63 end_log_pos 6265 CRC32 0x5f7ad700 Write_rows: table id 74 flags: STMT_END_F ### INSERT INTO `test`.`test1` ### SET ### @1=2 ### @2='lisi' ### @3=1 ### @4='zhangsan road No 870,floor 602' ### @5='2016-08-20 10:24:48' # at 6265 #160820 10:24:48 server id 63 end_log_pos 6296 CRC32 0xf6833d28 Xid = 200 COMMIT/*!*/; # at 6296 #160820 10:31:30 server id 63 end_log_pos 6343 CRC32 0xcfcdd344 Rotate to mysql-bin.000216 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; [root@hch_test_dbm1_121_63 binlog]# |
PS:这样是可以看到了dml的insert语句,但是只看到了最终的insert块,而看不到原始的过来的insert语句,很多时候排查问题需要原始的insert语句而不是底层的insert块。所以问题来了,如何看到最原始的insert sql语句呢?
4、通过binlog_rows_query_log_events参数来查看最原始的insert sql
(4.1)先在线设置全局的binlog_rows_query_log_events参数,刷新日志:
mysql> set binlog_rows_query_log_events=1; Query OK, 0 rows affected (0.01 sec)
mysql> mysql> flush logs; Query OK, 0 rows affected (0.01 sec)
mysql>exit
|
(4.2)然后重新登录录入新的数据记录:
[root@hch_test_dbm1_121_63 ~]# mysql -utim -ptimgood -h192.168.121.63 Warning: Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 19 Server version: 5.6.12-log Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> mysql> use test; Database changed mysql> insert into test1 select 3,'wanger','3','zhangsan road No 870,floor 603',now(); Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0
mysql>
|
(4.3)解析binlog,没有看到原始的insert语句
[root@hch_test_dbm1_121_63 binlog]# /usr/local/mysql/bin/mysqlbinlog --base64-output=decode-rows -v mysql-bin.000216 >1.sql [root@hch_test_dbm1_121_63 binlog]# more 1.sql /*!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 4 #160820 10:31:30 server id 63 end_log_pos 120 CRC32 0x1e4d0366 Start: binlog v 4, server v 5.6.12-log created 160820 10:31:30 # Warning: this binlog is either in use or was not closed properly. # at 120 #160820 10:32:04 server id 63 end_log_pos 200 CRC32 0xab0e625e Query thread_id=19 exec_time=0 error_code=0 SET TIMESTAMP=1471660324/*!*/; SET @@session.pseudo_thread_id=19/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1075838976/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.time_zone='SYSTEM'/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 200 # at 302 #160820 10:32:04 server id 63 end_log_pos 359 CRC32 0x41bf2876 Table_map: `test`.`test1` mapped to number 74 # at 359 #160820 10:32:04 server id 63 end_log_pos 447 CRC32 0x1a3ab3d8 Write_rows: table id 74 flags: STMT_END_F ### INSERT INTO `test`.`test1` ### SET ### @1=3 ### @2='wanger' ### @3=3 ### @4='zhangsan road No 870,floor 603' ### @5='2016-08-20 10:32:04' # at 447 #160820 10:32:04 server id 63 end_log_pos 478 CRC32 0xc5081021 Xid = 208 COMMIT/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; [root@hch_test_dbm1_121_63 binlog]#
|
(4.4)通过mysql的命令行查看最原始的insert sql语句,如下所示:
mysql> show binlog events in 'mysql-bin.000216'; +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------+ | mysql-bin.000216 | 4 | Format_desc | 63 | 120 | Server ver: 5.6.12-log, Binlog ver: 4 | | mysql-bin.000216 | 120 | Query | 63 | 200 | BEGIN || mysql-bin.000216 | 200 | Rows_query | 63 | 302 | # insert into test1 select 3,'wanger','3','zhangsan road No 870,floor 603',now() || mysql-bin.000216 | 302 | Table_map | 63 | 359 | table_id: 74 (test.test1) | | mysql-bin.000216 | 359 | Write_rows | 63 | 447 | table_id: 74 flags: STMT_END_F | | mysql-bin.000216 | 447 | Xid | 63 | 478 | COMMIT /* xid=208 */ | +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------+ 6 rows in set (0.00 sec) mysql> 登录后复制 |
5、试验总结
基于以上的试验,可以得出在row模式下,可以通过mysqlbinlog --base64-output=decode-rows –v查看最底层的insert数据模块,也可以通过命令行show binlog events in 'mysql-bin.000216';来实时查看最原始的insertsql记录。
我们可以在搭建数据库的时候,在启动参数文件my.cnf里面事先设置好,如下所示:
# vim my.cnf [mysqld] binlog_format=row # binlog 日志格式 binlog_rows_query_log_events = 1 # 将原始的操作sql记录写入事件中 |
以上就是MySQL 解密 --> 如何查看二进制日志ROW模式下最原始的SQL语句的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

MySQL在数据库和编程中的地位非常重要,它是一个开源的关系型数据库管理系统,广泛应用于各种应用场景。1)MySQL提供高效的数据存储、组织和检索功能,支持Web、移动和企业级系统。2)它使用客户端-服务器架构,支持多种存储引擎和索引优化。3)基本用法包括创建表和插入数据,高级用法涉及多表JOIN和复杂查询。4)常见问题如SQL语法错误和性能问题可以通过EXPLAIN命令和慢查询日志调试。5)性能优化方法包括合理使用索引、优化查询和使用缓存,最佳实践包括使用事务和PreparedStatemen

选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

Apache 连接数据库需要以下步骤:安装数据库驱动程序。配置 web.xml 文件以创建连接池。创建 JDBC 数据源,指定连接设置。从 Java 代码中使用 JDBC API 访问数据库,包括获取连接、创建语句、绑定参数、执行查询或更新以及处理结果。

在 Docker 中启动 MySQL 的过程包含以下步骤:拉取 MySQL 镜像创建并启动容器,设置根用户密码并映射端口验证连接创建数据库和用户授予对数据库的所有权限

MySQL在Web应用中的主要作用是存储和管理数据。1.MySQL高效处理用户信息、产品目录和交易记录等数据。2.通过SQL查询,开发者能从数据库提取信息生成动态内容。3.MySQL基于客户端-服务器模型工作,确保查询速度可接受。

在 CentOS 上安装 MySQL 涉及以下步骤:添加合适的 MySQL yum 源。执行 yum install mysql-server 命令以安装 MySQL 服务器。使用 mysql_secure_installation 命令进行安全设置,例如设置 root 用户密码。根据需要自定义 MySQL 配置文件。调整 MySQL 参数和优化数据库以提升性能。

Laravel 是一款 PHP 框架,用于轻松构建 Web 应用程序。它提供一系列强大的功能,包括:安装: 使用 Composer 全局安装 Laravel CLI,并在项目目录中创建应用程序。路由: 在 routes/web.php 中定义 URL 和处理函数之间的关系。视图: 在 resources/views 中创建视图以呈现应用程序的界面。数据库集成: 提供与 MySQL 等数据库的开箱即用集成,并使用迁移来创建和修改表。模型和控制器: 模型表示数据库实体,控制器处理 HTTP 请求。
