开发者社区> 问答> 正文

es同步,删除步骤逻辑错误

环境信息

canal 1.1.3 mysql 5.7

问题描述

mainTableDelete 方法逻辑问题, 既然是主表删除操作, 然后该方法又是通过查询sql语句后进行es数据操作, mysql的主表数据都已经删除了, 怎么可能sql语句得到结果呢?

原提问者GitHub用户violet250

展开
收起
古拉古拉 2023-05-08 13:40:52 78 0
2 条回答
写回答
取消 提交回答
  • 如果主键是不带函数的单一字段,删除时不会通过sql反查数据。带函数或者复合主键暂不支持物理删除的同步

    原回答者GitHub用户rewerma

    2023-05-09 17:46:34
    赞同 展开评论 打赏
  • 随心分享,欢迎友善交流讨论:)

    根据您的描述,在Canal 1.1.3中使用ES进行数据同步时,发现主表数据已经被删除,但是Canal仍然尝试使用查询SQL语句进行ES数据操作,这导致了逻辑错误。

    在Canal中,当主表的数据被删除时,Canal会调用"mainTableDelete"方法来进行相应的数据同步操作。在"mainTableDelete"方法中,Canal会执行查询SQL语句来获取ES中需要删除的数据,在执行完SQL语句后,Canal会将查询结果作为删除操作的参数,从而完成数据同步。

    然而,在您的情况中,由于主表的数据已经被删除,查询SQL语句无法获取到任何结果。因此,Canal无法正确地进行数据同步,导致了逻辑错误。

    为了解决这个问题,您可以尝试使用Canal的"row"模式进行数据同步。在"row"模式下,Canal会将每一行的数据解析成一个JSON对象,而不是按照列进行解析。这样,在主表数据被删除时,Canal仍然可以正确识别数据,并将其同步到目标系统中。

    要使用"row"模式进行同步,您需要在Canal的配置文件中设置canal.instance.mode参数为"row"。例如:

    canal.instance.mode=row 在这个例子中,我们使用"row"模式进行同步。这将使Canal将每一行的数据解析为一个JSON对象,并将其传输到目标系统中。

    如果您希望继续使用Canal的默认模式进行同步,并且仍然要处理主表数据被删除的问题,建议您修改"mainTableDelete"方法的实现,以检查查询结果是否为空。如果查询结果为空,则可以将删除操作视为成功,从而跳过ES数据操作的逻辑。例如,您可以按照以下方式修改"mainTableDelete"方法的实现:

    private void mainTableDelete(List pkList) { // 1. 构造查询SQL语句,获取需要删除的数据 String querySql = ... // 构造查询SQL语句 List<Map<String, String>> esDataList = ... // 执行SQL语句,获取查询结果

    if (esDataList.isEmpty()) {
        // 如果查询结果为空,跳过ES数据操作的逻辑
        return;
    }
    
    // 2. 删除ES中的数据
    for (Map<String, String> esData : esDataList) {
        ... // 执行ES数据操作,删除数据
    }
    

    } 在这个示例中,我们检查了查询结果是否为空。如果查询结果为空,则跳过ES数据操作的逻辑。这样,在主表数据被删除时,Canal仍然可以正确识别数据,并将其同步到目标系统中。

    2023-05-08 13:52:09
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载