在仲裁丢失后重试SQL插入时重复键值

时间:2018-02-22 15:51:14

标签: cockroachdb

我目前正在使用3个cockroachDB节点测试故障情况。

使用此方案:

  1. 在循环中插入记录
  2. 关闭3个节点中的2个节点(模拟Quorum丢失)
  3. 等待足够长的时间,以便Postgres JDBC驱动程序抛出IO异常
  4. 重新启动一个节点以恢复Quorum
  5. 重试以前失败的陈述
  6. 然后我点击了以下异常

    Cause: org.postgresql.util.PSQLException: ERROR: duplicate key value (messageid)=('71100358-aeae-41ac-a397-b79788097f74') violates unique constraint "primary"
    

    这意味着当Quorum再次可用时,插入在第一次尝试时成功(我从中获得了IO Exception)。问题是我没有意识到这一点。

    我无法假设应用程序逻辑问题会导致“重复键值”异常。是否有任何我可以调整的参数,以便在IO异常之前基础语句回滚?或者更好的方法?

    使用

    进行测试
    • CockroachDB v1.1.5(3个节点)
    • MyBatis 3.4.0
    • PostgreSQL驱动程序42.2.1
    • Java 8

1 个答案:

答案 0 :(得分:1)

这里可能会发生一些事情。

首先,如果你要杀死的其中一个节点是网关节点(你的那个节点) Java进程正在连接到),它可能只是数据存在 已提交,但节点在能够发回确认之前就已死亡 给客户。在这种情况下,CockroachDB可以做的事情并不多 或任何其他数据库。

更微妙的情况是你要杀死的节点除了节点之外 网关节点。也就是说,你正在谈话的节点向你发送了一个 错误,尽管数据已成功提交。这里的问题是 一旦写入筏,数据就会被提交,但有可能 如果其他节点已经死亡(并且可能稍后再回来),那就没办法了 网关节点知道他们是否已提交了它所询问的数据 他们来。在这种情况下,CockroachDB会返回“模糊的结果错误”。 我不确定jdbc如何公开返回的错误的具体细节 在这样的情况下客户端,但如果您检查错误本身,它应该说 这样的事情。

CockroachDB中的模糊结果在其Jepsen analysis中进行了简要讨论,并在CockroachDB文档中查看this page,了解可以返回的错误类型的信息。