diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java index b18ba40cae0..a0a00b729bb 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java @@ -323,7 +323,11 @@ public class ScanQueryMatcher { || kv.getMemstoreTS() > maxReadPointToTrackVersions) { // always include or it is not time yet to check whether it is OK // to purge deltes or not - return MatchCode.INCLUDE; + if (!isUserScan) { + // if this is not a user scan (compaction), we can filter this deletemarker right here + // otherwise (i.e. a "raw" scan) we fall through to normal version and timerange checking + return MatchCode.INCLUDE; + } } else if (keepDeletedCells) { if (timestamp < earliestPutTs) { // keeping delete rows, but there are no puts older than diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestKeepDeletes.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestKeepDeletes.java index ed2274a5e78..f4f3b34222b 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestKeepDeletes.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestKeepDeletes.java @@ -318,12 +318,55 @@ public class TestKeepDeletes extends HBaseTestCase { InternalScanner scan = region.getScanner(s); List kvs = new ArrayList(); scan.next(kvs); + assertEquals(8, kvs.size()); assertTrue(kvs.get(0).isDeleteFamily()); assertEquals(kvs.get(1).getValue(), T3); assertTrue(kvs.get(2).isDelete()); assertTrue(kvs.get(3).isDeleteType()); assertEquals(kvs.get(4).getValue(), T2); assertEquals(kvs.get(5).getValue(), T1); + // we have 3 CFs, so there are two more delete markers + assertTrue(kvs.get(6).isDeleteFamily()); + assertTrue(kvs.get(7).isDeleteFamily()); + + // verify that raw scans honor the passed timerange + s = new Scan(); + s.setRaw(true); + s.setMaxVersions(); + s.setTimeRange(0, 1); + scan = region.getScanner(s); + kvs = new ArrayList(); + scan.next(kvs); + // nothing in this interval, not even delete markers + assertTrue(kvs.isEmpty()); + + // filter new delete markers + s = new Scan(); + s.setRaw(true); + s.setMaxVersions(); + s.setTimeRange(0, ts+2); + scan = region.getScanner(s); + kvs = new ArrayList(); + scan.next(kvs); + assertEquals(4, kvs.size()); + assertTrue(kvs.get(0).isDeleteFamily()); + assertEquals(kvs.get(1).getValue(), T1); + // we have 3 CFs + assertTrue(kvs.get(2).isDeleteFamily()); + assertTrue(kvs.get(3).isDeleteFamily()); + + // filter old delete markers + s = new Scan(); + s.setRaw(true); + s.setMaxVersions(); + s.setTimeRange(ts+3, ts+5); + scan = region.getScanner(s); + kvs = new ArrayList(); + scan.next(kvs); + assertEquals(2, kvs.size()); + assertEquals(kvs.get(0).getValue(), T3); + assertTrue(kvs.get(1).isDelete()); + HRegion.closeHRegion(region); }