From 333f72864fad023579d31bc1fc51b888d0299d4e Mon Sep 17 00:00:00 2001 From: Pankaj Kumar Date: Thu, 7 Dec 2017 00:04:55 +0530 Subject: [PATCH] HBASE-19281, Snapshot creation failed after splitting table (replica region > 1) --- .../snapshot/EnabledTableSnapshotHandler.java | 5 ++- .../hbase/client/TestSnapshotFromClient.java | 47 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/EnabledTableSnapshotHandler.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/EnabledTableSnapshotHandler.java index 81a3bb4..d129912 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/EnabledTableSnapshotHandler.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/EnabledTableSnapshotHandler.java @@ -25,6 +25,7 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.classification.InterfaceAudience; +import org.apache.hadoop.hbase.client.RegionReplicaUtil; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.errorhandling.ForeignException; @@ -98,7 +99,9 @@ public class EnabledTableSnapshotHandler extends TakeSnapshotHandler { // Take the offline regions as disabled for (Pair region : regions) { HRegionInfo regionInfo = region.getFirst(); - if (regionInfo.isOffline() && (regionInfo.isSplit() || regionInfo.isSplitParent())) { + // Take snapshot of primary regions only + if (regionInfo.isOffline() && RegionReplicaUtil.isDefaultReplica(regionInfo) + && (regionInfo.isSplit() || regionInfo.isSplitParent())) { LOG.info("Take disabled snapshot of offline region=" + regionInfo); snapshotDisabledRegion(regionInfo); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotFromClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotFromClient.java index 541cb89..9cd70a7 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotFromClient.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotFromClient.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -31,14 +32,19 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.MetaTableAccessor; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription; import org.apache.hadoop.hbase.testclassification.LargeTests; import org.apache.hadoop.hbase.TableNotFoundException; +import org.apache.hadoop.hbase.Waiter; +import org.apache.hadoop.hbase.master.AssignmentManager; +import org.apache.hadoop.hbase.master.RegionState; import org.apache.hadoop.hbase.master.snapshot.SnapshotManager; import org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy; +import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException; import org.apache.hadoop.hbase.snapshot.SnapshotCreationException; import org.apache.hadoop.hbase.snapshot.SnapshotDoesNotExistException; import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils; @@ -453,4 +459,45 @@ public class TestSnapshotFromClient { } } } + + @Test(timeout = 300000) + public void testCreateSnapshotAfterTableRegionSplit() throws Exception { + Admin admin = null; + try { + admin = UTIL.getHBaseAdmin(); + final int regionReplication = admin.getTableDescriptor(TABLE_NAME).getRegionReplication(); + final int primaryregionCountBeforeSplit = MetaTableAccessor + .getTableRegions(UTIL.getZooKeeperWatcher(), UTIL.getConnection(), TABLE_NAME).size() + / regionReplication; + // Split the table region + admin.split(TABLE_NAME, "m".getBytes()); + // Wait for replica region to become online + UTIL.waitFor(60000, 500, new Waiter.Predicate() { + @Override + public boolean evaluate() throws IOException { + AssignmentManager am = UTIL.getHBaseCluster().getMaster().getAssignmentManager(); + return am.getRegionStates().getRegionByStateOfTable(TABLE_NAME) + .get(RegionState.State.OPEN) + .size() == ((primaryregionCountBeforeSplit + 1) * regionReplication); + } + }); + + try { + // Create snapshot after table split + admin.snapshot("testCreateSnapshotAfterTableRegionSplit-snap", TABLE_NAME); + assertEquals(1, admin.listTableSnapshots("test.*", ".*").size()); + } catch (HBaseSnapshotException e) { + fail("Snapshot creation failed for table with replica regions" + e); + } + admin.deleteTableSnapshots("test.*", "testCreateSnapshotAfterTableRegionSplit-snap*"); + } finally { + if (admin != null) { + try { + admin.deleteTableSnapshots("test.*", ".*"); + } catch (SnapshotDoesNotExistException ignore) { + } + admin.close(); + } + } + } } -- 2.7.2.windows.1