问题描述:
同事使用mysqlbinlog工具的--read-from-remote-server --raw选项,从远程实例实时拉取二进制日志时,发现得到的二进制日志文件大小与远程实例上的源文件大小不相同,并且使用mysqlbinlog解析时会报错。
测试环境版本信息如下:
MySQL版本:5.7.17 log MySQL Community Server (GPL) 通用tar包安装
Mysqlbinlog版本:5.7.17 自带版本,mysqlbinlog Ver 3.4 for linux-glibc2.5 at x86_64
操作系统版本:CentOS Linux release 7.6.1810 (Core)
分析过程:
1、对比拉取到的二进制日志文件、源文件的大小,发现拉取到的二进制日志文件比源文件小,并且该文件大小:7315456/4096,刚好可以整除,源库上进行多次更新后,多次观察,发现该数值都可以被4096整除。
因为Linux块大小是4096 Bytes,所以,我先做个假设:mysqlbinlog工具以4096字节为单位进行写入
[root@192_168_129_128 tmp]# ll /usr/local/mysql-5.7.17-linux-glibc2.5-x86_64/data/mybinlog.000006 ; ll mybinlog.000006 -rw-r----- 1 mysql mysql 7318723 May 12 16:55 /usr/local/mysql-5.7.17-linux-glibc2.5-x86_64/data/mybinlog.000006 -rw-r----- 1 root root 7315456 May 12 16:55 mybinlog.000006
2、我在8.0.19版本中测试,问题却不能复现。
3、写一个简单的shell脚本,将mysqlbinlog拉取进程放到后台执行,获取到上一步的pid之后,使用pstack命令和strace命令,分别查看该进程的函数调用和系统调用
#!/bin/bash nohup mysqlbinlog --read-from-remote-server --host=192.168.129.128 --user=dba --password=123456 --raw --to-last-log binlog.000002 --stop-never & pid=`ps -ef | grep mysqlbinlog | grep -v 'grep' | awk '{print $2}'` pstack $pid > pstack.log strace -f -t -p $pid -o strace.log
pstack命令的输出结果如下,虽然没有直接的线索,但是后续可以利用这些函数栈名,去源码中找线索:
#0 0x00007faf58f60a2d in recv () from /lib64/libpthread.so.0 #1 0x000000000045e9f9 in inline_mysql_socket_recv (flags=0, n=5826, buf=0x1d959d1, mysql_socket=..., src_line=123, src_file=0x550918 "/export/home/pb2/build/sb_0-21378219-1480347226.17/mysql-5.7.17/vio/viosocket.c") at /export/home/pb2/build/sb_0-21378219-1480347226.17/mysql-5.7.17/include/mysql/psi/mysql_socket.h:823 #2 vio_read (vio=0x1d90e60, buf=0x1d959d1 "27399199-10542799900-96491182343-85303866742-80196460272-89060617578-51177070778-10421134155;80308169113-21291571753-18876715410-91134905277-85771492482360j 03", size=5826) at /export/home/pb2/build/sb_0-21378219-1480347226.17/mysql-5.7.17/vio/viosocket.c:123 #3 0x0000000000434873 in net_read_raw_loop (count=5826, net=0x1d8e550) at /export/home/pb2/build/sb_0-21378219-1480347226.17/mysql-5.7.17/sql/net_serv.cc:672 #4 net_read_packet (net=0x1d8e550, complen=0x7fff6d023f88) at /export/home/pb2/build/sb_0-21378219-1480347226.17/mysql-5.7.17/sql/net_serv.cc:859 #5 0x0000000000434a7c in my_net_read (net=0x1d8e550) at /export/home/pb2/build/sb_0-21378219-1480347226.17/mysql-5.7.17/sql/net_serv.cc:899 #6 0x000000000043985b in cli_safe_read_with_ok (mysql=0x1d8e550, parse_ok=0 '