From 04ac08d49b8062bc0f2032d1b70a496016504b27 Mon Sep 17 00:00:00 2001 From: huaxiangsun Date: Wed, 6 May 2020 09:50:52 -0700 Subject: [PATCH] HBASE-24273 HBCK's "Orphan Regions on FileSystem" reports regions with referenced HFiles (#1613) (#1661) Signed-off-by: stack --- .../apache/hadoop/hbase/master/HbckChore.java | 36 ++++++++++++++++--- .../hadoop/hbase/master/TestMetaFixer.java | 10 ++++-- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java index b25bb152988e..6d41008c74f4 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java @@ -28,6 +28,7 @@ import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.MetaTableAccessor; import org.apache.hadoop.hbase.ScheduledChore; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.client.RegionInfo; @@ -134,7 +135,7 @@ protected synchronized void chore() { loadRegionsFromInMemoryState(); loadRegionsFromRSReport(); try { - loadRegionsFromFS(); + loadRegionsFromFS(scanForMergedParentRegions()); } catch (IOException e) { LOG.warn("Failed to load the regions from filesystem", e); } @@ -187,6 +188,31 @@ private void saveCheckResultToSnapshot() { } } + /** + * Scan hbase:meta to get set of merged parent regions, this is a very heavy scan. + * + * @return Return generated {@link HashSet} + */ + private HashSet scanForMergedParentRegions() throws IOException { + HashSet mergedParentRegions = new HashSet<>(); + // Null tablename means scan all of meta. + MetaTableAccessor.scanMetaForTableRegions(this.master.getConnection(), + r -> { + List mergeParents = MetaTableAccessor.getMergeRegions(r.rawCells()); + if (mergeParents != null) { + for (RegionInfo mergeRegion : mergeParents) { + if (mergeRegion != null) { + // This region is already being merged + mergedParentRegions.add(mergeRegion.getEncodedName()); + } + } + } + return true; + }, + null); + return mergedParentRegions; + } + private void loadRegionsFromInMemoryState() { List regionStates = master.getAssignmentManager().getRegionStates().getRegionStates(); @@ -256,7 +282,7 @@ private void loadRegionsFromRSReport() { } } - private void loadRegionsFromFS() throws IOException { + private void loadRegionsFromFS(final HashSet mergedParentRegions) throws IOException { Path rootDir = master.getMasterFileSystem().getRootDir(); FileSystem fs = master.getMasterFileSystem().getFileSystem(); @@ -271,12 +297,12 @@ private void loadRegionsFromFS() throws IOException { continue; } HbckRegionInfo hri = regionInfoMap.get(encodedRegionName); - if (hri == null) { + // If it is not in in-memory database and not a merged region, + // report it as an orphan region. + if (hri == null && !mergedParentRegions.contains(encodedRegionName)) { orphanRegionsOnFS.put(encodedRegionName, regionDir); continue; } - HbckRegionInfo.HdfsEntry hdfsEntry = new HbckRegionInfo.HdfsEntry(regionDir); - hri.setHdfsEntry(hdfsEntry); } numRegions += regionDirs.size(); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaFixer.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaFixer.java index f1531a5e8906..ee671109f962 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaFixer.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaFixer.java @@ -31,6 +31,7 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.RegionInfo; import org.apache.hadoop.hbase.client.RegionInfoBuilder; +import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.master.assignment.GCRegionProcedure; import org.apache.hadoop.hbase.testclassification.LargeTests; import org.apache.hadoop.hbase.testclassification.MasterTests; @@ -147,10 +148,12 @@ private static void makeOverlap(MasterServices services, RegionInfo a, RegionInf @Test public void testOverlap() throws Exception { TableName tn = TableName.valueOf(this.name.getMethodName()); - TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY); + Table t = TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY); + TEST_UTIL.loadTable(t, HConstants.CATALOG_FAMILY); List ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn); assertTrue(ris.size() > 5); - MasterServices services = TEST_UTIL.getHBaseCluster().getMaster(); + HMaster services = TEST_UTIL.getHBaseCluster().getMaster(); + HbckChore hbckChore = services.getHbckChore(); services.getCatalogJanitor().scan(); CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport(); assertTrue(report.isEmpty()); @@ -174,6 +177,9 @@ public void testOverlap() throws Exception { throw new RuntimeException(e); } }); + + hbckChore.chore(); + assertEquals(0, hbckChore.getOrphanRegionsOnFS().size()); } /**