diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java index 736c08ab039..e7a4528bd1a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java @@ -802,12 +802,16 @@ public class StoreScanner extends NonReversedNonLazyKeyValueScanner @VisibleForTesting protected boolean trySkipToNextRow(Cell cell) throws IOException { Cell nextCell = null; + // used to guard against a changed next indexed key by doing a identity comparison + // when the identity changes we need to compare the bytes again + Cell previousIndexedKey = null; do { Cell nextIndexedKey = getNextIndexedKey(); if (nextIndexedKey != null && nextIndexedKey != KeyValueScanner.NO_NEXT_INDEXED_KEY - && matcher.compareKeyForNextRow(nextIndexedKey, cell) >= 0) { + && (nextIndexedKey == previousIndexedKey || matcher.compareKeyForNextRow(nextIndexedKey, cell) >= 0)) { this.heap.next(); ++kvsScanned; + previousIndexedKey = nextIndexedKey; } else { return false; } @@ -823,12 +827,16 @@ public class StoreScanner extends NonReversedNonLazyKeyValueScanner @VisibleForTesting protected boolean trySkipToNextColumn(Cell cell) throws IOException { Cell nextCell = null; + // used to guard against a changed next indexed key by doing a identity comparison + // when the identity changes we need to compare the bytes again + Cell previousIndexedKey = null; do { Cell nextIndexedKey = getNextIndexedKey(); if (nextIndexedKey != null && nextIndexedKey != KeyValueScanner.NO_NEXT_INDEXED_KEY - && matcher.compareKeyForNextColumn(nextIndexedKey, cell) >= 0) { + && (nextIndexedKey == previousIndexedKey || matcher.compareKeyForNextColumn(nextIndexedKey, cell) >= 0)) { this.heap.next(); ++kvsScanned; + previousIndexedKey = nextIndexedKey; } else { return false; }