diff --git a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableSnapshotInputFormatImpl.java b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableSnapshotInputFormatImpl.java index e44d003cf5b6..405dd4d94257 100644 --- a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableSnapshotInputFormatImpl.java +++ b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableSnapshotInputFormatImpl.java @@ -363,7 +363,7 @@ public static List getRegionInfosFromManifest(SnapshotManifest manif continue; } // The mob region is a dummy region used only to organise mob files under mobdir. It has no - // region directory under the table dir to open, and holds no rows. See HBASE-30365. + // region directory under the table dir to open. See HBASE-30365. if (MobUtils.isMobRegionInfo(hri)) { continue; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/TableSnapshotScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/TableSnapshotScanner.java index 41bd0bd988bc..7e17d6303fdc 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/TableSnapshotScanner.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/TableSnapshotScanner.java @@ -26,6 +26,7 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.PrivateCellUtil; import org.apache.hadoop.hbase.client.metrics.ScanMetrics; +import org.apache.hadoop.hbase.mob.MobUtils; import org.apache.hadoop.hbase.regionserver.MemStoreLAB; import org.apache.hadoop.hbase.snapshot.RestoreSnapshotHelper; import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils; @@ -160,6 +161,11 @@ private boolean isValidRegion(RegionInfo hri) { if (hri.isOffline() && (hri.isSplit() || hri.isSplitParent())) { return false; } + // The mob region is a dummy region used only to organise mob files under mobdir. It has no + // region directory under the table dir to open. See HBASE-30365 and HBASE-30368. + if (MobUtils.isMobRegionInfo(hri)) { + return false; + } return PrivateCellUtil.overlappingKeys(scan.getStartRow(), scan.getStopRow(), hri.getStartKey(), hri.getEndKey()); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestTableSnapshotScanner.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestTableSnapshotScanner.java index 4b835719ecef..09663c910370 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestTableSnapshotScanner.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestTableSnapshotScanner.java @@ -49,6 +49,7 @@ import org.apache.hadoop.hbase.regionserver.StoreContext; import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTracker; import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory; +import org.apache.hadoop.hbase.snapshot.MobSnapshotTestingUtils; import org.apache.hadoop.hbase.snapshot.RestoreSnapshotHelper; import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils; import org.apache.hadoop.hbase.testclassification.ClientTests; @@ -370,6 +371,31 @@ public void testScannerWithRestoreScanner() throws Exception { } } + @Test + public void testScannerWithRestoredMobSnapshot() throws Exception { + TableName tableName = TableName.valueOf(methodName); + String snapshotName = methodName + "Snapshot"; + Path restoreDir = UTIL.getDataTestDirOnTestFS(snapshotName); + try { + MobSnapshotTestingUtils.createMobTable(UTIL, tableName, new byte[0][], 1, FAMILIES); + try (Table table = UTIL.getConnection().getTable(tableName)) { + UTIL.loadTable(table, FAMILIES); + } + UTIL.getAdmin().snapshot(snapshotName, tableName); + + Configuration conf = UTIL.getConfiguration(); + RestoreSnapshotHelper.copySnapshotForScanner(conf, fs, rootDir, restoreDir, snapshotName); + try (TableSnapshotScanner scanner = new TableSnapshotScanner(conf, rootDir, restoreDir, + snapshotName, new Scan().withStartRow(Bytes.toBytes("zzzz")), true)) { + assertNull(scanner.next()); + } + } finally { + fs.delete(restoreDir, true); + UTIL.getAdmin().deleteSnapshot(snapshotName); + UTIL.deleteTable(tableName); + } + } + private void testScanner(HBaseTestingUtil util, String snapshotName, int numRegions, boolean shutdownCluster) throws Exception { TableName tableName = TableName.valueOf("testScanner");