作者:卢文双 资深数据库研发工程师 目前负责青云云数据库的研发工作,热衷于研究主流数据库架构、源码,对关系型数据库 MySQL/PostgreSQL 及分布式数据库有深入研究。

前言

在为 Xenon[1] 适配新版 Percona XtraBackup 8.0[2](原有代码适配于 2.4 版本)时遇到的一些问题,在定位过程中对比了 XtraBackup 2.4 和 8.0 的异同。

版本信息[3]:

  • Percona-Server 8.0.19-10
  • Percona-Xtrabackup 8.0.13

问题描述

问题 1

MySQL 8.0 + Semi-Sync + 持续写入数据期间执行重建后, change master to && start slave 报错:

Last_Error: Could not execute Write_rows event on table db1.t1; Duplicate entry '28646' for key 't1.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000052, end_log_pos 437

问题 2

MySQL 8.0 + Group Replication + 持续写入数据期间执行重建后,change master to && start group_replication 报错:

2020-08-21T14:51:09.977606+08:00 61 [System] [MY-010597] [Repl] 'CHANGE MASTER TO FOR CHANNEL 'group_replication_applier' executed'. Previous state master_host='<NULL>', master_port= 0, master_log_file='', master_log_pos= 4, master_bind=''. New state master_host='<NULL>', master_port= 0, master_log_file='', master_log_pos= 4, master_bind=''.
2020-08-21T14:51:09.987494+08:00 61 [ERROR] [MY-013124] [Repl] Slave SQL for channel 'group_replication_applier': Slave failed to initialize relay log info structure from the repository, Error_code: MY-013124
2020-08-21T14:51:09.987542+08:00 61 [ERROR] [MY-011534] [Repl] Plugin group_replication reported: 'Error while starting the group replication applier thread'
2020-08-21T14:51:09.987651+08:00 7 [ERROR] [MY-011669] [Repl] Plugin group_replication reported: 'Unable to initialize the Group Replication applier module.'
2020-08-21T14:51:09.987831+08:00 7 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] The member is leaving a group without being on one.'

要解释这两个问题,首先要弄清楚 XtraBackup 2.4 和 8.0 的区别。

XtraBackup 2.4/8.0 版本区别

通过查到可知 XtraBackup 2.4 与 8.0 版本备份记录信息有如下不同点:

  • 2.4 备份生成的 xtrabackup_binlog_info 文件记录的 GTID 信息是准确的,但是备份恢复后 show master status 显示的 GTID 是不准确的;
  • 8.0 备份的实例中只有 InnoDB 表时,xtrabackup_binlog_info 文件记录的 GTID 信息不一定是准确的,但是备份恢复后 show master status 显示的 GTID 是准确的;
  • 8.0 备份的实例中有非 InnoDB 表时,xtrabackup_binlog_info 文件记录的 GTID 信息是准确的,备份恢复后 show master status 显示的 GTID 也是准确的。

两个版本执行过程如下:

2.4 8.0
1. start backup
2. copy ibdata1 / copy .ibd file
3. excuted FTWRL
4. backup non-InnoDB tables and files
5. writing xtrabackup_binlog_info
6. executed FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS
7. executed UNLOCK TABLES
8. copying ib_buffer_pool
9. completed OK!
1. start backup
2. copy .ibd file
3. backup non-InnoDB tables and files
4. executed FLUSH NO_WRITE_TO_BINLOG BINARY LOGS
5. selecting LSN and binary log position from p_s.log_status
6. copy last binlog file
7. writing /mysql/backup/backup/binlog.index
8. writing xtrabackup_binlog_info
9. executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS
10. copy ib_buffer_pool
11. completed OK!

注意:当存在非 InnoDB 表时,8.0 会执行 FTWRL。

通过两个版本执行过程命令不难看出,主要区别在于 8.0 版本当只存在 InnoDB 表时,执行步骤 5 命令来获取 LSN、binlog position、GTID。

手册中[4],对于表 log_status 的描述如下:

The log_status table provides information that enables an online backup tool to copy the required log files without locking those resources for the duration of the copy process.

When the log_status table is queried, the server blocks logging and related administrative changes for just long enough to populate the table, then releases the resources. The log_status table informs the online backup which point it should copy up to in the source’s binary log and gtid_executed record, and the relay log for each replication channel. It also provides relevant information for individual storage engines, such as the last log sequence number (LSN) and the LSN of the last checkpoint taken for the InnoDB storage engine.

从上述手册描述可知,performance_schema.log_status 是 MySQL 8.0 提供给在线备份工具获取复制信息的表格,查询该表时,mysql server 将阻止日志的记录和相关的更改来获取足够的时间以填充该表,然后释放资源。

log_status 表通知在线备份工具当前主库的 binlog 的位点和 gtid_executed 的值以及每个复制通道的 relay log。另外,它还提供了各个存储引擎的相关信息,比如,提供了 InnoDB 引擎使用的最后一个日志序列号(LSN)和最后一个检查点的 LSN。

表 log_status 定义参数信息示例如下:

-- Semi-Sync
mysql> select * from performance_schema.log_status\G
*************************** 1. row ***************************SERVER_UUID: 6b437e80-e5d5-11ea-88e3-52549922fdbbLOCAL: {"gtid_executed": "6b437e80-e5d5-11ea-88e3-52549922fdbb:1-201094", "binary_log_file": "mysql-bin.000079", "binary_log_position": 195}REPLICATION: {"channels": []}
STORAGE_ENGINES: {"InnoDB": {"LSN": 23711425885, "LSN_checkpoint": 23711425885}}
1 row in set (0.00 sec)-- Group Replication
mysql> select * from performance_schema.log_status\G
*************************** 1. row ***************************SERVER_UUID: 7bd32480-e5d5-11ea-8f8a-525499cfbb7dLOCAL: {"gtid_executed": "aaaaaaaa-aaaa-aaaa-aaaa-53ab6ea1210a:1-11", "binary_log_file": "mysql-bin.000003", "binary_log_position": 1274}REPLICATION: {"channels": [{"channel_name": "group_replication_applier", "relay_log_file": "mysql-relay-bin-group_replication_applier.000004", "relay_log_position": 311, "relay_master_log_file": "", "exec_master_log_position": 0}, {"channel_name": "group_replication_recovery", "relay_log_file": "mysql-relay-bin-group_replication_recovery.000003", "relay_log_position": 151, "relay_master_log_file": "", "exec_master_log_position": 0}]}
STORAGE_ENGINES: {"InnoDB": {"LSN": 20257208, "LSN_checkpoint": 20257208}}
1 row in set (0.00 sec)

问题定位

问题 1:MySQL 8.0 + Semi-Sync 重建

Xenon 原有的重建逻辑适配于 MySQL 5.6/5.7(重建过程中 Xenon 进程存活),一直无问题。

Xenon 重建逻辑

  1. 禁用 raft,将 Xenon 状态设为 LEARNER;
  2. 如 mysql 进程存在,则 stop mysql
  3. 清空 MySQL 数据目录;
  4. 执行 xtrabackup --backup 以 xbstream 方式获取对端数据;
  5. 执行 xtrabackup --prepare 应用 redo log;
  6. 启动 mysql;
  7. 执行 stop slave; reset slave all
  8. 执行 reset master,以 xtrabackup_binlog_info 文件中的 GTID 为准设置 gtid_purged;
  9. 启用 raft,将 Xenon 状态设为 FOLLOWER 或 IDLE;
  10. 等待 Xenon 自动 change master to 到主节点;
  11. 执行 start slave

Duplicate entry '28646' for key 't1.PRIMARY' 表示主键冲突,说明表中已存在相同主键的行。跟踪重建过程中的 general log,发现在第 6 和第 7 步中间,也就是设置 gtid_purged 之前凭空多出了 change master tostart slave 操作。

grneral log(部分)

通过下面示例代码信息可看出,在设置 gtid_purged 之前已经启用复制获取了一部分数据,那么 xtrabackup_binlog_info 中的内容就不再准确,之后设置的 GTID 与实际数据就不一致,实际的数据比设置的 GTID 要多,会引起主键冲突。

SET GLOBAL rpl_semi_sync_master_enabled=OFF
SET GLOBAL read_only = 1
SET GLOBAL super_read_only = 1
START SLAVE
STOP SLAVE
CHANGE MASTER TO MASTER_HOST = '192.168.0.3', MASTER_USER = 'qc_repl', MASTER_PASSWORD = <secret>, MASTER_PORT = 3306, MASTER_AUTO_POSITION = 1
START SLAVE
BEGIN
COMMIT /* implicit, from Xid_log_event */
......
BEGIN
COMMIT /* implicit, from Xid_log_event */
SET GLOBAL rpl_semi_sync_master_enabled=OFF
SET GLOBAL read_only = 1
SET GLOBAL super_read_only = 1
START SLAVE
BEGIN
COMMIT /* implicit, from Xid_log_event */
......
BEGIN
COMMIT /* implicit, from Xid_log_event */
STOP SLAVE
RESET SLAVE ALL
RESET MASTER
SET GLOBAL gtid_purged='6b437e80-e5d5-11ea-88e3-52549922fdbb:1-102610
'
START SLAVE
SET GLOBAL read_only = 1
SET GLOBAL super_read_only = 1
SET GLOBAL sync_binlog=1000
SET GLOBAL innodb_flush_log_at_trx_commit=1
SHOW SLAVE STATUS
SHOW MASTER STATUS
SET GLOBAL rpl_semi_sync_master_enabled=OFF
SET GLOBAL read_only = 1
SET GLOBAL super_read_only = 1
START SLAVE
SHOW SLAVE STATUS
SHOW MASTER STATUS
STOP SLAVE
CHANGE MASTER TO MASTER_HOST = '192.168.0.3', MASTER_USER = 'qc_repl', MASTER_PASSWORD = <secret>, MASTER_PORT = 3306, MASTER_AUTO_POSITION = 1
START SLAVE
疑问 1

问:为什么之前 MySQL 5.6/5.7 从没遇到过这个问题呢?

答:多次测试发现在 MySQL 5.6/5.7 中 set gtid_purged 前执行 change master to & start slave 会报复制错误 Slave failed to initialize relay log info structure from the repository,在 reset slave all; reset master、set gtid_purged 后再执行 change master to & start slave 就可以正常复制,数据无误。

疑问 2

问:Xenon 中哪块逻辑引起的额外的 change master tostart slave

答:在重建期间 Xenon 会设为 LEARNER 角色,而该角色在探测到 MySQL Alive后,会 change master 到主节点。

解决方案:
  • 去掉 LEARNER 对 MySQL 的监听,要等 raft 状态变为 FOLLOWER 后,由 FOLLOWER 的监听线程 change master to 到主节点。[5]

  • 对于 MySQL 8.0,重建后无需执行 reset master & set gtid_purged 操作。[6]

问题 2:MySQL 8.0 + Group-Replication 重建后无法启动 MGR

根据报错信息 Slave failed to initialize relay log info structure from the repository 看,应该是 XtraBackup 重建后的数据目录保留了 slave 复制信息导致的。

解决方案:

在启动组复制前执行 reset slavereset slave all 即可解决。

XtraBackup 8.0 避坑总结

  • 使用 Xtrabackup 8.0 重建集群节点后,无需执行 reset master & set gtid_purged 操作;
  • 使用 Xtrabackup 8.0 重建 Group-Replication 集群节点后,启动组复制前要先执行 reset slavereset slave all 清除 slave 信息,否则 start group_replication 会失败。

备注参考

[1]. Xenon : https://github.com/radondb/xenon

[2]. Percona XtraBackup : https://www.percona.com/software/mysql-database/percona-xtrabackup

[3]. 版本名含义参考:https://www.percona.com/blog/2020/08/18/aligning-percona-xtrabackup-versions-with-percona-server-for-mysql/

[4]. MySQL 官方手册:https://dev.mysql.com/doc/refman/8.0/en/performance-schema-log-status-table.html

[5]. pr104:https://github.com/radondb/xenon/pull/104

[6]. pr102:https://github.com/radondb/xenon/pull/102

关于 RadonDB

RadonDB 开源社区是一个面向云原生、容器化的数据库开源社区, 为数据库技术爱好者提供围绕主流开源数据库(MySQL、PostgreSQL、Redis、MongoDB、ClickHouse 等)的技术分享平台,并提供企业级 RadonDB 开源产品及服务。

目前 RadonDB 开源数据库系列产品已被 光大银行、浦发硅谷银行、哈密银行、泰康保险、太平保险、安盛保险、阳光保险、百年人寿、安吉物流、安畅物流、蓝月亮、天财商龙、罗克佳华、升哲科技、无锡汇跑体育、北京电信、江苏交通控股、四川航空、昆明航空、国控生物 等上千家企业及社区用户采用。

RadonDB 可基于云平台与 Kubernetes 容器平台交付,不仅提供覆盖多场景的数据库产品解决方案,而且提供专业的集群管理和自动化运维能力,主要功能特性包括:高可用主从切换、数据强一致性、读写分离、一键安装部署、多维指标监控&告警、弹性扩容&缩容、横向自由扩展、自动备份&恢复、同城多活、异地灾备 等。RadonDB 仅需企业及社区用户专注于业务层逻辑开发,无需关注集群高可用选型、管理和运维等复杂问题,帮助企业及社区用户大幅度提升业务开发与价值创新的效率!

GitHub:

https://github.com/radondb

微信群: 请搜索添加群助手微信号 radondb

Xenon 在使用 XtraBackup 8.0 重建数据过程中遇到的问题及定位分析。以及 XtraBackup 2.4 与 8.0 版本在执行流程上的异同。

问题定位 | XtraBackup 8.0 数据重建避坑事件始末相关推荐

  1. HarmonyOS实战 —基于hi3861芯片鸿蒙2.0的避坑指南

    HarmonyOS实战 -基于hi3861芯片鸿蒙2.0的避坑指南 特别说明:本文章与卡片开发无关,想看卡片开发的不用往下读了 最近学习鸿蒙设备开发的过程中遇到了很多问题,因为目前几乎所有设备开发教程 ...

  2. ASP.NET Core 3.0 迁移避坑指南

    一.前言 .NET Core 3.0将会在 .NET Conf 大会上正式发布,截止今日发布了9个预览版,改动也是不少,由于没有持续关注,今天将前面开源的动态WebApi项目迁移到.NET Core ...

  3. MPAndroidChart 自定义 X 轴、Y 轴标签,v3.1.0 如何避坑。

    错误版本:

  4. 0基础自学Python,有哪些避坑经验?

    回顾自己近 2 年的Python 自学经历,有一些学习心得和避坑经验分享给大家,让大家在学习 Python 的过程中少走一些弯路!减少遇到不必要的学习困难! 首先,最开始最大的困难应该就是对编程的抵触 ...

  5. 项目从0到1避坑指南

    背景: 物流行业,老板信息化意识弱,不是现有的TMS而是一个新的方向,目前市场上竞品较少 前言: 一个项目从0到1,有相关的固定的考虑事项.然而,由于公司环境.项目涉及的行业等一些实际条件的约束,会在 ...

  6. 深度学习环境配置避坑-CUDA11.0+DGL1.8

    深度学习环境配置避坑-CUDA11.0+DGL1.8 参考教程 坑1:CUDA版本与GPU型号不符 参考教程 之前已经写过详细的CUDA+Pytorch+DGL安装博文了,Linux系统可参考这里,W ...

  7. Ununtu 18.04 安装Carla 0.9.13 以及Carla ros bridge 超级避坑指南(更新于2022.10.20)

    Carla0.9.13 以及Carla ros bridge 超级避坑指南 Carla0.9.13 以及Carla ros bridge 超级避坑指南 站在巨人肩膀前进 显卡驱动问题 首先就是虚幻4的 ...

  8. 0 【Ubuntu/Linux】Ubuntu18.04有线连接图标不见(Linux系统安装2.5G有线网卡驱动,亲测避坑)

    前言 本人电脑安装的是windows10+Ubuntu18.04双系统,不是Linux虚拟机!!!!(虚拟机的网络问题需要看别的文章了) 本人的电脑是微星B560M MOTAR主板,该主板的网卡是2. ...

  9. HarmonyOS 开发避坑指南

    Harmony OS 开发避坑指南--源码下载和编译 本文介绍了如何下载鸿蒙系统源码,如何一次性配置可以编译三个目标平台(Hi3516,Hi3518和Hi3861)的编译环境,以及如何将源码编译为三个 ...

最新文章

  1. CV08-数据预处理与数据增强
  2. python四个带 key 参数的函数(max、min、map、filter)
  3. 1.8-zabbix服务端安装
  4. C语言 十进制和二进制相互转换 - C语言零基础入门教程
  5. 详细的 Python 安装教程(windows)
  6. jquery常见操作总结
  7. 图片压缩小工具,jpg,png压缩
  8. java messagebox_由MessageBox透视Win32 API的调用 | 学步园
  9. php百度地图普通ip定位,使用百度地图定位IP位置
  10. 淘宝京东查看价格历史的chrome插件
  11. java中int与byte相互转换
  12. 在linux系统下忘记了root密码,教你在Linux系统中解决忘记root口令密码的方法
  13. Debian安装WPS的方法
  14. 银行业智能运维的探索与实践
  15. 计算机往届生考研失败找工作,考研二战失败如何找工作 考研往届生找工作的方法...
  16. 正则表达式切掉log日志前面不需要的内容
  17. JPA一:理论知识和入门程序
  18. 《Bootloader 启动流程和概念介绍》
  19. Go语言自学系列 | golang标准库os模块 - File文件读操作
  20. USB驱动详解(主从对比)

热门文章

  1. 虚幻编程准备之-宏定义的语法
  2. Labview菜单实现
  3. 关于建立开放的学术论文共享平台的倡议
  4. 运行wrf报错:could not open xx albedo_modis/index
  5. 家用智能洗地机哪个牌子好?618洗地机品牌排行榜
  6. 微信号的2/8分布原理,你真的知道吗?
  7. win10如何进入安全模式?
  8. POE供电 5G通讯变压器 芯片
  9. KPI总结模板: Why?
  10. 电池供电微低功耗智慧摄像头直读式无线拍照抄表器技术方案