diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java index 4ce1db3..3a02bdb 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java @@ -406,6 +406,7 @@ public class RegionStates { regionsInTransition.put(encodedName, regionState); } if (lastHost != null && newState != State.SPLIT) { + addToReplicaMapping(hri); addToServerHoldings(lastHost, hri); if (newState != State.OPEN) { oldAssignments.put(encodedName, lastHost); diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailoverBalancerPersistence.java hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailoverBalancerPersistence.java index edecfdd..4d21e0d 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailoverBalancerPersistence.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailoverBalancerPersistence.java @@ -18,23 +18,53 @@ */ package org.apache.hadoop.hbase.master; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.hadoop.hbase.ClusterStatus; import org.apache.hadoop.hbase.HBaseTestingUtility; + +import org.apache.hadoop.hbase.HRegionInfo; +import org.apache.hadoop.hbase.HRegionLocation; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.RegionLocator; import org.apache.hadoop.hbase.testclassification.LargeTests; +import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.MasterNotRunningException; import org.apache.hadoop.hbase.MiniHBaseCluster; import org.apache.hadoop.hbase.util.JVMClusterUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import java.util.Map; @Category(LargeTests.class) public class TestMasterFailoverBalancerPersistence { + // Start the cluster + private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static MiniHBaseCluster cluster; + + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TEST_UTIL.startMiniCluster(4, 1); + cluster = TEST_UTIL.getHBaseCluster(); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + /** * Test that if the master fails, the load balancer maintains its @@ -44,14 +74,6 @@ public class TestMasterFailoverBalancerPersistence { */ @Test(timeout = 240000) public void testMasterFailoverBalancerPersistence() throws Exception { - final int NUM_MASTERS = 3; - final int NUM_RS = 1; - - // Start the cluster - HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); - - TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS); - MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); assertTrue(cluster.waitForActiveAndReadyMaster()); HMaster active = cluster.getMaster(); @@ -74,9 +96,57 @@ public class TestMasterFailoverBalancerPersistence { // ensure the load balancer is not running on the new master clusterStatus = active.getClusterStatus(); assertFalse(clusterStatus.isBalancerOn()); + } - // Stop the cluster - TEST_UTIL.shutdownMiniCluster(); + /** + * Test that if the master fails, the ReplicaMapping is rebuilt + * by the new master. + * + * @throws Exception + */ + @Test(timeout = 100000) + public void testReadReplicaMappingAfterMasterFailover() throws Exception { + final byte [] FAMILY = Bytes.toBytes("testFamily"); + + assertTrue(cluster.waitForActiveAndReadyMaster()); + HMaster active = cluster.getMaster(); + + final TableName tableName = TableName.valueOf("testReadReplicaMappingAfterMasterFailover"); + HTableDescriptor hdt = TEST_UTIL.createTableDescriptor(tableName.getNameAsString()); + hdt.setRegionReplication(2); + TEST_UTIL.createTable(hdt, new byte[][] { FAMILY }, TEST_UTIL.getConfiguration()); + + RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName); + List allRegionLocations = locator.getAllRegionLocations(); + + // There are two regions, one for primary, one for the replica. + assertTrue(allRegionLocations.size() == 2); + + List parentRegion = new ArrayList<>(); + parentRegion.add(allRegionLocations.get(0).getRegionInfo()); + Map> currentAssign = + active.getAssignmentManager().getRegionStates().getRegionAssignments(parentRegion); + Collection> c = currentAssign.values(); + int count = 0; + for (List l : c) { + count += l.size(); + } + + // Make sure that there are regions in the ReplicaMapping + assertEquals(2, count); + + active = killActiveAndWaitForNewActive(cluster); + + Map> currentAssignNew = + active.getAssignmentManager().getRegionStates().getRegionAssignments(parentRegion); + Collection> cNew = currentAssignNew.values(); + count = 0; + for (List l : cNew) { + count += l.size(); + } + + // Make sure that there are regions in the ReplicaMapping when the new master takes over. + assertEquals(2, count); } /**