栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

binlog解析技巧

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

binlog解析技巧

  1. 尽可能在从库解析,避免对主库造成影响
  2. 先粗略定位涉及相关的库表操作的 binlog,再单独解析对应的 binlog 中的数据
  3. 在解析 DDL 时无需加 -v 输出详细信息(加快解析速度)
  4. 如果开启了 binlog_rows_query_log_events 参数,需要用 -vv 参数才可显示具体的 SQL 语句
常用命令 1. 解析 binlog 排查问题

如果只是解析出来查看,可以加 --base64-output=decode-rows 不显示行格式的内容:

mysqlbinlog --no-defaults -vv --base64-output=decode-rows mysql-bin.000008
2. 解析指定 GTID 的事务

用来分析某个事务做了什么:

mysqlbinlog --no-defaults -vv --base64-output=decode-rows --include-gtids='00008027-0000-0000-0000-000000008027:234932' mysql-bin.000008
3. 解析指定范围的 binlog a. 时间范围

–start-datetime、–stop-datetime 解析出指定时间范围内的 binlog,这个只适合粗略的解析,不精准,因此不要用来回放 binlog。有个小技巧:如果只能确定大概的时间范围,而且不确定在哪个 binlog 中,可以直接解析多个 binlog。比如大概在 15:20-16:20 内做了个表删除操作,但这个时间内有多个 binlog,可以这样:

mysqlbinlog --no-defaults -vv --base64-output=decode-rows --start-datetime='2022-04-11 15:20:00' --stop-datetime='2022-04-11 16:20:00' mysql-bin.000007 mysql-bin.000008
b. 偏移范围

–start-position、–stop-position 解析 binlog 指定偏移量范围内的 binlog。如果同时指定了 --start-position 和 --stop-position,并且是解析多个 binlog,则 --start-position 只对第一个 binlog 生效,–stop-position 只对最后一个 binlog 生效。

这个常用场景是:已经解析过一次 binlog 并取得目标事务的 起始 position 后,精确的解析这一段 binlog:

mysqlbinlog --no-defaults -vv --base64-output=decode-rows --start-position='1700' --stop-position='2049' mysql-bin.000008

# at 1700       --"start-position是 GTID event 前的这个 position"
...
...
SET @@SESSION.GTID_NEXT= '00008027-0000-0000-0000-000000008027:234933';
# at 1779
#220411 16:34:34 server id 8027  end_log_pos 1854 CRC32 0x8045a89d 	Query	thread_id=10	exec_time=0	error_code=0
SET TIMESTAMP=1649666074;
BEGIN
;
# at 1854
#220411 16:34:34 server id 8027  end_log_pos 1909 CRC32 0x95943ed8 	Rows_query
# delete from zhouwb where id = 6
# at 1909
#220411 16:34:34 server id 8027  end_log_pos 1969 CRC32 0xbc91d326 	Table_map: `test`.`zhouwb` mapped to number 88
# at 1969
#220411 16:34:34 server id 8027  end_log_pos 2018 CRC32 0x55ee80ec 	Delete_rows: table id 88 flags: STMT_END_F
### DELETE FROM `test`.`zhouwb`
### WHERe
###   @1=6 
###   @2='nanchang' 
# at 2018
#220411 16:34:34 server id 8027  end_log_pos 2049 CRC32 0x0e1be5af 	Xid = 21
COMMIT;
# at 2049       --"stop-position是 COMMIT event 后的这个 position"
c. GTID范围

–include-gtids、–exclude-gtids 详细看参数解释。

4 回放 binlog
  • 回放一定不能加 --base64-output=decode-rows 参数,因为不会解析出行格式(这是binlog真正有效的部分);
  • 回放也可以用上面指定范围的参数;
  • 解析 binlog 回放到本实例,不需要修改 server id,但要注意 GTID 是否已存在;
  • GTID 已经存在,回放不会报错,但也不会真正回放这些事务,可以通过 --skip-gtids 参数跳过 GTID 的限制;
mysqlbinlog --no-defaults --skip-gtids mysql-bin.000008 | mysql -uroot -p -S /tmp/mysql_sandbox8027.sock
参数解释 1. --no-defaults

可以避免 my.cnf 里配了 [client] 某些 mysqlbinlog 没有的参数导致 mysqlbinlog 失败

2. -v 不加,只显示行格式(即那一串字符串),无法得到伪 SQL :
BEGIN
;
# at 2203
# at 2283
#220411 16:35:16 server id 8027  end_log_pos 2343 CRC32 0xdd9758d2 	Table_map: `test`.`zhouwb` mapped to number 88
# at 2343
#220411 16:35:16 server id 8027  end_log_pos 2405 CRC32 0xd3f30671 	Write_rows: table id 88 flags: STMT_END_F

BINLOG '
ROhTYhNbHwAAPAAAACcJAAAAAFgAAAAAAAEABHRlc3QABnpob3V3YgACAw8CUAACAQEAAgP8/wDS
WJfd
ROhTYh5bHwAAPgAAAGUJAAAAAFgAAAAAAAEAAgAC/wAGAAAAB2JlaWppbmcABwAAAAh0aWFuamlu
Z3EG89M=
';
# at 2405
#220411 16:35:16 server id 8027  end_log_pos 2436 CRC32 0xd8de314b 	Xid = 22
COMMIT;
加 -v,从行格式中重建伪SQL(带注释),不显示 binlog_rows_query_log_events 参数效果:
BEGIN
;
# at 2203
# at 2283
#220411 16:35:16 server id 8027  end_log_pos 2343 CRC32 0xdd9758d2 	Table_map: `test`.`zhouwb` mapped to number 88
# at 2343
#220411 16:35:16 server id 8027  end_log_pos 2405 CRC32 0xd3f30671 	Write_rows: table id 88 flags: STMT_END_F

BINLOG '
ROhTYhNbHwAAPAAAACcJAAAAAFgAAAAAAAEABHRlc3QABnpob3V3YgACAw8CUAACAQEAAgP8/wDS
WJfd
ROhTYh5bHwAAPgAAAGUJAAAAAFgAAAAAAAEAAgAC/wAGAAAAB2JlaWppbmcABwAAAAh0aWFuamlu
Z3EG89M=
';
### INSERT INTO `test`.`zhouwb`
### SET
###   @1=6
###   @2='beijing'
### INSERT INTO `test`.`zhouwb`
### SET
###   @1=7
###   @2='tianjing'
# at 2405
#220411 16:35:16 server id 8027  end_log_pos 2436 CRC32 0xd8de314b 	Xid = 22
COMMIT;
加 -vv,从行格式中重建伪SQL并添加字段数据类型的注释,可以显示 binlog_rows_query_log_events 参数效果:
BEGIN
;
# at 2203
#220411 16:35:16 server id 8027  end_log_pos 2283 CRC32 0xd4ef1b64 	Rows_query
# insert into zhouwb values(6, 'beijing'), (7, 'tianjing')
# at 2283
#220411 16:35:16 server id 8027  end_log_pos 2343 CRC32 0xdd9758d2 	Table_map: `test`.`zhouwb` mapped to number 88
# at 2343
#220411 16:35:16 server id 8027  end_log_pos 2405 CRC32 0xd3f30671 	Write_rows: table id 88 flags: STMT_END_F

BINLOG '
ROhTYh1bHwAAUAAAAOsIAACAADhpbnNlcnQgaW50byB6aG91d2IgdmFsdWVzKDYsICdiZWlqaW5n
JyksICg3LCAndGlhbmppbmcnKWQb79Q=
ROhTYhNbHwAAPAAAACcJAAAAAFgAAAAAAAEABHRlc3QABnpob3V3YgACAw8CUAACAQEAAgP8/wDS
WJfd
ROhTYh5bHwAAPgAAAGUJAAAAAFgAAAAAAAEAAgAC/wAGAAAAB2JlaWppbmcABwAAAAh0aWFuamlu
Z3EG89M=
';
### INSERT INTO `test`.`zhouwb`
### SET
###   @1=6 
###   @2='beijing' 
### INSERT INTO `test`.`zhouwb`
### SET
###   @1=7 
###   @2='tianjing' 
# at 2405
#220411 16:35:16 server id 8027  end_log_pos 2436 CRC32 0xd8de314b 	Xid = 22
COMMIT;
3. 加 --base64-output=decode-rows

不显示行格式,如果同时加 -v 参数,可以从行格式中解码为带注释的伪SQL:

BEGIN
;
# at 2203
#220411 16:35:16 server id 8027  end_log_pos 2283 CRC32 0xd4ef1b64 	Rows_query
# insert into zhouwb values(6, 'beijing'), (7, 'tianjing')
# at 2283
#220411 16:35:16 server id 8027  end_log_pos 2343 CRC32 0xdd9758d2 	Table_map: `test`.`zhouwb` mapped to number 88
# at 2343
#220411 16:35:16 server id 8027  end_log_pos 2405 CRC32 0xd3f30671 	Write_rows: table id 88 flags: STMT_END_F
### INSERT INTO `test`.`zhouwb`
### SET
###   @1=6 
###   @2='beijing' 
### INSERT INTO `test`.`zhouwb`
### SET
###   @1=7 
###   @2='tianjing' 
# at 2405
#220411 16:35:16 server id 8027  end_log_pos 2436 CRC32 0xd8de314b 	Xid = 22
COMMIT;
4. --skip-gtids

不保留 GTID 事件信息,这样回放 binlog 时会跟执行新事务一样,生成新的 GTID。对比如下:

## 带 --skip-gtids
[root@easydb data]# /root/opt/mysql/8.0.27/bin/mysqlbinlog --no-defaults -vv --base64-output=decode-rows --skip-gtids  mysql-bin.000008 | grep GTID
;

## 不带 --skip-gtids,可以看到 GTID event
[root@easydb data]# /root/opt/mysql/8.0.27/bin/mysqlbinlog --no-defaults -vv --base64-output=decode-rows  mysql-bin.000008 | grep GTID
#220411 15:40:09 server id 8027  end_log_pos 196 CRC32 0x3322bc7b 	Previous-GTIDs
#220411 15:46:17 server id 8027  end_log_pos 275 CRC32 0xa846d089 	GTID	last_committed=0	sequence_number=1	rbr_only=yes	original_committed_timestamp=1649663177532042	immediate_commit_timestamp=1649663177532042	transaction_length=348
SET @@SESSION.GTID_NEXT= '00008027-0000-0000-0000-000000008027:234929';
–include-gtids 只解析出指定的 GTID 的事务:
[root@easydb data]# /root/opt/mysql/8.0.27/bin/mysqlbinlog --no-defaults -vv --base64-output=decode-rows --include-gtids='00008027-0000-0000-0000-000000008027:234930-234932'  mysql-bin.000008 | grep GTID
#220411 15:40:09 server id 8027  end_log_pos 196 CRC32 0x3322bc7b 	Previous-GTIDs
#220411 15:46:52 server id 8027  end_log_pos 623 CRC32 0x88a5ac62 	GTID	last_committed=1	sequence_number=2	rbr_only=yes	original_committed_timestamp=1649663212297057	immediate_commit_timestamp=1649663212297057	transaction_length=350
SET @@SESSION.GTID_NEXT= '00008027-0000-0000-0000-000000008027:234930';
#220411 15:47:36 server id 8027  end_log_pos 973 CRC32 0x1c67959b 	GTID	last_committed=2	sequence_number=3	rbr_only=yes	original_committed_timestamp=1649663256370735	immediate_commit_timestamp=1649663256370735	transaction_length=384
SET @@SESSION.GTID_NEXT= '00008027-0000-0000-0000-000000008027:234931';
#220411 15:51:04 server id 8027  end_log_pos 1357 CRC32 0x96a24670 	GTID	last_committed=3	sequence_number=4	rbr_only=yes	original_committed_timestamp=1649663464924883	immediate_commit_timestamp=1649663464924883	transaction_length=422
SET @@SESSION.GTID_NEXT= '00008027-0000-0000-0000-000000008027:234932';
SET @@SESSION.GTID_NEXT= 'AUTOMATIC'  ;
不解析指定的 GTID 的事务 --exclude-gtids 利用 Linux 的管道命令解析

个人常用的 Linux 下解析命令:

/root/opt/mysql/8.0.27/bin/mysqlbinlog --no-defaults -vv --base64-output=decode-rows --database test --skip-gtids=true mysql-bin.000008 | grep -C 1 -i "delete from zhouwb" > /tmp/delete.log
  • no-defaults:避免 my.cnf 里配了 [client] 某些 mysqlbinlog 没有的参数导致 mysqlbinlog 失败。
  • base64-output=decode-rows -vv:显示具体 SQL 语句。
  • database:只列出该数据库下的行数据,但无法过滤 Rows_query_event。
  • skip-gtids=true:忽略 GTID 显示。
  • mysql-bin.000008:需要解析的 binlog 日志。
  • grep -C 1 -i “delete from zhouwb”:通过管道命令筛选出所需 SQL 及执行时间。
  • /tmp/delete.log:将结果导入到日志文件,方便查看。

效果展示:

[root@easydb data]# /root/opt/mysql/8.0.27/bin/mysqlbinlog --no-defaults -vv --base64-output=decode-rows --database test --skip-gtids=true mysql-bin.000008 | grep -C 1 -i "delete from zhouwb"
#220411 16:34:34 server id 8027  end_log_pos 1909 CRC32 0x95943ed8 	Rows_query
# delete from zhouwb where id = 6
# at 1909
因为有悔,所以披星戴月;因为有梦,所以奋不顾身! 个人博客首发:easydb.net 微信公众号:easydb 关注我,不走丢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1008317.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号