RDS for MySQL 8.0 升级 8.4 之下游 Binlog 消费处理实战 (一)—— 蓝绿部署下的 Canal CDC 位点衔接与故障处理

RDS for MySQL 8.0 升级 8.4 之下游 Binlog 消费处理实战 (一)—— 蓝绿部署下的 Canal CDC 位点衔接与故障处理

💡 原文中文,约14600字,阅读约需35分钟。
📝

内容提要

本文介绍RDS MySQL 8.0升级至8.4时,蓝绿切换导致Canal CDC出现errno 1236错误。原因是绿环境只读副本的binlog缺失部分GTID事务。解决方案是将Canal原GTID位点与绿副本的gtid_purged求并集修补,而非整体覆盖。同时需调整Kafka消息大小限制,并遵循切换前检查、故障处置和验证步骤。

🔎

延伸解读

GTID 位点修补的核心:并集而非覆盖

蓝绿切换后,Canal 报 errno 1236 的根源是绿只读副本的 binlog 缺失部分 GTID 事务(如 5ca50a2f:1-16),这些事务在副本创建时已进入 gtid_purged。正确做法是将 Canal 原 GTID 位点与绿副本的 gtid_purged 求并集,仅将无法获取的内部事务标记为已消费,其余仍由服务端补发。若用当前 Executed_Gtid_Set 整体覆盖,会静默丢失切换后未投递的事务,造成下游数据缺口。

版本兼容性:Canal 1.1.8 与 MySQL 8.4 的适配

MySQL 8.4 移除了 SHOW MASTER STATUS,改用 SHOW BINARY LOG STATUS。Canal 需 1.1.8 正式版及以上(含 PR #5231)才能适配,1.1.7 及以下或 1.1.8 的 alpha-1/alpha-2 会报语法错误。此外,8.4 默认禁用 mysql_native_password,复制账号需迁移到 caching_sha2_password。升级前务必确认 Canal 版本和账号认证方式,否则切换后可能无法正常寻位。

Kafka 消息大小限制:追赶期的隐藏陷阱

位点修复后,Canal 全速追赶时可能触发 RecordTooLargeException,因为默认将最多 50 个 entry 打包成一条消息,大字段变更易超过 1MB 默认限制。需同步调整 Canal producer(kafka.max.request.size)、Kafka topic/broker(max.message.bytes)和下游 consumer(max.partition.fetch.bytes)三处配置。注意压缩无法规避 producer 侧检查,且发送失败可能导致投递线程退出,表现为源端

Q&A

RDS MySQL 8.0升级到8.4时,Canal出现errno 1236错误的原因是什么?

在蓝绿切换后,Canal连接到绿环境只读副本时,由于绿只读副本的binlog中缺失部分GTID事务(如5ca50a2f:1-16),这些事务在创建绿只读副本时已通过快照进入gtid_executed但从未写入其binlog,导致服务端无法补发,从而报错errno 1236。

如何修复Canal在蓝绿切换后的GTID位点问题?

正确方法是将Canal原有的GTID位点与绿只读副本的gtid_purged求并集,而不是用当前Executed_Gtid_Set整体覆盖。并集后的GTID集合写入Canal meta或配置中,重启Canal即可恢复。

为什么不能用当前Executed_Gtid_Set覆盖Canal位点?

因为当前Executed_Gtid_Set包含切换后已执行但尚未被Canal投递的事务,整体覆盖会将这些事务标记为已消费,导致下游数据缺口,且不易察觉,属于静默丢数据风险。

Canal在ZooKeeper模式下如何修补GTID位点?

先停止instance,备份cursor节点,然后删除cursor节点,并在instance.properties中配置并集后的GTID集合(canal.instance.master.gtid),最后启动instance。或者直接修改cursor JSON中的gtid字段,但需注意格式。

Canal追赶阶段出现RecordTooLargeException如何处理?

需要调整三处消息大小限制:Canal producer的kafka.max.request.size、Kafka topic/broker的max.message.bytes或message.max.bytes、下游consumer的max.partition.fetch.bytes。同时注意压缩不能规避此问题,并需确认所有相关topic都已调整。

蓝绿切换前需要做哪些检查?

确认Canal版本为1.1.8及以上、复制账号使用caching_sha2_password、gtidon=true、连接使用DNS endpoint;设置binlog retention(建议168小时);记录绿只读副本的gtid_executed和gtid_purged;调整Kafka消息大小限制;确认位点存储模式并演练修补流程。

切换后如何验证Canal数据链路正常?

验证日志出现find start position successfully且无errno 1236,GTID位点持续前进;写入marker数据并确认出现在Kafka topic中;用GTID_SUBTRACT检查差值仅剩内部事务;对切换窗口做下游抽样对账。

🏷️

标签

➡️

继续阅读