Apache Cassandra 3.11中nodetool repair --full与repairedAt时间戳的关系及修复流程问询
嘿,这个问题问到点子上了——很多人都会凭直觉猜错,我来给你梳理清楚实际逻辑:
首先先明确基础行为:Cassandra 3.11默认启用增量修复,不带-full参数的nodetool repair会触发增量修复,完成后会给修复过的SSTables打上repairedAt时间戳;增量修复会更新这个时间戳,但全量修复的实际逻辑和我们直觉里的“全量处理所有数据”有出入。
你一开始的直觉是-full会无视repairedAt标记,但实际情况恰恰相反——根据Datastax的官方说明:
Once an SSTable has a repairedAt timestamp, it is considered repaired and will not be included in subsequent full or subrange repairs, whether run via nodetool or through Reaper/OpsCenter. Only SSTables without a repairedAt timestamp are processed during a non incremental repair. This design avoids re-repairing the same data repeatedly, but it does mean that if incremental repairs were used earlier, the already marked SSTables will be skipped. In such cases, the way to bring everything back under consistent repair is to run nodetool mark_unrepaired on the table and then perform a full/subrange repair again.
换句话说:只要某个SSTable带有repairedAt时间戳,不管你是执行全量修复还是子范围修复(不管用nodetool还是Reaper/OpsCenter这类工具),它都会被判定为已修复而直接跳过,只有没有这个标记的SSTable才会被处理。这个设计是为了避免重复修复相同数据,但也带来了一个问题:如果集群之前用过增量修复,后续的全量修复会自动跳过那些已经打了标记的SSTables,没法真正覆盖所有数据。
如果想要让全量修复真正处理所有数据,保证集群修复状态一致,正确的操作流程是:
- 先对目标表执行
nodetool mark_unrepaired命令,清除所有SSTables上的repairedAt标记 - 之后再执行
nodetool repair -full(或者子范围修复),这样所有数据都会被重新纳入修复流程
内容来源于stack exchange

