暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

gh-ost,又丢数据了

Bytebase 2024-01-25
351
gh-ost 是 GitHub 开源的一款 MySQL 在线 DDL 变更工具,具体原理和细节就不在这里过多介绍了,项目文档:https://github.com/github/gh-ost。
在我们使用 gh-ost 时,当 binlog 文件大于 4G 时,可能会发生数据丢失。
在 MySQL 中允许单个 binlog 文件大于 4G 的情况,而在 MySQL 源码中对于 binlog event end_log_pos 字段类型的定义为 uint32,最大存储 4G。所以当单个 binlog 文件大于 4G 时 end_log_pos 字段存储会溢出,循环使用。
尝试解析一个大于 4G 的 binlog 文件,看看溢出后的 end_log_pos 值,示例:
可以看到当 end_log_pos 达到 4294962881 时,下一个 event end_log_pos 溢出为 3601,值更小了,会导致一些工具判断逻辑出错。
丢数据的原因
在 gh-ost 代码的 handleRowsEvent 方法中,用来处理一个 DML event,有一处代码用来判断:当前接收的 event end_log_pos 值小于或等于最后一次执行的event end_log_pos 值则忽略当前 event。当 binlog 文件大于 4G 时,由于 event end_log_pos 溢出存储,会导致大于 4G 的 event 全部被丢弃处理。
this.LastAppliedRowsEventHint 记录最新接收到的 event 位点信息。
binlog 大于 4G 的原因
当数据表中存在 big row 时,一次 chunk 的数量过多时可能会带来一个大事务(假设事务大于4G),或业务自身有大事务。一个事务会写入单个 binlog 文件中。
group commit 与 binlog
在组提交的机制下,一个大事务(假设事务大于4G)的提交会带着同一个组的 N 个事务一块刷新 binlog cache,写入到同一个 binlog 文件。当前正在做 DDL 表的 DML 变更也可能会出现在这个组里面被一同写入到 binlog 文件,其 event end_log_pos 值会溢出。具体细节可以看相关资料,这里不展开了。
issue
提了个 issue 给官方,https://github.com/github/gh-ost/issues/1366
Thank you!

基于 gh-ost 的在线 Schema 变更

代码全开源!数据库工具届的瑞士军刀,替代多款工具的一站式数据库开发平台

5 分钟上手 Bytebase,完成第一次 Schema 变更

告别手搓!Postgres 一站式测试数据生成方案

文章转载自Bytebase,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论