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..aad96ed 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 @@ -20,7 +20,15 @@ package org.apache.hadoop.hbase.master; 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; @@ -28,8 +36,12 @@ 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 java.util.Map; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -80,6 +92,68 @@ public class TestMasterFailoverBalancerPersistence { } /** + * Test that if the master fails, the ReplicaMapping is rebuilt + * by the new master. + * + * @throws Exception + */ + @Test(timeout = 240000) + public void testReadReplicaMappingAfterMasterFailover() throws Exception { + final int NUM_MASTERS = 2; + final int NUM_RS = 2; + final byte [] FAMILY = Bytes.toBytes("testFamily"); + + // 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(); + + 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); + + // Stop the cluster + TEST_UTIL.shutdownMiniCluster(); + } + + /** * Kill the master and wait for a new active master to show up * * @param cluster