001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master.assignment; 019 020import static org.junit.Assert.assertNotEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import java.util.ArrayList; 025import java.util.List; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.HBaseTestingUtil; 029import org.apache.hadoop.hbase.HConstants; 030import org.apache.hadoop.hbase.TableName; 031import org.apache.hadoop.hbase.client.RegionInfo; 032import org.apache.hadoop.hbase.client.RegionInfoBuilder; 033import org.apache.hadoop.hbase.client.RegionReplicaTestHelper; 034import org.apache.hadoop.hbase.client.RegionReplicaUtil; 035import org.apache.hadoop.hbase.client.Table; 036import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 037import org.apache.hadoop.hbase.regionserver.HRegionServer; 038import org.apache.hadoop.hbase.regionserver.Region; 039import org.apache.hadoop.hbase.testclassification.MediumTests; 040import org.apache.hadoop.hbase.testclassification.RegionServerTests; 041import org.apache.hadoop.hbase.util.Bytes; 042import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 043import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; 044import org.apache.hadoop.hbase.util.RegionSplitter; 045import org.junit.AfterClass; 046import org.junit.BeforeClass; 047import org.junit.ClassRule; 048import org.junit.Rule; 049import org.junit.Test; 050import org.junit.experimental.categories.Category; 051import org.junit.rules.TestName; 052import org.slf4j.Logger; 053import org.slf4j.LoggerFactory; 054 055@Category({ RegionServerTests.class, MediumTests.class }) 056public class TestRegionReplicaSplit { 057 @ClassRule 058 public static final HBaseClassTestRule CLASS_RULE = 059 HBaseClassTestRule.forClass(TestRegionReplicaSplit.class); 060 private static final Logger LOG = LoggerFactory.getLogger(TestRegionReplicaSplit.class); 061 062 private static final int NB_SERVERS = 4; 063 064 private static final HBaseTestingUtil HTU = new HBaseTestingUtil(); 065 private static final byte[] f = HConstants.CATALOG_FAMILY; 066 067 @BeforeClass 068 public static void beforeClass() throws Exception { 069 HTU.getConfiguration().setInt("hbase.master.wait.on.regionservers.mintostart", 3); 070 HTU.startMiniCluster(NB_SERVERS); 071 } 072 073 @Rule 074 public TestName name = new TestName(); 075 076 private static Table createTableAndLoadData(final TableName tableName) throws IOException { 077 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName); 078 builder.setRegionReplication(3); 079 // create a table with 3 replication 080 Table table = HTU.createTable(builder.build(), new byte[][] { f }, getSplits(2), 081 new Configuration(HTU.getConfiguration())); 082 HTU.loadTable(HTU.getConnection().getTable(tableName), f); 083 HTU.flush(tableName); 084 return table; 085 } 086 087 private static byte[][] getSplits(int numRegions) { 088 RegionSplitter.UniformSplit split = new RegionSplitter.UniformSplit(); 089 split.setFirstRow(Bytes.toBytes("a")); 090 split.setLastRow(Bytes.toBytes("z")); 091 return split.split(numRegions); 092 } 093 094 @AfterClass 095 public static void afterClass() throws Exception { 096 HRegionServer.TEST_SKIP_REPORTING_TRANSITION = false; 097 HTU.shutdownMiniCluster(); 098 } 099 100 @Test 101 public void testRegionReplicaSplitRegionAssignment() throws Exception { 102 TableName tn = TableName.valueOf(this.name.getMethodName()); 103 Table table = null; 104 try { 105 table = createTableAndLoadData(tn); 106 HTU.loadNumericRows(table, f, 0, 3); 107 // split the table 108 List<RegionInfo> regions = new ArrayList<RegionInfo>(); 109 for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) { 110 for (Region r : rs.getRegionServer().getRegions(table.getName())) { 111 regions.add(r.getRegionInfo()); 112 } 113 } 114 // There are 6 regions before split, 9 regions after split. 115 HTU.getAdmin().split(table.getName(), Bytes.toBytes("d")); 116 int count = 0; 117 while (true) { 118 for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) { 119 for (Region r : rs.getRegionServer().getRegions(table.getName())) { 120 // Make sure that every region has some data (even for split daughter regions). 121 if (RegionReplicaUtil.isDefaultReplica(r.getRegionInfo())) { 122 assertTrue(r.getStore(f).hasReferences() || r.getStore(f).getStorefiles().size() > 0); 123 } 124 count++; 125 } 126 } 127 if (count >= 9) { 128 break; 129 } 130 count = 0; 131 } 132 RegionReplicaTestHelper.assertReplicaDistributed(HTU, table); 133 } finally { 134 if (table != null) { 135 HTU.deleteTable(tn); 136 } 137 } 138 } 139 140 @Test 141 public void testAssignFakeReplicaRegion() throws Exception { 142 TableName tn = TableName.valueOf(this.name.getMethodName()); 143 Table table = null; 144 try { 145 table = createTableAndLoadData(tn); 146 final RegionInfo fakeHri = RegionInfoBuilder.newBuilder(table.getName()) 147 .setStartKey(Bytes.toBytes("a")).setEndKey(Bytes.toBytes("b")).setReplicaId(1) 148 .setRegionId(EnvironmentEdgeManager.currentTime()).build(); 149 150 // To test AssignProcedure can defend this case. 151 HTU.getMiniHBaseCluster().getMaster().getAssignmentManager().assign(fakeHri); 152 // Wait until all assigns are done. 153 HBaseTestingUtil.await(50, () -> { 154 return HTU.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor().getActiveProcIds() 155 .isEmpty(); 156 }); 157 158 // Make sure the region is not online. 159 for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) { 160 for (Region r : rs.getRegionServer().getRegions(table.getName())) { 161 assertNotEquals(r.getRegionInfo(), fakeHri); 162 } 163 } 164 } finally { 165 if (table != null) { 166 HTU.deleteTable(tn); 167 } 168 } 169 } 170}