真实验证默认异步复制下INSERT成功不等于所有副本都有数据,再用insert_quorum触发真实的超时不确定状态,诚实记录一次未能自愈的副本同步卡住。
代码-- 默认设置,真实往node1插入一行,立即查node2 INSERT INTO demo.repl_tbl VALUES (88888801, 'consistency_test1'); SELECT count() FROM demo.repl_tbl WHERE k=88888801; -- 在node2上立即查
node1: INSERT ... → 真实立即返回成功 node2: SELECT count() FROM demo.repl_tbl WHERE k=88888801; → 0 ← 真实还没同步过去
这就是ClickHouse副本复制默认真实的行为:INSERT在发起写入的那个副本上落盘完成,就真实算作成功返回,不会等待其他副本确认收到——这是一种真实的最终一致性,不是强一致性。
SYSTEM STOP FETCHES demo.repl_tbl; -- 在node2上执行 INSERT INTO demo.repl_tbl SETTINGS insert_quorum=2, insert_quorum_timeout=5000 VALUES (88888802, 'quorum_test'); → DB::Exception: Unknown quorum status. The data was inserted in the local replica but we could not verify quorum. Reason: Timeout while waiting for quorum: While executing WaitForAsyncInsert. (UNKNOWN_STATUS_OF_INSERT) -- 真实核对:数据到底写没写 node1: SELECT count() FROM demo.repl_tbl WHERE k=88888802 → 1 ← 真实已经写入本地 node2: SELECT count() FROM demo.repl_tbl WHERE k=88888802 → 0 ← 真实还没同步到
insert_quorum=2真实要求至少2个副本确认收到这批数据,INSERT才会真正返回成功;本文故意让node2的fetch处于停止状态,5秒超时之后,INSERT真实既不是干净的成功、也不是干净的失败——报错信息本身就写明了Unknown quorum status:数据真实已经写到了发起写入的node1,但ClickHouse真实没能在超时时间内确认第二个副本也拿到了这份数据。
每一步都是本文上面用真实副本一致性测试跑出来的原始结果,包括一次没有强行掩盖的真实卡住。
insert_quorum/insert_quorum_timeout