Skip to content

scan operations for KvClient not working correctly #677

@FiV0

Description

@FiV0

Bug Report

I am running into issues with the scan operations for the KvClient. Issue that might be related #631

1. Describe the bug

The following two operations don't seem to work correctly for the KvClient
scan(ByteString startKey, long version, int limit)
scan(ByteString startKey, long version)
The former is just calling the later so that is kind of expected.

2. Minimal reproduce step

I added 11 key value pairs to tikv.

(["foo" "bar"] ["foo0" "bar"] ["foo1" "bar"] ["foo2" "bar"] ["foo3" "bar"] ["foo4" "bar"]
 ["foo5" "bar"] ["foo6" "bar"] ["foo7" "bar"] ["foo8" "bar"] ["foo9" "bar"])

scan(ByteString startKey, ByteString endKey, long version) works correctly. What follows is in Clojure but can very likely also be produced in Java.

;; the startKey to endKey version works
(->> (.scan client (ByteString/copyFromUtf8 "foo") (ByteString/copyFromUtf8 "foo5") timestamp)
     (map kv-pair->strings))
;; => (["foo" "bar"] ["foo0" "bar"] ["foo1" "bar"] ["foo2" "bar"] ["foo3" "bar"] ["foo4" "bar"])

(.scan client (ByteString/copyFromUtf8 "foo") timestamp 5)
;; => Execution error (IndexOutOfBoundsException) at org.tikv.common.operation.iterator.ScanIterator/cacheLoadFails (ScanIterator.java:100).
;;    current cache size = 11, larger than 5

;; if I specify a limit larger than the number of available keys nothing gets returned.
(.scan client (ByteString/copyFromUtf8 "foo") timestamp 12)
;; => []
(.scan client (ByteString/copyFromUtf8 "foo") timestamp)
;; => []

Here is the stacktrace for the error from the second invocation:

1. Caused by java.lang.IndexOutOfBoundsException
   current cache size = 11, larger than 5

         ScanIterator.java:  100  org.tikv.common.operation.iterator.ScanIterator/cacheLoadFails
 ConcreteScanIterator.java:  106  org.tikv.common.operation.iterator.ConcreteScanIterator/hasNext
             Iterator.java:  132  java.util.Iterator/forEachRemaining
             KVClient.java:  134  org.tikv.txn.KVClient/scan

I suspect that the bug is in the code at this location:

int scanLimit = Math.min(limit, conf.getScanBatchSize());
if (currentCache.size() < scanLimit) {
startKey = curRegionEndKey;
lastKey = Key.toRawKey(curRegionEndKey);
} else if (currentCache.size() > scanLimit) {
throw new IndexOutOfBoundsException(
"current cache size = " + currentCache.size() + ", larger than " + scanLimit);
} else {
// Start new scan from exact next key in current region
lastKey = Key.toRawKey(currentCache.get(currentCache.size() - 1).getKey());
startKey = lastKey.next().toByteString();
}
// notify last batch if lastKey is greater than or equal to endKey
// if startKey is empty, it indicates +∞
if (hasEndKey && lastKey.compareTo(endKey) >= 0 || startKey.isEmpty()) {
processingLastBatch = true;
startKey = null;

3. What did you see instead

See above.

4. What did you expect to see?

Correct scanning operations as described in the API at https://tikv.github.io/client-java/site/apidocs/index.html.

5. What are your Java Client and TiKV versions?

  • Client Java: 3.3.0
  • TiKV: v6.4.0

I used the tikv setup describe in this tutorial.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions