MySQL内核月报 2015.02-MySQL · 捉虫动态· 变量修改导致binlog错误

简介:

背景

MySQL 5.6.6 版本新加了这样一个参数——log_bin_use_v1_row_events,这个参数用来控制binlog中Rows_log_event的格式,如果这个值为1的话,就用v1版的Rows_log_event格式(即5.6.6之前的),默认是0,用新的v2版本的格式,更详细看官方文档。这个参数一般保持默认即可,但是当我们需要搭 5.6->5.5 这要的主备的时候,就需要把主库的这个值改为1,不然5.5的备库不能正确解析Rows_log_event。最近在使用这个参数的时候发现了一个bug,导致主库binlog写坏,备库复制中断,报错如下:

Last_SQL_Errno: 1594 Last_SQL_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.

bug 分析

binlog event 结构

 

如上所示,每种binlog event 都可以分为header 和 body 2部分,body 又可以分为 fixed part 和 variable part,其中event header的长度相同并且固定,5.0开始用的v4格式的binlog,其event header固定长度为19字节,包含多个字段,具体每个字段的含义可以看这里。 event body 中post header 长度也是固定的,所以叫 fixed part,但是不同类型event这一部分的长度不一样,最后的 variable part 就是event的主体了,这个就长度不一了。 log_bin_use_v1_row_events 这个值的不同,影响的部分就是 postheader 这里的长度,如果值为1的话,用v1格式,postheader 长度是8个字节,如果是0,用v2格式,其长度为10。每个Rows_log_event的event header的type字节会标明当前event是v1还是v2,试想一下,如果event header部分标明是v2,postheader却实际上只有8个字节,或者反过来,event header部分标明是v1,postheader有10个字节,备库拿到这样的binlog,去尝试解析的时候,就完全凌乱了。

为啥会出现这种一个event前后不一致的情况呢,代码编写不严谨!

在写 Rows_log_event(Write/Update/Delete) 过程中,有2次用到 log_bin_use_v1_row_events 这个全局变量,一次是在构造函数处,一次是在写postheader时 Rows_log_event::write_data_header(),2次都是直接使用,如果正好在这2次中间,我们执行 set global log_bin_use_v1_row_events = 0|1,改变原来的值,就会导致前后逻辑判断结果不一致。如果主库有频繁的更新操作,每次更新又比较大,只要修改这个值,就很容易触发这个bug。

另外官方还有点不严谨的是,文档上说这个值是 readonly的,实际代码是dynamic 的,如果是 readonly 的话,也就不会触发上面的bug了。


bug修复

修复很简单,把2次引用全局变量改成一次就好了,在Rows_log_event::write_data_header函数里直接使用已经保存的m_type,改法如下

 

这样改之后,就只会在构造函数中才用到全局变量。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
|
Java 关系型数据库 数据库连接
Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)
Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
|
关系型数据库 MySQL Serverless
实时计算 Flink版产品使用问题之使用cdas语法同步mysql数据到sr serverless是否支持动态加表
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
SQL 存储 关系型数据库
17. Mysql 动态SQL
17. Mysql 动态SQL
405 1
|
关系型数据库 MySQL 数据库
实时计算 Flink版操作报错合集之任务启动后加动态表读binlog报错如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
487 6

相关产品

  • 云数据库 RDS MySQL 版
  • 推荐镜像

    更多