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.client; 019 020import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.assertErrors; 021import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.doFsck; 022import static org.junit.Assert.assertNotEquals; 023import static org.junit.Assert.assertTrue; 024import static org.junit.Assert.fail; 025 026import edu.umd.cs.findbugs.annotations.Nullable; 027import java.io.IOException; 028import java.util.Arrays; 029import java.util.Collection; 030import java.util.EnumSet; 031import java.util.HashSet; 032import java.util.List; 033import java.util.Set; 034import java.util.concurrent.ExecutorService; 035import java.util.concurrent.atomic.AtomicBoolean; 036import org.apache.hadoop.conf.Configuration; 037import org.apache.hadoop.hbase.Abortable; 038import org.apache.hadoop.hbase.ClusterMetrics.Option; 039import org.apache.hadoop.hbase.HBaseClassTestRule; 040import org.apache.hadoop.hbase.HBaseTestingUtility; 041import org.apache.hadoop.hbase.HConstants; 042import org.apache.hadoop.hbase.HRegionLocation; 043import org.apache.hadoop.hbase.MetaTableAccessor; 044import org.apache.hadoop.hbase.RegionLocations; 045import org.apache.hadoop.hbase.ServerName; 046import org.apache.hadoop.hbase.TableName; 047import org.apache.hadoop.hbase.TableNotFoundException; 048import org.apache.hadoop.hbase.Waiter; 049import org.apache.hadoop.hbase.master.NoSuchProcedureException; 050import org.apache.hadoop.hbase.master.assignment.AssignmentManager; 051import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 052import org.apache.hadoop.hbase.regionserver.StorefileRefresherChore; 053import org.apache.hadoop.hbase.testclassification.LargeTests; 054import org.apache.hadoop.hbase.util.Bytes; 055import org.apache.hadoop.hbase.util.HBaseFsck; 056import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter.ERROR_CODE; 057import org.apache.hadoop.hbase.util.HBaseFsckRepair; 058import org.apache.hadoop.hbase.util.hbck.HbckTestingUtil; 059import org.apache.hadoop.hbase.zookeeper.LoadBalancerTracker; 060import org.apache.hadoop.hbase.zookeeper.ZKUtil; 061import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 062import org.apache.hadoop.hbase.zookeeper.ZNodePaths; 063import org.apache.zookeeper.KeeperException; 064import org.junit.After; 065import org.junit.Before; 066import org.junit.ClassRule; 067import org.junit.Ignore; 068import org.junit.Rule; 069import org.junit.Test; 070import org.junit.experimental.categories.Category; 071import org.junit.rules.TestName; 072import org.slf4j.Logger; 073import org.slf4j.LoggerFactory; 074 075/** 076 * Tests the scenarios where replicas are enabled for the meta table 077 */ 078@Category(LargeTests.class) 079public class TestMetaWithReplicas { 080 081 @ClassRule 082 public static final HBaseClassTestRule CLASS_RULE = 083 HBaseClassTestRule.forClass(TestMetaWithReplicas.class); 084 085 private static final Logger LOG = LoggerFactory.getLogger(TestMetaWithReplicas.class); 086 private final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 087 private static final int REGIONSERVERS_COUNT = 3; 088 089 @Rule 090 public TestName name = new TestName(); 091 092 @Before 093 public void setup() throws Exception { 094 TEST_UTIL.getConfiguration().setInt("zookeeper.session.timeout", 30000); 095 TEST_UTIL.getConfiguration().setInt(HConstants.META_REPLICAS_NUM, 3); 096 TEST_UTIL.getConfiguration().setInt( 097 StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD, 1000); 098 TEST_UTIL.startMiniCluster(REGIONSERVERS_COUNT); 099 AssignmentManager am = TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager(); 100 Set<ServerName> sns = new HashSet<ServerName>(); 101 ServerName hbaseMetaServerName = 102 TEST_UTIL.getMiniHBaseCluster().getMaster().getMetaTableLocator(). 103 getMetaRegionLocation(TEST_UTIL.getZooKeeperWatcher()); 104 LOG.info("HBASE:META DEPLOY: on " + hbaseMetaServerName); 105 sns.add(hbaseMetaServerName); 106 for (int replicaId = 1; replicaId < 3; replicaId ++) { 107 RegionInfo h = 108 RegionReplicaUtil.getRegionInfoForReplica(RegionInfoBuilder.FIRST_META_REGIONINFO, 109 replicaId); 110 try { 111 am.waitForAssignment(h); 112 ServerName sn = am.getRegionStates().getRegionServerOfRegion(h); 113 LOG.info("HBASE:META DEPLOY: " + h.getRegionNameAsString() + " on " + sn); 114 sns.add(sn); 115 } catch (NoSuchProcedureException e) { 116 LOG.info("Presume the procedure has been cleaned up so just proceed: " + e.toString()); 117 } 118 } 119 // Fun. All meta region replicas have ended up on the one server. This will cause this test 120 // to fail ... sometimes. 121 if (sns.size() == 1) { 122 int count = TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads().size(); 123 assertTrue("count=" + count, count == REGIONSERVERS_COUNT); 124 LOG.warn("All hbase:meta replicas are on the one server; moving hbase:meta: " + sns); 125 int metaServerIndex = TEST_UTIL.getHBaseCluster().getServerWithMeta(); 126 int newServerIndex = metaServerIndex; 127 while (newServerIndex == metaServerIndex) { 128 newServerIndex = (newServerIndex + 1) % REGIONSERVERS_COUNT; 129 } 130 assertNotEquals(metaServerIndex, newServerIndex); 131 ServerName destinationServerName = 132 TEST_UTIL.getHBaseCluster().getRegionServer(newServerIndex).getServerName(); 133 ServerName metaServerName = 134 TEST_UTIL.getHBaseCluster().getRegionServer(metaServerIndex).getServerName(); 135 assertNotEquals(destinationServerName, metaServerName); 136 TEST_UTIL.getAdmin().move(RegionInfoBuilder.FIRST_META_REGIONINFO.getEncodedNameAsBytes(), 137 Bytes.toBytes(destinationServerName.toString())); 138 } 139 // Disable the balancer 140 LoadBalancerTracker l = new LoadBalancerTracker(TEST_UTIL.getZooKeeperWatcher(), 141 new Abortable() { 142 AtomicBoolean aborted = new AtomicBoolean(false); 143 @Override 144 public boolean isAborted() { 145 return aborted.get(); 146 } 147 @Override 148 public void abort(String why, Throwable e) { 149 aborted.set(true); 150 } 151 }); 152 l.setBalancerOn(false); 153 LOG.debug("All meta replicas assigned"); 154 } 155 156 @After 157 public void tearDown() throws Exception { 158 TEST_UTIL.shutdownMiniCluster(); 159 } 160 161 @Test 162 public void testMetaHTDReplicaCount() throws Exception { 163 assertTrue(TEST_UTIL.getAdmin().getTableDescriptor(TableName.META_TABLE_NAME) 164 .getRegionReplication() == 3); 165 } 166 167 @Test 168 public void testZookeeperNodesForReplicas() throws Exception { 169 // Checks all the znodes exist when meta's replicas are enabled 170 ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher(); 171 Configuration conf = TEST_UTIL.getConfiguration(); 172 String baseZNode = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT, 173 HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT); 174 String primaryMetaZnode = ZNodePaths.joinZNode(baseZNode, 175 conf.get("zookeeper.znode.metaserver", "meta-region-server")); 176 // check that the data in the znode is parseable (this would also mean the znode exists) 177 byte[] data = ZKUtil.getData(zkw, primaryMetaZnode); 178 ProtobufUtil.toServerName(data); 179 for (int i = 1; i < 3; i++) { 180 String secZnode = ZNodePaths.joinZNode(baseZNode, 181 conf.get("zookeeper.znode.metaserver", "meta-region-server") + "-" + i); 182 String str = zkw.znodePaths.getZNodeForReplica(i); 183 assertTrue(str.equals(secZnode)); 184 // check that the data in the znode is parseable (this would also mean the znode exists) 185 data = ZKUtil.getData(zkw, secZnode); 186 ProtobufUtil.toServerName(data); 187 } 188 } 189 190 @Test 191 public void testShutdownHandling() throws Exception { 192 // This test creates a table, flushes the meta (with 3 replicas), kills the 193 // server holding the primary meta replica. Then it does a put/get into/from 194 // the test table. The put/get operations would use the replicas to locate the 195 // location of the test table's region 196 shutdownMetaAndDoValidations(TEST_UTIL); 197 } 198 199 public static void shutdownMetaAndDoValidations(HBaseTestingUtility util) throws Exception { 200 // This test creates a table, flushes the meta (with 3 replicas), kills the 201 // server holding the primary meta replica. Then it does a put/get into/from 202 // the test table. The put/get operations would use the replicas to locate the 203 // location of the test table's region 204 ZKWatcher zkw = util.getZooKeeperWatcher(); 205 Configuration conf = util.getConfiguration(); 206 conf.setBoolean(HConstants.USE_META_REPLICAS, true); 207 208 String baseZNode = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT, 209 HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT); 210 String primaryMetaZnode = ZNodePaths.joinZNode(baseZNode, 211 conf.get("zookeeper.znode.metaserver", "meta-region-server")); 212 byte[] data = ZKUtil.getData(zkw, primaryMetaZnode); 213 ServerName primary = ProtobufUtil.toServerName(data); 214 LOG.info("Primary=" + primary.toString()); 215 216 TableName TABLE = TableName.valueOf("testShutdownHandling"); 217 byte[][] FAMILIES = new byte[][] { Bytes.toBytes("foo") }; 218 if (util.getAdmin().tableExists(TABLE)) { 219 util.getAdmin().disableTable(TABLE); 220 util.getAdmin().deleteTable(TABLE); 221 } 222 ServerName master = null; 223 try (Connection c = ConnectionFactory.createConnection(util.getConfiguration());) { 224 try (Table htable = util.createTable(TABLE, FAMILIES);) { 225 util.getAdmin().flush(TableName.META_TABLE_NAME); 226 Thread.sleep(conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD, 227 30000) * 6); 228 List<RegionInfo> regions = MetaTableAccessor.getTableRegions(c, TABLE); 229 HRegionLocation hrl = MetaTableAccessor.getRegionLocation(c, regions.get(0)); 230 // Ensure that the primary server for test table is not the same one as the primary 231 // of the meta region since we will be killing the srv holding the meta's primary... 232 // We want to be able to write to the test table even when the meta is not present .. 233 // If the servers are the same, then move the test table's region out of the server 234 // to another random server 235 if (hrl.getServerName().equals(primary)) { 236 util.getAdmin().move(hrl.getRegionInfo().getEncodedNameAsBytes(), null); 237 // wait for the move to complete 238 do { 239 Thread.sleep(10); 240 hrl = MetaTableAccessor.getRegionLocation(c, regions.get(0)); 241 } while (primary.equals(hrl.getServerName())); 242 util.getAdmin().flush(TableName.META_TABLE_NAME); 243 Thread.sleep(conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD, 244 30000) * 3); 245 } 246 // Ensure all metas are not on same hbase:meta replica=0 server! 247 248 master = util.getHBaseClusterInterface().getClusterMetrics().getMasterName(); 249 // kill the master so that regionserver recovery is not triggered at all 250 // for the meta server 251 LOG.info("Stopping master=" + master.toString()); 252 util.getHBaseClusterInterface().stopMaster(master); 253 util.getHBaseClusterInterface().waitForMasterToStop(master, 60000); 254 LOG.info("Master " + master + " stopped!"); 255 if (!master.equals(primary)) { 256 util.getHBaseClusterInterface().killRegionServer(primary); 257 util.getHBaseClusterInterface().waitForRegionServerToStop(primary, 60000); 258 } 259 ((ClusterConnection)c).clearRegionCache(); 260 } 261 LOG.info("Running GETs"); 262 Get get = null; 263 Result r = null; 264 byte[] row = "test".getBytes(); 265 try (Table htable = c.getTable(TABLE);) { 266 Put put = new Put(row); 267 put.addColumn("foo".getBytes(), row, row); 268 BufferedMutator m = c.getBufferedMutator(TABLE); 269 m.mutate(put); 270 m.flush(); 271 // Try to do a get of the row that was just put 272 get = new Get(row); 273 r = htable.get(get); 274 assertTrue(Arrays.equals(r.getRow(), row)); 275 // now start back the killed servers and disable use of replicas. That would mean 276 // calls go to the primary 277 LOG.info("Starting Master"); 278 util.getHBaseClusterInterface().startMaster(master.getHostname(), 0); 279 util.getHBaseClusterInterface().startRegionServer(primary.getHostname(), 0); 280 util.getHBaseClusterInterface().waitForActiveAndReadyMaster(); 281 LOG.info("Master active!"); 282 ((ClusterConnection)c).clearRegionCache(); 283 } 284 conf.setBoolean(HConstants.USE_META_REPLICAS, false); 285 LOG.info("Running GETs no replicas"); 286 try (Table htable = c.getTable(TABLE);) { 287 r = htable.get(get); 288 assertTrue(Arrays.equals(r.getRow(), row)); 289 } 290 } 291 } 292 293 @Test 294 public void testMetaLookupThreadPoolCreated() throws Exception { 295 final TableName tableName = TableName.valueOf(name.getMethodName()); 296 byte[][] FAMILIES = new byte[][] { Bytes.toBytes("foo") }; 297 if (TEST_UTIL.getAdmin().tableExists(tableName)) { 298 TEST_UTIL.getAdmin().disableTable(tableName); 299 TEST_UTIL.getAdmin().deleteTable(tableName); 300 } 301 try (Table htable = TEST_UTIL.createTable(tableName, FAMILIES);) { 302 byte[] row = "test".getBytes(); 303 ConnectionImplementation c = ((ConnectionImplementation) TEST_UTIL.getConnection()); 304 // check that metalookup pool would get created 305 c.relocateRegion(tableName, row); 306 ExecutorService ex = c.getCurrentMetaLookupPool(); 307 assert(ex != null); 308 } 309 } 310 311 @Ignore @Test // Uses FSCK. Needs fixing after HBASE-14614. 312 public void testChangingReplicaCount() throws Exception { 313 // tests changing the replica count across master restarts 314 // reduce the replica count from 3 to 2 315 stopMasterAndValidateReplicaCount(3, 2); 316 // increase the replica count from 2 to 3 317 stopMasterAndValidateReplicaCount(2, 3); 318 } 319 320 private void stopMasterAndValidateReplicaCount(final int originalReplicaCount, 321 final int newReplicaCount) 322 throws Exception { 323 ServerName sn = TEST_UTIL.getHBaseClusterInterface().getClusterMetrics().getMasterName(); 324 TEST_UTIL.getHBaseClusterInterface().stopMaster(sn); 325 TEST_UTIL.getHBaseClusterInterface().waitForMasterToStop(sn, 60000); 326 List<String> metaZnodes = TEST_UTIL.getZooKeeperWatcher().getMetaReplicaNodes(); 327 assert(metaZnodes.size() == originalReplicaCount); //we should have what was configured before 328 TEST_UTIL.getHBaseClusterInterface().getConf().setInt(HConstants.META_REPLICAS_NUM, 329 newReplicaCount); 330 if (TEST_UTIL.getHBaseCluster().countServedRegions() < newReplicaCount) { 331 TEST_UTIL.getHBaseCluster().startRegionServer(); 332 } 333 TEST_UTIL.getHBaseClusterInterface().startMaster(sn.getHostname(), 0); 334 TEST_UTIL.getHBaseClusterInterface().waitForActiveAndReadyMaster(); 335 TEST_UTIL.waitFor(10000, predicateMetaHasReplicas(newReplicaCount)); 336 // also check if hbck returns without errors 337 TEST_UTIL.getConfiguration().setInt(HConstants.META_REPLICAS_NUM, 338 newReplicaCount); 339 HBaseFsck hbck = HbckTestingUtil.doFsck(TEST_UTIL.getConfiguration(), false); 340 HbckTestingUtil.assertNoErrors(hbck); 341 } 342 343 private Waiter.ExplainingPredicate<Exception> predicateMetaHasReplicas( 344 final int newReplicaCount) { 345 return new Waiter.ExplainingPredicate<Exception>() { 346 @Override 347 public String explainFailure() throws Exception { 348 return checkMetaLocationAndExplain(newReplicaCount); 349 } 350 351 @Override 352 public boolean evaluate() throws Exception { 353 return checkMetaLocationAndExplain(newReplicaCount) == null; 354 } 355 }; 356 } 357 358 @Nullable 359 private String checkMetaLocationAndExplain(int originalReplicaCount) 360 throws KeeperException, IOException { 361 List<String> metaZnodes = TEST_UTIL.getZooKeeperWatcher().getMetaReplicaNodes(); 362 if (metaZnodes.size() == originalReplicaCount) { 363 RegionLocations rl = ((ClusterConnection) TEST_UTIL.getConnection()) 364 .locateRegion(TableName.META_TABLE_NAME, 365 HConstants.EMPTY_START_ROW, false, false); 366 for (HRegionLocation location : rl.getRegionLocations()) { 367 if (location == null) { 368 return "Null location found in " + rl.toString(); 369 } 370 if (location.getRegionInfo() == null) { 371 return "Null regionInfo for location " + location; 372 } 373 if (location.getHostname() == null) { 374 return "Null hostName for location " + location; 375 } 376 } 377 return null; // OK 378 } 379 return "Replica count is not as expected " + originalReplicaCount + " <> " + metaZnodes.size() 380 + "(" + metaZnodes.toString() + ")"; 381 } 382 383 @Ignore @Test 384 public void testHBaseFsckWithMetaReplicas() throws Exception { 385 HBaseFsck hbck = HbckTestingUtil.doFsck(TEST_UTIL.getConfiguration(), false); 386 HbckTestingUtil.assertNoErrors(hbck); 387 } 388 389 @Ignore @Test // Disabled. Relies on FSCK which needs work for AMv2. 390 public void testHBaseFsckWithFewerMetaReplicas() throws Exception { 391 ClusterConnection c = (ClusterConnection)ConnectionFactory.createConnection( 392 TEST_UTIL.getConfiguration()); 393 RegionLocations rl = c.locateRegion(TableName.META_TABLE_NAME, HConstants.EMPTY_START_ROW, 394 false, false); 395 HBaseFsckRepair.closeRegionSilentlyAndWait(c, 396 rl.getRegionLocation(1).getServerName(), rl.getRegionLocation(1).getRegionInfo()); 397 // check that problem exists 398 HBaseFsck hbck = doFsck(TEST_UTIL.getConfiguration(), false); 399 assertErrors(hbck, new ERROR_CODE[]{ERROR_CODE.UNKNOWN,ERROR_CODE.NO_META_REGION}); 400 // fix the problem 401 hbck = doFsck(TEST_UTIL.getConfiguration(), true); 402 // run hbck again to make sure we don't see any errors 403 hbck = doFsck(TEST_UTIL.getConfiguration(), false); 404 assertErrors(hbck, new ERROR_CODE[]{}); 405 } 406 407 @Ignore @Test // The close silently doesn't work any more since HBASE-14614. Fix. 408 public void testHBaseFsckWithFewerMetaReplicaZnodes() throws Exception { 409 ClusterConnection c = (ClusterConnection)ConnectionFactory.createConnection( 410 TEST_UTIL.getConfiguration()); 411 RegionLocations rl = c.locateRegion(TableName.META_TABLE_NAME, HConstants.EMPTY_START_ROW, 412 false, false); 413 HBaseFsckRepair.closeRegionSilentlyAndWait(c, 414 rl.getRegionLocation(2).getServerName(), rl.getRegionLocation(2).getRegionInfo()); 415 ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher(); 416 ZKUtil.deleteNode(zkw, zkw.znodePaths.getZNodeForReplica(2)); 417 // check that problem exists 418 HBaseFsck hbck = doFsck(TEST_UTIL.getConfiguration(), false); 419 assertErrors(hbck, new ERROR_CODE[]{ERROR_CODE.UNKNOWN,ERROR_CODE.NO_META_REGION}); 420 // fix the problem 421 hbck = doFsck(TEST_UTIL.getConfiguration(), true); 422 // run hbck again to make sure we don't see any errors 423 hbck = doFsck(TEST_UTIL.getConfiguration(), false); 424 assertErrors(hbck, new ERROR_CODE[]{}); 425 } 426 427 @Test 428 public void testAccessingUnknownTables() throws Exception { 429 Configuration conf = new Configuration(TEST_UTIL.getConfiguration()); 430 conf.setBoolean(HConstants.USE_META_REPLICAS, true); 431 Table table = TEST_UTIL.getConnection().getTable(TableName.valueOf(name.getMethodName())); 432 Get get = new Get(Bytes.toBytes("foo")); 433 try { 434 table.get(get); 435 } catch (TableNotFoundException t) { 436 return; 437 } 438 fail("Expected TableNotFoundException"); 439 } 440 441 @Test 442 public void testMetaAddressChange() throws Exception { 443 // checks that even when the meta's location changes, the various 444 // caches update themselves. Uses the master operations to test 445 // this 446 Configuration conf = TEST_UTIL.getConfiguration(); 447 ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher(); 448 String baseZNode = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT, 449 HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT); 450 String primaryMetaZnode = ZNodePaths.joinZNode(baseZNode, 451 conf.get("zookeeper.znode.metaserver", "meta-region-server")); 452 // check that the data in the znode is parseable (this would also mean the znode exists) 453 byte[] data = ZKUtil.getData(zkw, primaryMetaZnode); 454 ServerName currentServer = ProtobufUtil.toServerName(data); 455 Collection<ServerName> liveServers = TEST_UTIL.getAdmin() 456 .getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS)).getLiveServerMetrics().keySet(); 457 ServerName moveToServer = null; 458 for (ServerName s : liveServers) { 459 if (!currentServer.equals(s)) { 460 moveToServer = s; 461 } 462 } 463 assert(moveToServer != null); 464 final TableName tableName = TableName.valueOf(name.getMethodName()); 465 TEST_UTIL.createTable(tableName, "f"); 466 assertTrue(TEST_UTIL.getAdmin().tableExists(tableName)); 467 TEST_UTIL.getAdmin().move(RegionInfoBuilder.FIRST_META_REGIONINFO.getEncodedNameAsBytes(), 468 Bytes.toBytes(moveToServer.getServerName())); 469 int i = 0; 470 assert !moveToServer.equals(currentServer); 471 LOG.info("CurrentServer=" + currentServer + ", moveToServer=" + moveToServer); 472 final int max = 10000; 473 do { 474 Thread.sleep(10); 475 data = ZKUtil.getData(zkw, primaryMetaZnode); 476 currentServer = ProtobufUtil.toServerName(data); 477 i++; 478 } while (!moveToServer.equals(currentServer) && i < max); //wait for 10 seconds overall 479 assert(i != max); 480 TEST_UTIL.getAdmin().disableTable(tableName); 481 assertTrue(TEST_UTIL.getAdmin().isTableDisabled(tableName)); 482 } 483 484 @Test 485 public void testShutdownOfReplicaHolder() throws Exception { 486 // checks that the when the server holding meta replica is shut down, the meta replica 487 // can be recovered 488 try (ClusterConnection conn = (ClusterConnection) 489 ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());) { 490 RegionLocations rl = conn. 491 locateRegion(TableName.META_TABLE_NAME, Bytes.toBytes(""), false, true); 492 HRegionLocation hrl = rl.getRegionLocation(1); 493 ServerName oldServer = hrl.getServerName(); 494 TEST_UTIL.getHBaseClusterInterface().killRegionServer(oldServer); 495 int i = 0; 496 do { 497 LOG.debug("Waiting for the replica " + hrl.getRegionInfo() + " to come up"); 498 Thread.sleep(10000); //wait for the detection/recovery 499 rl = conn.locateRegion(TableName.META_TABLE_NAME, Bytes.toBytes(""), false, true); 500 hrl = rl.getRegionLocation(1); 501 i++; 502 } while ((hrl == null || hrl.getServerName().equals(oldServer)) && i < 3); 503 assertTrue(i != 3); 504 } 505 } 506 507 @Ignore @Test // Disabled because fsck and this needs work for AMv2 508 public void testHBaseFsckWithExcessMetaReplicas() throws Exception { 509 // Create a meta replica (this will be the 4th one) and assign it 510 RegionInfo h = RegionReplicaUtil.getRegionInfoForReplica( 511 RegionInfoBuilder.FIRST_META_REGIONINFO, 3); 512 TEST_UTIL.assignRegion(h); 513 HBaseFsckRepair.waitUntilAssigned(TEST_UTIL.getAdmin(), h); 514 // check that problem exists 515 HBaseFsck hbck = doFsck(TEST_UTIL.getConfiguration(), false); 516 assertErrors(hbck, new ERROR_CODE[]{ERROR_CODE.UNKNOWN, ERROR_CODE.SHOULD_NOT_BE_DEPLOYED}); 517 // fix the problem 518 hbck = doFsck(TEST_UTIL.getConfiguration(), true); 519 // run hbck again to make sure we don't see any errors 520 hbck = doFsck(TEST_UTIL.getConfiguration(), false); 521 assertErrors(hbck, new ERROR_CODE[]{}); 522 } 523}