Repository navigation
Conversation
Behind a new test-utils feature, Transaction::probe() returns a TransactionProbe that can set the primary key (one the transaction need not write), set an exact lock TTL, prewrite only chosen keys, and commit the primary alone. Nothing it does starts the heartbeat, commits secondaries or rolls back, so dropping the transaction afterwards leaves the locks a crashed client would. It mirrors client-go's CommitterProbe. Without the feature nothing changes. With it, Committer takes an optional lock TTL override; None keeps the computed TTL. Signed-off-by: Eduard Ralph <eduard@ralphovi.net>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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 |
Draft: opened early for testing and review. This is new public API, behind a feature flag.
What
A
test-utilsCargo feature that addsTransaction::probe(), returning aTransactionProbethat drives a transaction's two-phase commit one phase at a time:set_primary_key(key): use this primary, which need not be a key the transaction writes;set_lock_ttl(ms): prewrite with this lock TTL instead of the computed one;prewrite(keys): prewrite only these keys (each must already be written in the transaction), and stop;commit_primary(): commit the primary alone, leaving the secondaries locked.Nothing the probe does starts the heartbeat, commits secondaries or rolls back, so dropping the transaction afterwards leaves exactly the locks a crashed client would.
Safety rules the probe keeps:
commit_primarygoes throughcommit_primary_with_retry, so a commit ts TiKV rejects as too small is retried as incommit().commit_primaryhas sent the commit,rollback()is refused unless TiKV cleanly rejected it: the primary may be durable, and rolling back its secondaries would tear the transaction. A lost answer comes back asUndeterminedError, as fromcommit().Without the feature nothing changes. With it, the only change outside the probe is that
Committertakes an optional lock TTL override;Nonekeeps the computed TTL as before (unit testwithout_the_probe_the_lock_ttl_is_still_computed).Why
client-go exports the same capability from a non-test file (
CommitterProbeintxnkv/transaction/test_probe.go), and its own tests construct lock states with it directly. client-rust has no equivalent: its mocks are#[cfg(test)], so a caller (including this repo's integration tests) cannot build those states without races or compile-time failpoints. For example, an orphaned secondary lock (primary never written) currently needs a region split and a racing transaction to manufacture; with the probe it is:That makes lock-resolution behaviour (#543, fixed in #561) testable deterministically, and the same holds for roll-forward of a committed primary and, later, async-commit locks.
Tests
commit_primarycommits only the primary and closes rollback; a lost commit answer isUndeterminedErrorand keeps rollback closed; a clean rejection leaves rollback open; the normal commit path still computes its TTL.integration-tests+test-utils):txn_probe_leaves_an_orphaned_secondary_lock(scan finds the one orphan lock; after its TTL a reader resolves it as rolled back) andtxn_probe_commit_primary_leaves_the_secondary_to_roll_forward(only the secondary stays locked; a reader rolls it forward).make check,make unit-testandmake integration-test-txnenabletest-utils.Open questions for review
CommitterProbe. Alternatives: methods directly onTransactionbehind the feature, or a probe on the client. Happy to change.CommitterTTL override (no new API), then the feature-gated probe.Transaction::commit()leaves the status atStartedCommitwhen the primary commit is undetermined, so a followingrollback()is allowed there too. The probe closes that for itself; the same change incommit()seems worth its own PR.