mysqlbinlog 怎样解析出正常的sql语句?

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'

图片



猜你喜欢

转载自blog.51cto.com/15060546/2650695