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.regionserver; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import java.util.ArrayList; 026import java.util.Collection; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.hbase.HBaseClassTestRule; 029import org.apache.hadoop.hbase.HBaseTestingUtility; 030import org.apache.hadoop.hbase.HConstants; 031import org.apache.hadoop.hbase.TableName; 032import org.apache.hadoop.hbase.client.RegionInfo; 033import org.apache.hadoop.hbase.client.RegionReplicaUtil; 034import org.apache.hadoop.hbase.client.Table; 035import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 036import org.apache.hadoop.hbase.testclassification.MediumTests; 037import org.apache.hadoop.hbase.testclassification.RegionServerTests; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.apache.hadoop.hbase.util.RegionSplitter; 040import org.apache.hadoop.hdfs.DFSConfigKeys; 041import org.junit.After; 042import org.junit.AfterClass; 043import org.junit.Before; 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 TestRegionReplicasWithRestartScenarios { 055 056 @ClassRule 057 public static final HBaseClassTestRule CLASS_RULE = 058 HBaseClassTestRule.forClass(TestRegionReplicasWithRestartScenarios.class); 059 060 private static final Logger LOG = 061 LoggerFactory.getLogger(TestRegionReplicasWithRestartScenarios.class); 062 063 @Rule public TestName name = new TestName(); 064 065 private static final int NB_SERVERS = 3; 066 private Table table; 067 068 private static final HBaseTestingUtility HTU = new HBaseTestingUtility(); 069 private static final byte[] f = HConstants.CATALOG_FAMILY; 070 071 @BeforeClass 072 public static void beforeClass() throws Exception { 073 // Reduce the hdfs block size and prefetch to trigger the file-link reopen 074 // when the file is moved to archive (e.g. compaction) 075 HTU.getConfiguration().setInt(DFSConfigKeys.DFS_BLOCK_SIZE_KEY, 8192); 076 HTU.getConfiguration().setInt(DFSConfigKeys.DFS_CLIENT_READ_PREFETCH_SIZE_KEY, 1); 077 HTU.getConfiguration().setInt(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, 128 * 1024 * 1024); 078 HTU.getConfiguration().setInt(">hbase.master.wait.on.regionservers.mintostart", 3); 079 HTU.startMiniCluster(NB_SERVERS); 080 } 081 082 @Before 083 public void before() throws IOException { 084 TableName tableName = TableName.valueOf(this.name.getMethodName()); 085 // Create table then get the single region for our new table. 086 this.table = createTableDirectlyFromHTD(tableName); 087 } 088 089 @After 090 public void after() throws IOException { 091 this.table.close(); 092 } 093 094 private static Table createTableDirectlyFromHTD(final TableName tableName) throws IOException { 095 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName); 096 builder.setRegionReplication(3); 097 return HTU.createTable(builder.build(), new byte[][] { f }, getSplits(20), 098 new Configuration(HTU.getConfiguration())); 099 } 100 101 private static byte[][] getSplits(int numRegions) { 102 RegionSplitter.UniformSplit split = new RegionSplitter.UniformSplit(); 103 split.setFirstRow(Bytes.toBytes(0L)); 104 split.setLastRow(Bytes.toBytes(Long.MAX_VALUE)); 105 return split.split(numRegions); 106 } 107 108 @AfterClass 109 public static void afterClass() throws Exception { 110 HRegionServer.TEST_SKIP_REPORTING_TRANSITION = false; 111 HTU.shutdownMiniCluster(); 112 } 113 114 private HRegionServer getRS() { 115 return HTU.getMiniHBaseCluster().getRegionServer(0); 116 } 117 118 private HRegionServer getSecondaryRS() { 119 return HTU.getMiniHBaseCluster().getRegionServer(1); 120 } 121 122 private HRegionServer getTertiaryRS() { 123 return HTU.getMiniHBaseCluster().getRegionServer(2); 124 } 125 126 @Test 127 public void testRegionReplicasCreated() throws Exception { 128 Collection<HRegion> onlineRegions = getRS().getOnlineRegionsLocalContext(); 129 boolean res = checkDuplicates(onlineRegions); 130 assertFalse(res); 131 Collection<HRegion> onlineRegions2 = getSecondaryRS().getOnlineRegionsLocalContext(); 132 res = checkDuplicates(onlineRegions2); 133 assertFalse(res); 134 Collection<HRegion> onlineRegions3 = getTertiaryRS().getOnlineRegionsLocalContext(); 135 checkDuplicates(onlineRegions3); 136 assertFalse(res); 137 int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size(); 138 assertEquals(62, totalRegions); 139 } 140 141 private boolean checkDuplicates(Collection<HRegion> onlineRegions3) throws Exception { 142 ArrayList<Region> copyOfRegion = new ArrayList<Region>(onlineRegions3); 143 for (Region region : copyOfRegion) { 144 RegionInfo regionInfo = region.getRegionInfo(); 145 RegionInfo regionInfoForReplica = 146 RegionReplicaUtil.getRegionInfoForDefaultReplica(regionInfo); 147 int i = 0; 148 for (Region actualRegion : onlineRegions3) { 149 if (regionInfoForReplica.equals( 150 RegionReplicaUtil.getRegionInfoForDefaultReplica(actualRegion.getRegionInfo()))) { 151 i++; 152 if (i > 1) { 153 LOG.info("Duplicate found " + actualRegion.getRegionInfo() + " " + 154 region.getRegionInfo()); 155 assertTrue(Bytes.equals(region.getRegionInfo().getStartKey(), 156 actualRegion.getRegionInfo().getStartKey())); 157 assertTrue(Bytes.equals(region.getRegionInfo().getEndKey(), 158 actualRegion.getRegionInfo().getEndKey())); 159 return true; 160 } 161 } 162 } 163 } 164 return false; 165 } 166}