很多时候,当我们的业务数据产生了不正常的变化,但却无法得知这类操作是在哪里进行,并且如何进行,单单从程序当面排查很费力。那么就需要通过分析数据库日志来得到历史执行SQL,根据SQL执行逻辑来确认代码位置,进而确认是否是BUG,亦或是误操作等。
一. BinLog简介
BinLog 是MySQL Server层记录的二进制日志文件,用于记录MySQL的数据更新或者潜在更新(比如DELETE语句执行删除而实际并没有符合条件的数据),select或show等不会修改数据的操作不会记录在binlog中。
BinLog文件是我们得到历史执行SQL的基础,但是仅仅只能得到历史的DML&DDL操作,而不能得到查询操作。
二. mysqlbinlog 工具
由于BinLog是二进制文件,所以无法直接使用文本打开。所以需要通过mysqlbinlog解析二进制文件后才可读。
由于windows下面无法使用管道命令如此简洁的提取出SQL,所以这边就只写Linux下的使用方法。我平时的做法会将windows下面的binlog拷贝到Linux下,再利用Linux的管道命令解析。
Linux下常见使用命令:
mysqlbinlog /data/mysql_data/bin.000008 --database test --base64-output=decode-rows -vv --skip-gtids=true |grep -C 2 -i "delete from Audit_Orga_Specialtype" > /opt/sql.log
/data/mysql_data/bin.000008:需要解析的binlog日志。
database :只列出该数据库的SQL。
base64-output=decode-rows -vv :显示具体SQL语句。
skip-gtids=true :忽略GTID相关显示。
grep -C 2 -i "delete from Audit_Orga_Specialtype" :通过管道命令筛选出所需SQL及执行时间。
/opt/sql.log :将结果导入到日志文件,方便查看。
结果示例:
三. 解析方式对比
对于常见的数据库(SQL Server 、Oracle 、MySQL)来说,都具有类似相同的日志来记录历史SQL,不同的只是日志的记录方式和解析方法:
| 数据库 | SQL日志| 常见解析方式|优点|缺点|
| :-------- | --------😐 :------: | :------: |
| SQL Server| LDF文件&日志备份| ApexLog|图形化工具、操作简单,可以自由筛选时间、表对象及对应操作|无法得到当时实际执行的SQL,只有具体的行数据及操作类型。
| Oracle| 在线日志&归档日志 | LogMiner|可以得到当时实际运行SQL及对应账号、客户端IP|步骤比较复杂,需要一个一个添加归档日志。
| MySQL| BinLog&RelayLog | mysqlbinlog|可以得到当时实际运行SQL及运行时间|无法知道运行账号及客户端IP,如果binlog日志较多,需要解析多次。