原始网页:https://www.cockroachlabs.com/docs/stable/common-errors.html#result-is-ambiguous


本小节将帮助用户理解和解决输出到stderr和日志的错误消息。

主题 消息
Client connection connection refused
Client connection node is running secure mode, SSL connection required
Transactions retry transaction
Node startup node belongs to cluster <cluster ID> but is attempting to connect to a gossip network for cluster <another cluster ID>
Node configuration clock synchronization error: this node is more than 500ms away from at least half of the known nodes
Node configuration open file descriptor limit of <number> is under the minimum required <number>
Replication replicas failing with "0 of 1 store with an attribute matching []; likely not enough nodes in cluster"
Deadline exceeded context deadline exceeded
Ambiguous results result is ambiguous

connection refused

该消息代表客户端尝试连接一个异常节点,该节点没有运行CockroachDB或着监听的接口跟客户端连接指定的不一致(例如hostname或是端口)。

尝试以下方式解决问题:

若用户不确定--host--port指定的值,可以查看节点日志确认。必要时也可以杀死cockroach进程并重新启动节点。

pkill cockroach
cockroach start [flags]

消息:node is running secure mode, SSL connection required

该消息表示集群正在使用TLS加密技术保护集群通讯网络,而客户端尝试使用一个开放的连接,没有使用必要的TLS验证。

解决该问题的方式是执行cockroach cert client-create命令为连接该节点的用户生成客户端证书和密钥文件。关于完整的安全部署流程,包括生成安全证书和连接客户端,可以查看手动部署

消息:retry transaction

40001错误码和retry transaction字符串的消息,代表着一个事务因为跟另一个并行的或是最近的事务访问到相同的数据,产生冲突,并进而导致事务失败。该事务需要客户端重新提交,详见客户端事务重试

消息:node belongs to cluster <cluster ID> but is attempting to connect to a gossip network for cluster <another cluster ID>

该消息通常代表节点尝试连接集群,但是该节点已经是另外一个集群的成员。这由节点数据文件夹里的元数据决定。为解决这个问题,尝试以下方式:

cockroach start [flags] --store=[new directory] --join=[cluster host]:26257
rm -r cockroach-data/
cockroach start [flags] --join=[cluster host]:26257

该消息可能在以下场景出现:

  1. 集群启动的第一个节点未使用--joinFlag。
  2. 后续启动的节点使用--joinFlag指向第一个节点。
  3. 停止第一个节点停止,然后删除节点数据文件夹并重启节点,或是指定其他数据文件夹重启节点。上述操作将导致第一个节点初始化一个新的集群。
  4. 其他节点仍然尝试跟第一个节点通讯,但是发现他们的集群ID和第一个节点的集群ID不匹配。

为避免这种情况出现,需要完善脚本,使用以下推荐的新的方式来启动集群:

  1. 启动集群每个最初的节点,使用--joinFlag指定3到5个集群节点。
  2. 使用任意一个节点,执行cockroach init命令来初始化集群。
  3. 当添加新的节点的时候,启动节点时使用--joinFlag指定集群节点。

更多细节详见示例

消息:open file descriptor limit of <number> is under the minimum required <number>

CockroachDB可能使用大量的文件句柄,往往大于默认情况下可用的句柄数量。该消息代表运行CockroachDB节点的机器不满足CockroachDB推荐的设置。

关于CockroachDB文件句柄限制的更多细节,以及如何在各个平台上提高该限制,可以查看文件句柄限制

消息:replicas failing with "0 of 1 store with an attribute matching []; likely not enough nodes in cluster

单节点集群的情况

在单节点集群下,副本复制的错误最终会输出到节点的日志文件,例如:

E160407 09:53:50.337328 storage/queue.go:511  [replicate] 7 replicas failing with "0 of 1 store with an attribute matching []; likely not enough nodes in cluster"

这是由于CockroachDB默认需要3个节点。如果用户不打算添加额外的节点,可以更新默认的复制区域配置,以匹配只有一个节点的集群情况。

#非安全模式集群
cockroach zone set .default --insecure --disable-replication

#安全模式集群
cockroach zone set .default --certs-dir=[path to certs directory] --disable-replication

使用--disable-replicationFlag能够自动地减少复制区域的副本数量到1。 用户还可以选择以下方式设置:

#非安全模式集群
echo 'num_replicas: 1' | cockroach zone set .default --insecure -f -
COPY 
#安全模式集群
echo 'num_replicas: 1' | cockroach zone set .default --certs-dir=[path to certs directory] -f -

更多细节详见配置复制区域

多节点集群

在多节点集群下,如果您发现了关于副本复制的错误,可能是部分节点无法相互之间通信,推荐查看集群配置的问题追踪

消息:clock synchronization error: this node is more than 500ms away from at least half of the known nodes

该错误代表节点因为检测到自己的时间与集群至少一半的节点不同步且偏移超过最大允许偏移量的80%(默认为500毫秒)。CockroachDB需要中等程度的时间同步机制来保持数据的一致性,因此节点为避免一致性异常选择以这种方式关闭。

为解决这个问题,用户需要在每个节点是配置时间同步软件,详见对应方式的部署教程当中的时间同步章节:

开发环境 推荐方式
手动部署 使用配置了Google外部NTP服务的NTP工具。
AWS 使用Amazon时间同步服务。
Azure 关闭Hyper-V时间同步,使用配置了Google外部NTP服务的NTP工具。
Digital Ocean 使用配置了Google外部NTP服务的NTP工具。
GCE 使用配置了Google内部NTP服务的NTP工具。

消息:context deadline exceeded

该消息发生在CockroachDB一个组件放弃操作的时候,因为其所依赖的另一个组件未按预期运行,例如另一个组件丢失网络连接。为进一步调查,需要在节点的日志中查找作为根本原因的主要故障。

消息:result is ambiguous

在分布式系统当中,一些错误可能有含糊的结果。例如在提交COMMIT语句的时候接收到connection closed的错误,此时用户不清楚事务是否真的提交成功。尽管其他数据库也出现这样的错误,但是在CockroachDB更加容易出现。含糊的结果很可能是集群节点之间的错误导致的。该错误返回PostgreeSQL错误码40003statement_completion_unknown)和result is ambiguous消息。

节点崩溃、网络错误、超时可能导致含糊的错误。如果用户在其他事情稳定的情况下遇到很多这样的错误,请查看性能问题。注意含糊结果只会发生在事务的最后一个语句(COMMITRELEASE SAVEPOINT)或是事务以外的语句。如果在尝试提交事务之前连接终端,则事务一定会取消。

通常情况下,用户需要采取跟connection closed错误相同的方式来处理含糊的错误。如果事务是幂等的,那么对于含糊的错误,可以安全地进行重试。UPSERT语句就是一个典型幂等的,也可以通过在执行写操作之前验证预期的状态来将其他事务改写成幂等的。而像是UPDATE my_table SET x=x+1 WHERE id=$1这样的递增操作就属于不容易改造成幂等的。如果您的事务是非幂等的,应该确定应用程序提交事务两次或向用户返回错误=哪种更好,从而来决定是否重试。