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; 021 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.List; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.hbase.HBaseClassTestRule; 027import org.apache.hadoop.hbase.HBaseTestingUtility; 028import org.apache.hadoop.hbase.HConstants; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.client.RegionInfo; 031import org.apache.hadoop.hbase.client.RegionInfoBuilder; 032import org.apache.hadoop.hbase.client.RegionReplicaTestHelper; 033import org.apache.hadoop.hbase.client.Table; 034import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 035import org.apache.hadoop.hbase.regionserver.HRegionServer; 036import org.apache.hadoop.hbase.regionserver.Region; 037import org.apache.hadoop.hbase.testclassification.MediumTests; 038import org.apache.hadoop.hbase.testclassification.RegionServerTests; 039import org.apache.hadoop.hbase.util.Bytes; 040import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 041import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; 042import org.apache.hadoop.hbase.util.RegionSplitter; 043import org.junit.AfterClass; 044import org.junit.BeforeClass; 045import org.junit.ClassRule; 046import org.junit.Rule; 047import org.junit.Test; 048import org.junit.experimental.categories.Category; 049import org.junit.rules.TestName; 050import org.slf4j.Logger; 051import org.slf4j.LoggerFactory; 052 053@Category({ RegionServerTests.class, MediumTests.class }) 054public class TestRegionReplicaSplit { 055 @ClassRule 056 public static final HBaseClassTestRule CLASS_RULE = 057 HBaseClassTestRule.forClass(TestRegionReplicaSplit.class); 058 private static final Logger LOG = LoggerFactory.getLogger(TestRegionReplicaSplit.class); 059 060 private static final int NB_SERVERS = 4; 061 062 private static final HBaseTestingUtility HTU = new HBaseTestingUtility(); 063 private static final byte[] f = HConstants.CATALOG_FAMILY; 064 065 @BeforeClass 066 public static void beforeClass() throws Exception { 067 HTU.getConfiguration().setInt("hbase.master.wait.on.regionservers.mintostart", 3); 068 HTU.startMiniCluster(NB_SERVERS); 069 } 070 071 @Rule 072 public TestName name = new TestName(); 073 074 private static Table createTableAndLoadData(final TableName tableName) throws IOException { 075 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName); 076 builder.setRegionReplication(3); 077 // create a table with 3 replication 078 Table table = HTU.createTable(builder.build(), new byte[][] { f }, getSplits(2), 079 new Configuration(HTU.getConfiguration())); 080 HTU.loadTable(HTU.getConnection().getTable(tableName), f); 081 return table; 082 } 083 084 private static byte[][] getSplits(int numRegions) { 085 RegionSplitter.UniformSplit split = new RegionSplitter.UniformSplit(); 086 split.setFirstRow(Bytes.toBytes(0L)); 087 split.setLastRow(Bytes.toBytes(Long.MAX_VALUE)); 088 return split.split(numRegions); 089 } 090 091 @AfterClass 092 public static void afterClass() throws Exception { 093 HRegionServer.TEST_SKIP_REPORTING_TRANSITION = false; 094 HTU.shutdownMiniCluster(); 095 } 096 097 @Test 098 public void testRegionReplicaSplitRegionAssignment() throws Exception { 099 TableName tn = TableName.valueOf(this.name.getMethodName()); 100 Table table = null; 101 try { 102 table = createTableAndLoadData(tn); 103 HTU.loadNumericRows(table, f, 0, 3); 104 // split the table 105 List<RegionInfo> regions = new ArrayList<RegionInfo>(); 106 for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) { 107 for (Region r : rs.getRegionServer().getRegions(table.getName())) { 108 regions.add(r.getRegionInfo()); 109 } 110 } 111 // There are 6 regions before split, 9 regions after split. 112 HTU.getAdmin().split(table.getName(), Bytes.toBytes(1)); 113 int count = 0; 114 while (true) { 115 for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) { 116 for (Region r : rs.getRegionServer().getRegions(table.getName())) { 117 count++; 118 } 119 } 120 if (count >= 9) { 121 break; 122 } 123 count = 0; 124 } 125 RegionReplicaTestHelper.assertReplicaDistributed(HTU, table); 126 } finally { 127 if (table != null) { 128 HTU.deleteTable(tn); 129 } 130 } 131 } 132 133 @Test 134 public void testAssignFakeReplicaRegion() throws Exception { 135 TableName tn = TableName.valueOf(this.name.getMethodName()); 136 Table table = null; 137 try { 138 table = createTableAndLoadData(tn); 139 final RegionInfo fakeHri = RegionInfoBuilder.newBuilder(table.getName()) 140 .setStartKey(Bytes.toBytes("a")).setEndKey(Bytes.toBytes("b")).setReplicaId(1) 141 .setRegionId(EnvironmentEdgeManager.currentTime()).build(); 142 143 // To test AssignProcedure can defend this case. 144 HTU.getMiniHBaseCluster().getMaster().getAssignmentManager().assign(fakeHri); 145 // Wait until all assigns are done. 146 HBaseTestingUtility.await(50, () -> { 147 return HTU.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor().getActiveProcIds() 148 .isEmpty(); 149 }); 150 151 // Make sure the region is not online. 152 for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) { 153 for (Region r : rs.getRegionServer().getRegions(table.getName())) { 154 assertNotEquals(r.getRegionInfo(), fakeHri); 155 } 156 } 157 } finally { 158 if (table != null) { 159 HTU.deleteTable(tn); 160 } 161 } 162 } 163}