在 MySQL 日常维护中,要回滚或者恢复数据,我们经常会用 binlog 来在数据库上重放,执行类似下面的语句:

    最近遇到了这样一个问题,在重放 binlog 时,mysqld 报这样的错

      分析

      上面的错是说语法不对,难道是 binlog 写错了,为了方便查看,先把 mysqlbinlog 解析结果保存到一个文件

      1. mysqlbinlog mysql-bin.000001 > abc.sql

      然后打开 abc.sql 文件,会看到这样的语句

      为啥后面会多 1 个 0 呢,后来发现是用户在用 MySQL C API 时用错了,具体是这个函数 mysql_real_query,基原型是

        详细说明参考,length 参数表示 stmt_str 的长度,所以正常的调用应该是这样的:

        1. mysq_real_query(mysql, sql, strlen(sql))

        可是用户在使用时多加了个1,变成这样

        最终导致记录的 binlog 后面多了个 ‘\0’。 这个问题只在 statement 格式有,row 格式没有。

        解决方法

        1. 5.6 版本加参数

          如果是用 5.6 版本的 mysql client 的话,在重放时出错提示信息不一样,是类似下面这样的,更加友好,这个错误是 mysql client 报的,不是mysqld报的:

            5.6 版本的 mysql client 多了一个参数 –binary-mode,允许语句里有 ‘\0’,所以如果是用5.6的话,就可以不用修改代码,重放binlog时这样做就可以了:

            1. mysqlbinlog mysql-bin.000001 | mysql --binary-mode -hxxxx -Pxx -u