From 107553267c8c508bd09a67fddb2e122240baa424 Mon Sep 17 00:00:00 2001 From: liuxiaocs7 Date: Tue, 15 Sep 2026 16:56:36 +0800 Subject: [PATCH 1/2] HBASE-30381 MOB snapshot scanning fails on branch-2.5 after HBASE-29662 --- .../TableSnapshotInputFormatImpl.java | 6 +++++ .../hbase/client/TableSnapshotScanner.java | 6 +++++ .../client/TestTableSnapshotScanner.java | 26 +++++++++++++++++++ 3 files changed, 38 insertions(+) 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 f8fa1f6294c5..a954fa5d2564 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 @@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.client.Scan.ReadType; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; +import org.apache.hadoop.hbase.mob.MobUtils; import org.apache.hadoop.hbase.regionserver.HRegion; import org.apache.hadoop.hbase.snapshot.RestoreSnapshotHelper; import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils; @@ -361,6 +362,11 @@ public static List getRegionInfosFromManifest(SnapshotManifest mani if (hri.isOffline() && (hri.isSplit() || hri.isSplitParent())) { 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. See HBASE-30381. + if (MobUtils.isMobRegionInfo(hri)) { + continue; + } regionInfos.add(hri); } return regionInfos; 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 9e01e34877c4..7a077cbdb242 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 @@ -27,6 +27,7 @@ import org.apache.hadoop.hbase.HRegionInfo; 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-30381. + 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 8accaba836fd..4fd2ae92a121 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.HRegion; import org.apache.hadoop.hbase.regionserver.HRegionFileSystem; import org.apache.hadoop.hbase.regionserver.HRegionServer; +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(HBaseTestingUtility util, String snapshotName, int numRegions, boolean shutdownCluster) throws Exception { TableName tableName = TableName.valueOf("testScanner"); From 6d70b78fe51beaaa82c4de6fccc5e7651a9364f4 Mon Sep 17 00:00:00 2001 From: liuxiaocs7 Date: Tue, 15 Sep 2026 21:10:06 +0800 Subject: [PATCH 2/2] update --- .../java/org/apache/hadoop/hbase/mapreduce/TestCopyTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestCopyTable.java b/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestCopyTable.java index e072420c0c4a..68899450f694 100644 --- a/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestCopyTable.java +++ b/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestCopyTable.java @@ -244,7 +244,7 @@ public void testLoadingTtlExpiredSnapshotToTable() throws Exception { } @Test - public void tsetLoadingSnapshotToMobTable() throws Exception { + public void testLoadingSnapshotToMobTable() throws Exception { testCopyTableBySnapshot("testLoadingSnapshotToMobTable", false, true); }