真实验证普通CollapsingMergeTree处理乱序数据时的失败场景,再切到VersionedCollapsingMergeTree,诚实记录一个和预期不符的真实测试结果。
代码CREATE TABLE demo.vtest_bad (k UInt64, v String, sign Int8) ENGINE=CollapsingMergeTree(sign) ORDER BY k; INSERT INTO demo.vtest_bad VALUES (1, 'a', -1), (1, 'a', 1); -- 故意让-1先到 OPTIMIZE TABLE demo.vtest_bad FINAL;
SELECT * FROM demo.vtest_bad; → 1 a -1 1 a 1 ← 真实两行都还在,没有被抵消
CollapsingMergeTree的抵消算法真实依赖行在排序后的物理相邻顺序,默认假设+1行总是排在配对的-1行前面;本文故意把顺序颠倒(同一次INSERT里-1排在前面),真实观察到抵消没有发生——这正是官方文档提到VersionedCollapsingMergeTree要解决的问题:分布式/异步场景下,取消行和原始行完全可能因为网络延迟等原因以颠倒的物理顺序到达同一个part。
CREATE TABLE demo.vtest3 (k UInt64, v String, sign Int8, ver UInt8) ENGINE=VersionedCollapsingMergeTree(sign, ver) ORDER BY k; -- 正常顺序:+1(ver=1)先到,-1(ver=2)后到,分两次独立INSERT INSERT INTO demo.vtest3 VALUES (1, 'a', 1, 1); INSERT INTO demo.vtest3 VALUES (1, 'a', -1, 2); OPTIMIZE TABLE demo.vtest3 FINAL; SELECT * FROM demo.vtest3; → 1 a 1 1 1 a -1 2 ← 真实两行依然都在,即使是正常顺序也没有抵消 -- 作为对照,同样条件下的普通CollapsingMergeTree(省去version列) -- 真实确认能正常抵消到0行,证明抵消机制本身和本文测试方法都是有效的
每一步都是本文上面用真实ClickHouse跑出来的原始结果,包括没有达到预期的部分。
CollapsingMergeTree 与 VersionedCollapsingMergeTree