tikv/tikv · critical

cannot resolve the conflict {} for key {}

Error message

cannot resolve the conflict {} for key {}

What it means

This panic comes from the log-backup subcompaction conflict resolver in compact-log-backup. When two different records share the same user key in the write CF, `resolve` tries to order them via a partial ordering over WriteRef (overlapped-rollback Puts/Rollbacks, protected Rollbacks). If the write types fall into a combination with no comparison rule, `partial_cmp` returns `None` and TiKV panics rather than silently picking a winner, because choosing the wrong record could corrupt transactional data.

Source

Thrown at components/compact-log-backup/src/compaction/exec.rs:194

                (Rollback | Put, Put) if wb.has_overlapped_rollback => Some(Ordering::Less),

                // Rollback -> Protected Rollback.
                // Keep the protected one.
                // This was observed in some versions and shouldn't happen normally.
                (Rollback, Rollback) if wa.is_protected() => Some(Ordering::Greater),
                (Rollback, Rollback) if wb.is_protected() => Some(Ordering::Less),

                // No comparing rule here.
                _ => None,
            }
        };

        sanity_check(&wa, &wb);
        let maybe_ord = partial_cmp(&wa, &wb);
        info!("resolve conflict result."; "conflict_id" => cid, "order" => ?maybe_ord);
        match maybe_ord {
            Some(Ordering::Greater) => std::mem::swap(a, b),
            None => panic!(
                "cannot resolve the conflict {} for key {}",
                cid,
                redact(&a.key)
            ),

            Some(_) => {}
        }
    }

    fn update_checksum_diff(
        c: &Subcompaction,
        a: &mut Record,
        b: &mut Record,
        diff: &mut ChecksumDiff,
    ) {
        Self::resolve(c, a, b);

        diff.removed_key += 1;

View on GitHub (pinned to 78aedc1c81)

Solutions

  1. Capture the log with the key (redacted) and conflict_id and report to TiKV — this indicates data shapes the resolver doesn't know
  2. Pin/upgrade to a TiKV version whose `partial_cmp` in components/compact-log-backup/src/compaction/exec.rs covers the offending write-type pair
  3. Exclude the affected log-backup segment from compaction until the resolver is patched (limit compaction range to avoid the conflicting key range)
  4. Verify backup data integrity: check the SSTs in the involved subcompaction for corruption or manual modification

Example fix

// before (resolver has no rule for the pair)
(Rollback, Rollback) if wa.is_protected() => Some(Ordering::Greater),
// after (add the missing rule, e.g. keep newer/protected rollback)
(Rollback, Rollback) if wb.is_protected() => Some(Ordering::Less),
(Rollback, Delete) => Some(Ordering::Less),
Defensive patterns

Strategy: validation

Validate before calling

// Before running subcompactions over a range, inspect write-CF record pairs
fn resolvable(wa: &WriteRef, wb: &WriteRef) -> bool {
    use WriteType::*;
    matches!(
        (wa.write_type, wb.write_type),
        (Put, Rollback | Put) | (Rollback, Put) | (Rollback, Rollback)
    )
}

Type guard

fn has_comparison_rule(w: &WriteRef) -> bool {
    use WriteType::*;
    matches!(w.write_type, Put | Rollback)
}

Prevention

When it happens

Trigger: Running PITR log-backup subcompactions where two input SSTs contain conflicting write-CF records for the same key whose write types don't match any known rule (e.g. a Delete vs a plain Rollback, or two non-protected Rollbacks with different content), typically caused by records written by older TiKV versions or by a bug upstream.

Common situations: Log backup compaction after restoring from backup taken with an older TiKV; data written during versions that produced non-protected rollbacks or collapsed-rollback patterns the resolver doesn't recognize; corrupted or externally-modified backup SST files.

Related errors


AI-assisted analysis of tikv/tikv@78aedc1c81 (2026-09-03). Data as JSON: /api/errors/8f53ce4b15a3e545. Report an issue: GitHub.