obbinlog 与 mysql binlog 差异

【 使用环境 】生产环境
【 OB or 其他组件 】ob 4.3.4 obbinlog 4.2.5 canal 1.1.7
【 使用版本 】社区版
【问题描述】在ob执行INSERT INTO TABLE ON DUPLICATE KEY UPDATE时,当记录存在,obbinlog会生成一条delete和一条insert的日志,相同场景mysql只有一条update日志,如何能达到一样的效果。
【复现路径】



【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):

【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)

【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!

根据文档库中的信息,obbinlog 和 MySQL binlog 的差异主要体现在对 INSERT INTO ... ON DUPLICATE KEY UPDATE 语句的处理上。以下是详细分析和解决方案:


问题分析

  1. MySQL 的行为
    在 MySQL 中,当执行 INSERT INTO ... ON DUPLICATE KEY UPDATE 时,如果记录存在,则会生成一条 UPDATE 类型的日志。

  2. OceanBase 的行为
    在 OceanBase 中,对于相同的场景,obbinlog 会生成两条日志:一条 DELETE 日志和一条 INSERT 日志。这是由于 OceanBase 的实现机制决定的,具体表现为:

    • 当检测到主键冲突时,OceanBase 会先删除旧记录(生成 DELETE 日志),然后插入新记录(生成 INSERT 日志)。
    • 这种行为与 MySQL 的单条 UPDATE 日志不同。
  3. 用户需求
    用户希望在 OceanBase 中实现与 MySQL 相同的效果,即只生成一条 UPDATE 类型的日志。


解决方案

目前,OceanBase 社区版中尚未提供直接修改 obbinlog 行为以生成单条 UPDATE 日志的功能。但可以通过以下方式间接解决或优化:

1. 使用 REPLACE INTO 替代

REPLACE INTO 是一种替代方案,其行为与 INSERT INTO ... ON DUPLICATE KEY UPDATE 类似,但在底层实现上可能会更接近 MySQL 的 UPDATE 日志生成逻辑。示例如下:

REPLACE INTO table_name (c1, c2, c3) VALUES (4, 7, 8), (5, 8, 9);

注意:REPLACE INTO 实际上也是通过 DELETEINSERT 来实现的,因此可能仍然会生成两条日志。

2. 调整下游解析工具的逻辑

如果无法更改 obbinlog 的行为,可以调整下游解析工具(如 Canal)的逻辑,使其能够正确处理 DELETEINSERT 的组合日志。具体步骤如下:

  • 检测到 DELETEINSERT 的组合时,将其合并为一条 UPDATE 操作。
  • 这需要对解析工具进行定制开发。

3. 提交功能需求

如果上述方案无法满足需求,建议向 OceanBase 社区提交功能需求,请求支持生成单条 UPDATE 日志的行为。可以通过以下链接提交需求:


相关文档参考


总结

目前,OceanBase 的 obbinlog 在处理 INSERT INTO ... ON DUPLICATE KEY UPDATE 时生成两条日志的行为是由其底层实现决定的。如果需要达到与 MySQL 相同的效果,可以通过调整下游解析工具的逻辑或提交功能需求来解决。

详情请参考:

  1. 通过 oblogproxy 进行增量日志代理服务
  2. 列存 FAQ
  3. oblogproxy
  4. 设置并行执行参数
  5. replace 和 insert_or_update 的区别
  6. 集群管理 FAQ
  7. 日志概述
  8. Redo 日志
3 个赞

观摩

1 个赞

这个比较偏内核原理了啊

:+1: :+1: :+1: :grinning:

这个是有什么问题么?

在业务没有完全迁移ob时,需要将ob数据回写原业务库,这种先删后插的操作不满足数据同步的预期,正常应该是更新操作。

根据文档库中的信息,您的问题涉及在业务未完全迁移至 OceanBase 时,将 OceanBase 数据回写到原业务库(如 MySQL)的过程中,期望实现更新操作而非先删后插的行为。以下是详细分析和解决方案:


问题分析

  1. OceanBase 的行为
    在 OceanBase 中,INSERT INTO ... ON DUPLICATE KEY UPDATE 或类似的冲突处理机制可能会生成 DELETEINSERT 的组合日志,而不是直接的 UPDATE 日志。这种行为可能导致下游同步工具(如 OMS 或 Canal)无法正确识别为更新操作。

  2. 用户需求
    用户希望在数据回写过程中,能够以更新操作的形式同步数据,而不是通过删除和插入的方式。

  3. 挑战

    • OceanBase 社区版目前尚未提供直接修改 obbinlog 行为以生成单条 UPDATE 日志的功能。
    • 如果使用 OMS 进行数据同步,需要确保源端和目标端的数据一致性,并避免不必要的删除和插入操作。

解决方案

1. 使用反向增量同步功能

OMS 社区版支持反向增量同步功能,可以满足将 OceanBase 数据回写到原业务库的需求。具体步骤如下:

  • 创建事务库 omstxndb
    如果原业务库是 MySQL,请手动创建 OMS 社区版需要使用的事务库 omstxndb。如果不创建该事务库,可能会出现异常提示 omstxndb 库不存在。(参考文档:OMS 社区版事务库配置

  • 配置反向增量同步任务
    在创建数据迁移任务时,勾选 反向增量 功能。这将确保 OceanBase 的变更能够以更新操作的形式回写到原业务库。

2. 调整下游解析工具的逻辑

如果使用的是第三方工具(如 Canal)进行数据同步,可以调整其解析逻辑,使其能够正确处理 DELETEINSERT 的组合日志。具体步骤如下:

  • 检测到 DELETEINSERT 的组合时,将其合并为一条 UPDATE 操作。
  • 这需要对解析工具进行定制开发。

3. 使用 REPLACE INTO 替代

在某些场景下,可以考虑使用 REPLACE INTO 替代 INSERT INTO ... ON DUPLICATE KEY UPDATE。虽然 REPLACE INTO 实际上也是通过 DELETEINSERT 来实现的,但在某些情况下可能更接近于更新操作的效果。

示例:

REPLACE INTO table_name (c1, c2, c3) VALUES (4, 7, 8), (5, 8, 9);

4. 提交功能需求

如果上述方案无法满足需求,建议向 OceanBase 社区提交功能需求,请求支持生成单条 UPDATE 日志的行为。可以通过以下链接提交需求:


相关文档参考

  • OMS 社区版事务库配置
    文档标题:OMS 社区版事务库配置
    描述了在 MySQL 作为源端时,手动创建事务库 omstxndb 的必要性。

  • 数据迁移与同步限制
    文档标题:数据迁移与同步限制
    提及了 OceanBase 在某些场景下的特殊行为。


总结

在业务未完全迁移至 OceanBase 时,可以通过以下方式实现数据回写并满足更新操作的预期:

  1. 使用 OMS 社区版的反向增量同步功能。
  2. 调整下游解析工具的逻辑,合并 DELETEINSERTUPDATE
  3. 提交功能需求,请求支持生成单条 UPDATE 日志的行为。

如果您需要进一步的技术支持,建议联系 OceanBase 官方团队或社区专家。

详情请参考:

  1. oms_sync_failed 同步任务失败
  2. OMS 社区版问题排查手册
  3. 释放和删除数据同步任务
  4. 配置迁移对象的匹配规则
  5. 释放和删除数据迁移任务
  6. oms_migration_failed 迁移任务失败
  7. 更新 Full-Import 组件
  8. 同步 DDL
  9. 更新 Incr-Sync 组件
  10. 创建 OceanBase 社区版至 RocketMQ 的数据同步任务

(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)

目前ob的这个命令操作就是先删除 后插入