From 31bee2ad86f0fe217116f1677a06789179421a26 Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Wed, 24 Jan 2018 03:34:45 +0900 Subject: [PATCH] HBASE-19850 The number of Offline Regions is wrong after restoring a snapshot --- .../master/snapshot/RestoreSnapshotHandler.java | 35 +++++++++++++++++++++- .../client/TestRestoreSnapshotFromClient.java | 27 +++++++++++++++-- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/RestoreSnapshotHandler.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/RestoreSnapshotHandler.java index f9aea13..5f4357f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/RestoreSnapshotHandler.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/RestoreSnapshotHandler.java @@ -34,6 +34,7 @@ import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.MetaTableAccessor; import org.apache.hadoop.hbase.client.Connection; +import org.apache.hadoop.hbase.client.RegionReplicaUtil; import org.apache.hadoop.hbase.errorhandling.ForeignException; import org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher; import org.apache.hadoop.hbase.executor.EventType; @@ -154,6 +155,9 @@ public class RestoreSnapshotHandler extends TableEventHandler implements Snapsho if (metaChanges.hasRegionsToRemove()) hrisToRemove.addAll(metaChanges.getRegionsToRemove()); MetaTableAccessor.deleteRegions(conn, hrisToRemove); + // We also need to remove the current set of regions from in memory states + deleteRegionsFromInMemoryStates(hrisToRemove, hTableDescriptor.getRegionReplication()); + // 4.2 Add the new set of regions to META // // At this point the old regions are no longer present in META. @@ -175,7 +179,6 @@ public class RestoreSnapshotHandler extends TableEventHandler implements Snapsho RestoreSnapshotHelper.restoreSnapshotACL(snapshot, tableName, server.getConfiguration()); } - // At this point the restore is complete. Next step is enabling the table. LOG.info("Restore snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) + " on table=" + tableName + " completed!"); @@ -205,6 +208,36 @@ public class RestoreSnapshotHandler extends TableEventHandler implements Snapsho } } + /** + * Delete regions from in-memory states + * @param regionInfos regions to delete + * @param regionReplication the number of region replications + */ + private void deleteRegionsFromInMemoryStates(List regionInfos, + int regionReplication) { + // Delete the regions from AssignmentManager + for (HRegionInfo hri : regionInfos) { + masterServices.getAssignmentManager().getRegionStates().deleteRegion(hri); + } + // Delete the regions from ServerManager + masterServices.getServerManager().removeRegions(regionInfos); + + // For region replicas + if (regionReplication > 1) { + for (HRegionInfo regionInfo : regionInfos) { + for (int i = 1; i < regionReplication; i++) { + HRegionInfo regionInfoForReplica = + RegionReplicaUtil.getRegionInfoForReplica(regionInfo, i); + // Delete the regions from AssignmentManager + masterServices.getAssignmentManager().getRegionStates() + .deleteRegion(regionInfoForReplica); + // Delete the regions from ServerManager + masterServices.getServerManager().removeRegion(regionInfoForReplica); + } + } + } + } + @Override protected void completed(final Throwable exception) { this.stopped = true; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java index d5ef6e2..99f257c 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java @@ -39,6 +39,7 @@ import org.apache.hadoop.hbase.MetaTableAccessor; import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver; import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; +import org.apache.hadoop.hbase.master.RegionState; import org.apache.hadoop.hbase.regionserver.InternalScanner; import org.apache.hadoop.hbase.regionserver.ScanType; import org.apache.hadoop.hbase.regionserver.Store; @@ -47,7 +48,6 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.Waiter; import org.apache.hadoop.hbase.master.AssignmentManager; import org.apache.hadoop.hbase.master.MasterFileSystem; -import org.apache.hadoop.hbase.master.RegionState; import org.apache.hadoop.hbase.master.snapshot.SnapshotManager; import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException; import org.apache.hadoop.hbase.snapshot.CorruptedSnapshotException; @@ -384,8 +384,7 @@ public class TestRestoreSnapshotFromClient { } public static class DelayCompactionObserver extends BaseRegionObserver { - @Override - public InternalScanner preCompact(ObserverContext e, + @Override public InternalScanner preCompact(ObserverContext e, final Store store, final InternalScanner scanner, final ScanType scanType) throws IOException { @@ -400,6 +399,28 @@ public class TestRestoreSnapshotFromClient { } } + @Test + public void testOfflineRegionsShouldBeZeroAfterRestoreSnapshot() throws IOException, + InterruptedException { + // Load more data to split regions + SnapshotTestingUtils.loadData(TEST_UTIL, tableName, 2000, FAMILY); + + // Split regions + List regions = admin.getTableRegions(tableName); + RegionReplicaUtil.removeNonDefaultRegions(regions); + splitRegion(regions.get(0)); + + // Restore the snapshot + admin.disableTable(tableName); + admin.restoreSnapshot(snapshotName0); + admin.enableTable(tableName); + + int offlineRegions = TEST_UTIL.getHBaseCluster().getMaster().getAssignmentManager() + .getRegionStates().getRegionByStateOfTable(tableName).get(RegionState.State.OFFLINE).size(); + + assertEquals(0, offlineRegions); + } + // ========================================================================== // Helpers // ========================================================================== -- 2.10.1 (Apple Git-78)