MySQL内核月报 2014.10-MySQL· 捉虫动态·binlog重放失败

本文涉及的产品
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

背景

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

mysqlbinlog mysql-bin.000001 | mysql -hxxxx -Pxx -u

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

ERROR 1064 (42000) at line 25: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER ;


分析

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

mysqlbinlog mysql-bin.000001 > abc.sql

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

"CREATE TABLE t_binlog_sbr(a int)^@"

最后面的奇怪的 "^@" 这是啥呢,我们用二进制方式打开文件后,发现这个其实是1个字节,值是 00,被显示成 "^@"了。

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

int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned long length)

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

mysq_real_query(mysql, sql, strlen(sql))

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

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

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


解决方法

有同学会问,+1 可以,+2、 +3 呢,这个是不可以的,>=2 的都是不行的,语句发过来后,mysqld 在 parse_sql 阶段直接报错返回了,后面就不会执行了。

1) 修改代码

mysq_real_query(mysql, sql, strlen(sql) + 1) 这种用法是不对的,但是 MySQL 却允许,虽然这么用是不对的,但是为了兼容性,最好还是允许这种使用方式,但是在写binlog的时候做个判断,长度是不是写错了,错了的话纠正过来,在 THD::binlog_query 里面改。


2) 5.6 版本加参数

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

ERROR at line 24: ASCII '\0' appeared in the statement, but this is not allowed unless option --binary-mode is enabled and mysql is run in non-interactive mode. Set --binary-mode to 1 if ASCII '\0' is expected....

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

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


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
canal 消息中间件 关系型数据库
Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
【9月更文挑战第1天】Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
485 4
|
3月前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
286 2
|
3月前
|
SQL 关系型数据库 MySQL
【MySQL】根据binlog日志获取回滚sql的一个开发思路
【MySQL】根据binlog日志获取回滚sql的一个开发思路
|
2月前
|
消息中间件 canal 关系型数据库
Maxwell:binlog 解析器,轻松同步 MySQL 数据
Maxwell:binlog 解析器,轻松同步 MySQL 数据
209 11
|
9天前
|
存储 关系型数据库 MySQL
MySQL中的Redo Log、Undo Log和Binlog:深入解析
【10月更文挑战第21天】在数据库管理系统中,日志是保障数据一致性和完整性的关键机制。MySQL作为一种广泛使用的关系型数据库管理系统,提供了多种日志类型来满足不同的需求。本文将详细介绍MySQL中的Redo Log、Undo Log和Binlog,从背景、业务场景、功能、底层实现原理、使用措施等方面进行详细分析,并通过Java代码示例展示如何与这些日志进行交互。
12 0
|
3月前
|
关系型数据库 MySQL Shell
MySQL回滚脚本: 误操作delete binlog回滚shell脚本
MySQL回滚脚本: 误操作delete binlog回滚shell脚本
|
3月前
|
关系型数据库 MySQL 数据库
MySQL回滚工具:binlog 闪回工具 MyFlash工具
MySQL回滚工具:binlog 闪回工具 MyFlash工具
|
3月前
|
监控 关系型数据库 MySQL
MySQL如何快速获取binlog的开始时间和结束时间
【8月更文挑战第17天】在MySQL中快速获取binlog的开始与结束时间可通过多种途径:1) 使用`mysqlbinlog`结合`head`和`tail`命令查看单个或多个binlog文件的时间范围;2) 查询`information_schema.binlog_events`表获取近似的开始与结束时间戳;3) 利用第三方工具如Percona Toolkit的`pt-mysql-summary`获取binlog信息。选择适当方法前应考虑操作环境及数据安全性。
300 2
|
3月前
|
数据采集 关系型数据库 MySQL
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
37 1
|
4月前
|
关系型数据库 MySQL Java

相关产品

  • 云数据库 RDS MySQL 版