transaction: resolve orphaned locks whose primary was never written - #544
transaction: resolve orphaned locks whose primary was never written#544eduralph wants to merge 7 commits into
Conversation
|
Welcome @eduralph! |
📝 WalkthroughWalkthrough
ChangesTransaction status error handling
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
check_txn_status matched only ExtractedErrors, but its plan delivers per-key errors as MultipleKeyErrors, so the rollback_if_not_exist escalation in get_txn_status_from_lock was unreachable and an orphaned secondary lock poisoned its key permanently. Accept both wrappers. Refs tikv#531 Signed-off-by: Eduard Ralph <eduard@ralphovi.net>
Add a regression test for the MultipleKeyErrors fix: an expired lock whose
primary was never written must escalate to rollback_if_not_exist and resolve,
rather than surfacing the raw error. The test asserts the two CheckTxnStatus
calls and fails on the pre-fix code with MultipleKeyErrors([KeyError { .. }]).
Also correct the new comment: the key errors are produced by
single_shard_handler, not single_plan_handler, and name CollectSingle as the
reason this call site differs from the plans that never see MultipleKeyErrors.
Refs tikv#531
Signed-off-by: Eduard Ralph <eduard@ralphovi.net>
0902af0 to
f6cf433
Compare
|
@ekexium to raise awareness |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ekexium The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
[LGTM Timeline notifier]Timeline:
|
|
@pingyu - we're 1 LGTM away from getting this merged |
|
How about replacing It seems that the other interfaces have the same issue, and it could introduce potential bugs into future code. p.s. Removing |
|
Agreed, and I think the diagnosis is sharper than "the other interfaces have the same issue" — the two variants aren't just redundant, which one you get is decided by plan shape, invisibly, at a distance.
That coupling is already visible in the public raw API, for the same class of failure:
So a caller matching On the internal side I went through the four places that match So yes to One request on sequencing: could this land as a follow-up rather than in this PR? This one is a two-line match-arm widening for a live bug — an orphaned lock whose primary was never written currently poisons its key forever — and it's already approved. The refactor is a breaking change touching the error enum, both producer sites, and every consumer, and it deserves its own review rather than riding in on a bug fix. Happy to open that PR — I'd plan to introduce |
|
Put it up as #557 (draft, stacked on this branch) so it is concrete rather than hypothetical. It removes One thing worth your eye, since it is the least obvious part: Marked draft because it is stacked; happy to rebase it onto master once this one lands, or to fold it |
6f0e69b to
7a6baf2
Compare
…ants Brings tikv#544's branch tip — and with it all of upstream master, including tikv#555 (undetermined apply outcome terminal at commit points), tikv#554 (paginated range scanner) and tikv#562 (follower fallback) — under this PR's split of `ExtractedErrors`. Conflict: src/request/plan.rs, four hunks, all of them two sides appending at the same place. - `is_response_error` (this PR) and `is_undetermined_region_error` (tikv#555) were added at the same point in the file. Both kept; they classify different things and share no call site. - Three hunks of test-module additions collided at the same append point: this PR's FailingPlan / RegionErrPlan / RawErrPlan against tikv#555's UndeterminedPlan / MaskingPlan. All kept. One resolution decision worth naming: tikv#555 added `terminal_on_undetermined` and `terminal_on_dispatch_error` to `RetryableMultiRegion`, so this PR's `retryable()` test helper no longer compiled. Both are set `false` — the ordinary `retry_multi_region` defaults. `FailingPlan` only ever answers with a key or a region error, never an undetermined apply outcome or a dispatch failure, so neither opt-in is reachable from those tests; what they pin is the error CLASS `ExtractError` reports, which is orthogonal to the terminal policy. The three sites this PR rewrites (`ExtractError::execute`, `CleanupLocks`'s error arms, and the `resolve_lock_with_retry` arm) were untouched by the incoming side, so their resolution is this PR's version unchanged. Against tikv#544's tip the merge is exactly this PR's own four-file delta and nothing else. Verified: cargo check/fmt/clippy -D warnings clean; 107 lib + 50 doc tests; 27 integration, 8 failpoint and 28 sync-transaction tests green against a local api-v2 TiKV v8.5.5 (client-rust's own config/tikv.toml).
check_txn_status matched only ExtractedErrors, but its plan delivers per-key errors as MultipleKeyErrors, so the Rollback_if_not_exist escalation in get_txn_status_from_lock was unreachable and an orphaned secondary lock poisoned its key permanently. Accept both wrappers.
Closes #543
Signed-off-by: Eduard Ralph eduard@ralphovi.net
Summary by CodeRabbit