MySQL · 答疑解惑 · GTID不一致分析

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 背景 server A,B 为双主结构,对于 server A 当gtid_next设置为AUTOMATIC时,A上执行的事务在binlog刷盘时递增获取事务的gtid,从而保证了在binlog中属于A的gtid是连续递增的。 A的binlog在B应用时,B会通过 Executed_Gtid_S

背景

server A,B 为双主结构,对于 server A 当gtid_next设置为AUTOMATIC时,A上执行的事务在binlog刷盘时递增获取事务的gtid,从而保证了在binlog中属于A的gtid是连续递增的。

A的binlog在B应用时,B会通过 Executed_Gtid_Set 来记录A的binlog在B的执行情况。而A的binlog中gtid是连续的,从而

  1. B未开启并行复制,B依次应用binlog,Executed_Gtid_Set中B的gtid集合应该是连续的,如A:1-100

  2. B开启并行复制此时,B并发应用binlog,Executed_Gtid_Set中B的gtid集合末端可能会出现不连续的情况,如A:1-92:94-96:98-100
    但是如果在A停止写入,B和A完全同步的情况下,Executed_Gtid_Set中B的gtid集合应该是连续的。

以下分析均基于双主结构。

GTID不一致产生原因

并行复制

前面提到,并行复制时,Executed_Gtid_Set 尾部可能出现正常的空洞。这种不一致可以忽略,最终会一致的。

change master导致gtid丢失

change master重新指定binlog的拉取位置会导致主备gtid不一致。

考虑如下情况

主库:

create table t1(c1 int) engine=innodb;
create view v1 as select * from t1;

备库:

set sql_log_bin=0;
drop view v1;

主库:

create view v1 as select * from t1;

执行失败但仍然会生成binlog, binlog中error_code=1050,参考之前月报binlog event 中的 error code

#160118 17:33:11 server id 2219317521  end_log_pos 172885 CRC32 0xb6f4693d  Query   thread_id=76714 exec_time=0 error_code=1050
SET TIMESTAMP=1453109591/*!*/;
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` AS select * from t1

备库:

show slave status\G
Last_SQL_Error: Query caused different errors on master and slave.     Error on master: message (format)='Table '%-.192s' already exists' error code=1050 ; Error on slave: actual message='no error', error code=0. Default database: 'zy'. Query: 'CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` AS select * from t1'

备库create view执行成功,而与预期应出现的binlog error_code不一致导致备库复制中断。

那么如何修复此类错误呢?首先想到这个binlog事件是可以跳过的,因此尝试使用跳过空事务的方式来尝试修复。实际上,这种修复方式是不起作用的。

构造空事务来忽略相同gtid,执行start slave;后SQL线程执行过程如下

  1. 首先预检查gtid是否执行,如果此gtid已执行,语句直接返回成功0;
  2. 然后检查预期error_code是否为1050,而实际error_code=0,还是不一致。

因此,此类错误通过构造空事务方式无法修复。

此时就需要change master 方式指向失败事件的下一个位点。然后按位点的方式(master_auto_position=0)来拉binlog。

stop slave;
change master to  master_log_file='xxxx', master_log_pos=xxx,master_auto_position=0;
start slave;

至此失败已经修复,但show slave status可以看到 Executed_Gtid_Set 存在空洞,gtid已经不一致了。

此时,我们可以通过skip空事务的方式来弥补这个空洞。

下一步,我们可以选择修改为通过gtid方式来拉binlog(此步必须在弥补空洞之后)。

stop slave;
change master to master_auto_position=1;
start slave;

主机crash

主库所在主机crash后,可能导致主库比备库少一些gtid。

binlog在写文件时先write,再sync。假设主库在write binlog之后,sync 之前,同时备库也拉取了这些未sync的binlog。此时主库宕机,主库一部分 binlog 未落盘,但这部分binlog已经传到了备库,那么备库会比主库多一些事务。因此主库重启后,重新构造 gtid_executed_set 时会比备库少一些gtid。

那些未sync的事务实际处于两阶段提交的prepare状态,重启后这些处于prepare的事务由于没有写binlog会回滚掉。

主机宕机HA切换后,新主库会比新备库多一些事务。

而实际上新主库会比新备库多一些事务应该没有影响,这些事务是用户发出了commit命令,但主机crash了,没有收到commit的回复,处于未知状态。这些未决事务可以提交也可以回滚!

对于以上情况,在binlog没有purge的情况下,结合应用我们可以根据gtid来修复主备不一致的情况,或回滚备库的修改,或者重做主库丢失的事务。

gtid不一致的 影响

假设备库比主库少一些gtid, 而主库多出来的这些gtid已经purge了。如果用备库做的备份集来恢复出一个实例时,备库会去主库拉取缺少的那些gtid,而那些gtid已经purge了。
这就会导致臭名昭著的1236问题

Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'

根据前面的gtid不一致的分析,我们应该提前发现不一致,并及时修复,避免此类情况发生。

修复方法

这里总结些gtid不一致的修复方法:

  1. 对于可以忽略的gtid事务,可以通过跳过gtid的方式修复;
  2. 修改GTID_PURGED的方式
    先reset master,再设置GTID_PURGED来修复不一致,此种方式需确保主备数据一致的情况下进行,风险较大,酌情考虑。
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
9天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
11 0
|
3月前
|
关系型数据库 MySQL Serverless
高顿教育:大数据抽数分析业务引入polardb mysql serverless
高顿教育通过使用polardb serverless形态进行数据汇总,然后统一进行数据同步到数仓,业务有明显高低峰期,灵活的弹性伸缩能力,大大降低了客户使用成本。
|
20天前
|
SQL 关系型数据库 MySQL
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(8.0版本升级篇)
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(8.0版本升级篇)
93 0
|
9天前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
75 0
|
15天前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
17天前
|
SQL 关系型数据库 MySQL
【MySQL】慢SQL分析流程
【4月更文挑战第1天】【MySQL】慢SQL分析流程
|
20天前
|
SQL 关系型数据库 MySQL
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(数据恢复补充篇)(一)
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(数据恢复补充篇)
29 0
|
1月前
|
存储 关系型数据库 MySQL
TiDB与MySQL、PostgreSQL等数据库的比较分析
【2月更文挑战第25天】本文将对TiDB、MySQL和PostgreSQL等数据库进行详细的比较分析,探讨它们各自的优势和劣势。TiDB作为一款分布式关系型数据库,在扩展性、并发性能等方面表现突出;MySQL以其易用性和成熟性受到广泛应用;PostgreSQL则在数据完整性、扩展性等方面具有优势。通过对比这些数据库的特点和适用场景,帮助企业更好地选择适合自己业务需求的数据库系统。
|
2月前
|
存储 运维 关系型数据库
规划阿里云RDS跨区迁移业务需求业务影响分析
规划阿里云RDS跨区迁移业务需求业务影响分析
24 4
|
2月前
|
SQL 存储 关系型数据库
MySQL(终结篇二)- SQL 语句分析与优化
MySQL(终结篇二)- SQL 语句分析与优化
87 0

相关产品

  • 云数据库 RDS MySQL 版