MySQL内核月报 2014.11-MySQL· 捉虫动态·SIGHUP 导致 binlog 写错

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

bug描述

这是5.6中和gtid相关的一个bug,当 mysqld 收到 sighup 信号 (比如 kill -1) 的时候,会 flush binlog,但是新生成binlog开头没写 Previous_gtids_log_event,这会导致下面 2 个问题:

  1. 这个时候 mysqld 重启的话,会发现再也起不来了,error log 里有这样的错

    The binary log file 'mysql/mysql-bin.000020' is logically corrupted: The first global transaction identifier was read, but no other information regarding identifiers existing on the previous log files was found.

  2. 这个时候主库继续更新,然后从库来拉取 binlog 的时候,io 线程会停下来

    Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Error reading header of binary log while looking for the oldest binary log that contains any GTID that is not in the given gtid set'

bug 分析

mysqld 在收到 sighup 信号后,signal_hand 线程会调用 reload_acl_and_cache 函数 (sql_reload.cc),最终会调用 MYSQL_BIN_LOG::open_binlog,open_binlog 有这段逻辑:

 

signal_hand 没有调用 store_globals 设置 THR_THD 这个key,所以这个时候 current_thd 得到的值是空的,因此prev_gtids_event 也就不会写进新binlog中的。

2个问题的分析

  1. mysqld 重启不起来的原因:

    mysqld 在启动的时候会通过 mysql_bin_log.init_gtid_sets 来初始化 gtid_executed 和 gtid_purged 2个set,初使化 gtid_executed 时,会读最新的binlog,将文件开头 Previous_gtids_log_event 的 gtid set 和文件里所有的 gtid_event 加起来,放进 gtid_executed,在读文件过程中,如果发现没有 Previous_gtids_log_event ,就报错,程序退出。

  2. 备库的错误信息解释:

    在gtid协议下,主库向备库发 binlog 是用 com_binlog_dump_gtid 函数,这个函数会调到 MYSQL_BIN_LOG::find_first_log_not_in_gtid_set(),这个函数的作用是找到备库需要的第一个 binlog 文件,逻辑是这样的,从编号最大的binlog 往前找,对每个binlog,读取 Previous_gtids_log_event,如果发现这个集合是备库的发来的 gtid_set 的子集,就停止,当前这个binlog文件就是备库需要的第一个binlog文件。找的过程中,如果发现没有 Previous_gtids_log_event,就把错误信息 ER_MASTER_FATAL_ERROR_READING_BINLOG 发给备库。

问题的解决方法

  1. 对server 起不来的,只能手动删所有 binlog 文件了,同时还要清空 binlog.index 文件,有备库的话要重搭备库。
  2. 对于主备场景下,备库停掉的,purge 主库的binlog,如果主备不致的话,比如主库sighup后又有新的更新,这时候需要重做备库,因为binlog已经没了,只能拿主库的数据来重新做一个。


bug 修复

这个bug官方已经修复,具体可以参考 revno: 5908

修复方法类似reload_acl_and_cache 中 REFRESH_GRANT 的逻辑,生成一个临时的 THD 作为 current_thd,在flush logs 完后释放掉。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
10天前
|
存储 安全 关系型数据库
Mysql 的binlog日志的优缺点
MySQL的binlog(二进制日志)是一个记录数据库更改的日志文件,它包含了所有对数据库执行的更改操作,如INSERT、UPDATE和DELETE等。binlog的主要目的是复制和恢复。以下是binlog日志的优缺点: ### 优点: 1. **数据恢复**:当数据库出现意外故障或数据丢失时,可以利用binlog进行点恢复(point-in-time recovery),将数据恢复到某一特定时间点。 2. **主从复制**:binlog是实现MySQL主从复制功能的核心组件。主服务器将binlog中的事件发送到从服务器,从服务器再重放这些事件,从而实现数据的同步。 3. **审计**:b
|
19天前
|
SQL 关系型数据库 MySQL
mysql的binlog恢复数据
mysql的binlog恢复数据
19 0
|
24天前
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
19 1
|
24天前
|
Java 关系型数据库 数据库连接
Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)
Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)
23 1
|
2月前
|
存储 SQL 安全
浅谈MySQL Binlog
浅谈MySQL Binlog
43 0
|
24天前
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
14 1
|
24天前
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
20 1
|
24天前
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
21 2
|
24天前
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
15 1
|
24天前
|
Java 数据库连接 mybatis
Mybatis+mysql动态分页查询数据案例——Mybatis的配置文件(mybatis-config.xml)
Mybatis+mysql动态分页查询数据案例——Mybatis的配置文件(mybatis-config.xml)
14 1

相关产品

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

    更多