Risk for enterprise users: Low
Labels: enhancement, feature-gap, area/txnkv
Reference implementations: client-rust src/transaction/snapshot.rs (scan_reverse), client-go txnkv/txnsnapshot/scan.go, client-java org/tikv/common/Snapshot.java
What is missing
Transaction::scan() is forward-only (src/Client/TxnKv/Transaction.php:195); TxnReader::executeScanForRegion() never sets KvScanRequest.reverse (src/Client/TxnKv/TxnReader.php:292). There is no transactional range delete: KvDeleteRange and UnsafeDestroyRange are generated in src/Proto/Tikvpb/TikvClient.php but unused.
How the official clients do it
All three official clients provide reverse scanning on the transactional snapshot: client-rust Snapshot::scan_reverse (src/transaction/snapshot.rs), client-go through its scanner with a reverse flag, client-java via Snapshot. UnsafeDestroyRange is exposed by client-go (tikv/gc.go:347) and client-rust (src/transaction/client.rs:374) as a GC-worker operation.
Impact of not having it
Reverse-ordered transactional reads — "latest N events for this key prefix" is the canonical case — must be emulated by scanning forward and reversing in PHP, which reads the whole range into memory. For a large range this is a memory and latency problem. Range deletion must be done key by key, which for a large range is slow and produces a very large transaction, running straight into GAP-16.
Workaround available today
Scan forward and reverse in application code, accepting the memory cost. For deletion, scan then delete in bounded batches across several transactions, accepting non-atomicity.
Implementation sketch
Reverse scan is a small change: add a $reverse parameter to TxnReader::scan() and executeScanForRegion(), set KvScanRequest.reverse, and iterate regions in reverse order — RegionRangeClipper::clipReverse() already exists and is used by RawKvScanner::reverseScan() (src/Client/RawKv/RawKvScanner.php:90). Range deletion is a separate, more careful piece of work because UnsafeDestroyRange bypasses MVCC and must not be exposed casually.
Effort estimate
Small for reverse scan; Medium for range deletion including safety guards.
Acceptance criteria
Filed from the Feature gaps vs official clients audit (audit-feature-gaps.md), finding GAP-21.
See the consolidated summary for the root-cause grouping this belongs to.
Risk for enterprise users: Low
Labels:
enhancement,feature-gap,area/txnkvReference implementations: client-rust
src/transaction/snapshot.rs(scan_reverse), client-gotxnkv/txnsnapshot/scan.go, client-javaorg/tikv/common/Snapshot.javaWhat is missing
Transaction::scan()is forward-only (src/Client/TxnKv/Transaction.php:195);TxnReader::executeScanForRegion()never setsKvScanRequest.reverse(src/Client/TxnKv/TxnReader.php:292). There is no transactional range delete:KvDeleteRangeandUnsafeDestroyRangeare generated insrc/Proto/Tikvpb/TikvClient.phpbut unused.How the official clients do it
All three official clients provide reverse scanning on the transactional snapshot: client-rust
Snapshot::scan_reverse(src/transaction/snapshot.rs), client-go through its scanner with a reverse flag, client-java viaSnapshot.UnsafeDestroyRangeis exposed by client-go (tikv/gc.go:347) and client-rust (src/transaction/client.rs:374) as a GC-worker operation.Impact of not having it
Reverse-ordered transactional reads — "latest N events for this key prefix" is the canonical case — must be emulated by scanning forward and reversing in PHP, which reads the whole range into memory. For a large range this is a memory and latency problem. Range deletion must be done key by key, which for a large range is slow and produces a very large transaction, running straight into GAP-16.
Workaround available today
Scan forward and reverse in application code, accepting the memory cost. For deletion, scan then delete in bounded batches across several transactions, accepting non-atomicity.
Implementation sketch
Reverse scan is a small change: add a
$reverseparameter toTxnReader::scan()andexecuteScanForRegion(), setKvScanRequest.reverse, and iterate regions in reverse order —RegionRangeClipper::clipReverse()already exists and is used byRawKvScanner::reverseScan()(src/Client/RawKv/RawKvScanner.php:90). Range deletion is a separate, more careful piece of work becauseUnsafeDestroyRangebypasses MVCC and must not be exposed casually.Effort estimate
Small for reverse scan; Medium for range deletion including safety guards.
Acceptance criteria
Transaction::scan()accepts a reverse flag with bound semantics matchingRawKvClient::reverseScan().Filed from the Feature gaps vs official clients audit (
audit-feature-gaps.md), finding GAP-21.See the consolidated summary for the root-cause grouping this belongs to.