MySQL运维中经常会解析binlog文件,来查看MySQL做了什么操作。
简单场景,一个研发同学执行了delete from table where XXX and XX。这时候需要dba同学来找回数据。此处找回我们就需要解析mysql binlog看看到底删除了什么,或者更新了什么。
mysql 日志格式 ROW模式,建议生产都用ROW
解析工具:MySQLbinlog binlog2sql(美团开源工具,非常建议使用)
mysql版本:8.0.19
一、mysqlbinlog解析文件
解析之前需要查看binlog 格式,默认情况下建议生产环境全部采用ROW格式
通过参数 binlog_format 参数的值,可以设置 binlog 的格式,可选值有 statement、row、mixed
statement 格式:记录数据库执行的原始 SQL 语句
row 格式:记录具体的行的修改,这个为目前默认值
mixed 格式:因为上边两种格式各有优缺点,所以就出现了 mixed 格式
二、mysqlbinlog语法解析
需要注意的是
# mysqlbinlog 的执行格式
mysqlbinlog [options] log_file ...
# 查看bin-log二进制文件(shell方式)
mysqlbinlog -v --base64-output=decode-rows /var/lib/mysql/master.000003
# 查看bin-log二进制文件(带查询条件)
mysqlbinlog -v --base64-output=decode-rows /var/lib/mysql/master.000003 \
--start-datetime="2019-03-01 00:00:00" \
--stop-datetime="2019-03-10 00:00:00" \
--start-position="5000" \
--stop-position="20000"
疑问点一:如何解析出和客户端执行一致的sql语句?答案是可以的
1.数据库开启binlog_rows_query_log_events=1参数
2.mysqlbinlog -vv参数 --base64-output=decode-rows 参数
--base64-output=decode-rows -vv 用这个参数解析binlog就可以看到sql了
3.sql试例
mysqlbinlog --no-defaults -vv --base64-output=DECODE-ROWS --skip-gtids -d demo binlog.000074 | grep -C 1 -i "Rows_query"
三、解析结果文件
四、解释
position: 位于文件中的位置,即第一行的(# at 200514),说明该事件记录从文件第200514 个字节开始
timestamp: 事件发生的时间戳,
server id: 服务器标识(1)
end_log_pos 表示下一个事件开始的位置(即当前事件的结束位置+1)
thread_id: 执行该事件的线程id
exec_time: 事件执行的花费时间
error_code: 错误码,0意味着没有发生错误
type:事件类型Query
五、binlog2sql解析(强烈建议采用binlog2sql)
1.安装binlog2sql
wget <a href="https://codeload.github.com/danfengcao/binlog2sql/zip/master" /h">https://codeload.github.com/danfengcao/binlog2sql/zip/master
cd binlog2sql
pip install -r requirements.txt
注意安装提示:
安装时报错ModuleNotFoundError: No module named 'pymysqlreplication'
解决:pip install mysql-replication
2.解析binlog
重要参数解析:
解析模式
--stop-never 持续解析binlog。可选。,默认False,同步至执行命令时最新的binlog位置。
-K, --no-primary-key 对INSERT语句去除主键。可选。默认False
-B, --flashback 生成回滚SQL,可解析大文件,不受内存限制。可选。默认False。与stop-never或no-primary-key不能同时添加。(删库之后利器)
--back-interval -B模式下,每打印一千行回滚SQL,加一句SLEEP多少秒,如不想加SLEEP,请设为0。可选。默认1.0。
解析范围控制
--start-file 起始解析文件,只需文件名,无需全路径 。必须。
--start-position/--start-pos 起始解析位置。可选。默认为start-file的起始位置。
--stop-file/--end-file 终止解析文件。可选。默认为start-file同一个文件。若解析模式为stop-never,此选项失效。
--stop-position/--end-pos 终止解析位置。可选。默认为stop-file的最末位置;若解析模式为stop-never,此选项失效。
--start-datetime 起始解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。
--stop-datetime 终止解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。
对象过滤
-d, --databases 只解析目标db的sql,多个库用空格隔开,如-d db1 db2。可选。默认为空。
-t, --tables 只解析目标table的sql,多张表用空格隔开,如-t tbl1 tbl2。可选。默认为空。
--only-dml 只解析dml,忽略ddl。可选。默认False。
--sql-type 只解析指定类型,支持INSERT, UPDATE, DELETE。多个类型用空格隔开,如--sql-type INSERT DELETE。可选。默认为增删改都解析。用了此参数但没填任何类型,则三者都不解析。
解析示例:
python2.7 binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uroot -p'[email protected]' -ddemo -tt_name --start-file='binlog.000074'
解析结果:
解析为反向语句 -B参数
python2.7 binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uroot -p'[email protected]' -B -ddemo -tt_name --start-file='binlog.000074'