Return-Path: X-Original-To: apmail-hbase-commits-archive@www.apache.org Delivered-To: apmail-hbase-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2718F18E5F for ; Mon, 2 Nov 2015 03:51:49 +0000 (UTC) Received: (qmail 20527 invoked by uid 500); 2 Nov 2015 03:51:49 -0000 Delivered-To: apmail-hbase-commits-archive@hbase.apache.org Received: (qmail 20478 invoked by uid 500); 2 Nov 2015 03:51:48 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 20463 invoked by uid 99); 2 Nov 2015 03:51:48 -0000 Received: from Unknown (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Nov 2015 03:51:48 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 48D4EC0FF9 for ; Mon, 2 Nov 2015 03:51:48 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 0.99 X-Spam-Level: X-Spam-Status: No, score=0.99 tagged_above=-999 required=6.31 tests=[KAM_LAZY_DOMAIN_SECURITY=1, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from mx1-us-east.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id fFhaVBxMKzwX for ; Mon, 2 Nov 2015 03:51:31 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-us-east.apache.org (ASF Mail Server at mx1-us-east.apache.org) with ESMTP id EC826444DC for ; Mon, 2 Nov 2015 03:51:11 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 8DB22E1021 for ; Mon, 2 Nov 2015 03:51:10 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 838493A019A for ; Mon, 2 Nov 2015 03:51:10 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1711891 [40/50] - in /hbase/hbase.apache.org/trunk: ./ apidocs/ apidocs/org/apache/hadoop/hbase/ apidocs/org/apache/hadoop/hbase/class-use/ apidocs/org/apache/hadoop/hbase/client/ apidocs/org/apache/hadoop/hbase/client/class-use/ apidocs/o... Date: Mon, 02 Nov 2015 03:51:05 -0000 To: commits@hbase.apache.org From: misty@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20151102035110.838493A019A@svn01-us-west.apache.org> Modified: hbase/hbase.apache.org/trunk/xref-test/org/apache/hadoop/hbase/master/TestMasterTransitions.html URL: http://svn.apache.org/viewvc/hbase/hbase.apache.org/trunk/xref-test/org/apache/hadoop/hbase/master/TestMasterTransitions.html?rev=1711891&r1=1711890&r2=1711891&view=diff ============================================================================== --- hbase/hbase.apache.org/trunk/xref-test/org/apache/hadoop/hbase/master/TestMasterTransitions.html (original) +++ hbase/hbase.apache.org/trunk/xref-test/org/apache/hadoop/hbase/master/TestMasterTransitions.html Mon Nov 2 03:51:02 2015 @@ -35,512 +35,513 @@ 25 import org.apache.hadoop.hbase.HBaseTestingUtility; 26 import org.apache.hadoop.hbase.HConstants; 27 import org.apache.hadoop.hbase.HRegionInfo; -28 import org.apache.hadoop.hbase.TableName; -29 import org.apache.hadoop.hbase.client.Durability; -30 import org.apache.hadoop.hbase.client.Put; -31 import org.apache.hadoop.hbase.client.RegionLocator; -32 import org.apache.hadoop.hbase.client.Result; -33 import org.apache.hadoop.hbase.client.ResultScanner; -34 import org.apache.hadoop.hbase.client.Scan; -35 import org.apache.hadoop.hbase.client.Table; -36 import org.apache.hadoop.hbase.testclassification.LargeTests; -37 import org.apache.hadoop.hbase.testclassification.MasterTests; -38 import org.apache.hadoop.hbase.util.Bytes; -39 import org.junit.AfterClass; -40 import org.junit.Assert; -41 import org.junit.Before; -42 import org.junit.BeforeClass; -43 import org.junit.Ignore; -44 import org.junit.Test; -45 import org.junit.experimental.categories.Category; -46 -47 /** -48 * Test transitions of state across the master. Sets up the cluster once and -49 * then runs a couple of tests. -50 */ -51 @Category({MasterTests.class, LargeTests.class}) -52 public class TestMasterTransitions { -53 private static final Log LOG = LogFactory.getLog(TestMasterTransitions.class); -54 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); -55 private static final TableName TABLENAME = TableName.valueOf("master_transitions"); -56 private static final byte [][] FAMILIES = new byte [][] {Bytes.toBytes("a"), -57 Bytes.toBytes("b"), Bytes.toBytes("c")}; -58 -59 /** -60 * Start up a mini cluster and put a small table of many empty regions into it. -61 * @throws Exception -62 */ -63 @BeforeClass public static void beforeAllTests() throws Exception { -64 TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true); -65 TEST_UTIL.startMiniCluster(2); -66 // Create a table of three families. This will assign a region. -67 TEST_UTIL.createMultiRegionTable(TABLENAME, FAMILIES); -68 Table t = TEST_UTIL.getConnection().getTable(TABLENAME); -69 int countOfRegions = -1; -70 try (RegionLocator r = TEST_UTIL.getConnection().getRegionLocator(TABLENAME)) { -71 countOfRegions = r.getStartKeys().length; -72 } -73 TEST_UTIL.waitUntilAllRegionsAssigned(TABLENAME); -74 addToEachStartKey(countOfRegions); -75 t.close(); -76 } -77 -78 @AfterClass public static void afterAllTests() throws Exception { -79 TEST_UTIL.shutdownMiniCluster(); -80 } -81 -82 @Before public void setup() throws IOException { -83 TEST_UTIL.ensureSomeRegionServersAvailable(2); -84 } -85 -86 /** -87 * Listener for regionserver events testing hbase-2428 (Infinite loop of -88 * region closes if hbase:meta region is offline). In particular, listen -89 * for the close of the 'metaServer' and when it comes in, requeue it with a -90 * delay as though there were an issue processing the shutdown. As part of -91 * the requeuing, send over a close of a region on 'otherServer' so it comes -92 * into a master that has its meta region marked as offline. -93 */ -94 /* -95 static class HBase2428Listener implements RegionServerOperationListener { -96 // Map of what we've delayed so we don't do do repeated delays. -97 private final Set<RegionServerOperation> postponed = -98 new CopyOnWriteArraySet<RegionServerOperation>(); -99 private boolean done = false;; -100 private boolean metaShutdownReceived = false; -101 private final HServerAddress metaAddress; -102 private final MiniHBaseCluster cluster; -103 private final int otherServerIndex; -104 private final HRegionInfo hri; -105 private int closeCount = 0; -106 static final int SERVER_DURATION = 3 * 1000; -107 static final int CLOSE_DURATION = 1 * 1000; -108 -109 HBase2428Listener(final MiniHBaseCluster c, final HServerAddress metaAddress, -110 final HRegionInfo closingHRI, final int otherServerIndex) { -111 this.cluster = c; -112 this.metaAddress = metaAddress; -113 this.hri = closingHRI; -114 this.otherServerIndex = otherServerIndex; -115 } -116 -117 @Override -118 public boolean process(final RegionServerOperation op) throws IOException { -119 // If a regionserver shutdown and its of the meta server, then we want to -120 // delay the processing of the shutdown and send off a close of a region on -121 // the 'otherServer. -122 boolean result = true; -123 if (op instanceof ProcessServerShutdown) { -124 ProcessServerShutdown pss = (ProcessServerShutdown)op; -125 if (pss.getDeadServerAddress().equals(this.metaAddress)) { -126 // Don't postpone more than once. -127 if (!this.postponed.contains(pss)) { -128 // Close some region. -129 this.cluster.addMessageToSendRegionServer(this.otherServerIndex, -130 new HMsg(HMsg.Type.MSG_REGION_CLOSE, hri, -131 Bytes.toBytes("Forcing close in test"))); -132 this.postponed.add(pss); -133 // Put off the processing of the regionserver shutdown processing. -134 pss.setDelay(SERVER_DURATION); -135 this.metaShutdownReceived = true; -136 // Return false. This will add this op to the delayed queue. -137 result = false; -138 } -139 } -140 } else { -141 // Have the close run frequently. -142 if (isWantedCloseOperation(op) != null) { -143 op.setDelay(CLOSE_DURATION); -144 // Count how many times it comes through here. -145 this.closeCount++; -146 } -147 } -148 return result; -149 } -150 -151 public void processed(final RegionServerOperation op) { -152 if (isWantedCloseOperation(op) != null) return; -153 this.done = true; -154 } -155 */ -156 /* -157 * @param op -158 * @return Null if not the wanted ProcessRegionClose, else <code>op</code> -159 * cast as a ProcessRegionClose. -160 */ -161 /* -162 private ProcessRegionClose isWantedCloseOperation(final RegionServerOperation op) { -163 // Count every time we get a close operation. -164 if (op instanceof ProcessRegionClose) { -165 ProcessRegionClose c = (ProcessRegionClose)op; -166 if (c.regionInfo.equals(hri)) { -167 return c; -168 } -169 } -170 return null; -171 } -172 -173 boolean isDone() { -174 return this.done; -175 } -176 -177 boolean isMetaShutdownReceived() { -178 return metaShutdownReceived; -179 } -180 -181 int getCloseCount() { -182 return this.closeCount; -183 } -184 -185 @Override -186 public boolean process(HServerInfo serverInfo, HMsg incomingMsg) { -187 return true; -188 } -189 } -190 */ -191 /** -192 * In 2428, the meta region has just been set offline and then a close comes -193 * in. -194 * @see <a href="https://issues.apache.org/jira/browse/HBASE-2428">HBASE-2428</a> -195 */ -196 @Ignore @Test (timeout=300000) public void testRegionCloseWhenNoMetaHBase2428() -197 throws Exception { -198 /* -199 LOG.info("Running testRegionCloseWhenNoMetaHBase2428"); -200 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); -201 final HMaster master = cluster.getMaster(); -202 int metaIndex = cluster.getServerWithMeta(); -203 // Figure the index of the server that is not server the hbase:meta -204 int otherServerIndex = -1; -205 for (int i = 0; i < cluster.getRegionServerThreads().size(); i++) { -206 if (i == metaIndex) continue; -207 otherServerIndex = i; -208 break; -209 } -210 final HRegionServer otherServer = cluster.getRegionServer(otherServerIndex); -211 final HRegionServer metaHRS = cluster.getRegionServer(metaIndex); -212 -213 // Get a region out on the otherServer. -214 final HRegionInfo hri = -215 otherServer.getOnlineRegions().iterator().next().getRegionInfo(); -216 -217 // Add our RegionServerOperationsListener -218 HBase2428Listener listener = new HBase2428Listener(cluster, -219 metaHRS.getHServerInfo().getServerAddress(), hri, otherServerIndex); -220 master.getRegionServerOperationQueue(). -221 registerRegionServerOperationListener(listener); -222 try { -223 // Now close the server carrying meta. -224 cluster.abortRegionServer(metaIndex); -225 -226 // First wait on receipt of meta server shutdown message. -227 while(!listener.metaShutdownReceived) Threads.sleep(100); -228 while(!listener.isDone()) Threads.sleep(10); -229 // We should not have retried the close more times than it took for the -230 // server shutdown message to exit the delay queue and get processed -231 // (Multiple by two to add in some slop in case of GC or something). -232 assertTrue(listener.getCloseCount() > 1); -233 assertTrue(listener.getCloseCount() < -234 ((HBase2428Listener.SERVER_DURATION/HBase2428Listener.CLOSE_DURATION) * 2)); -235 -236 // Assert the closed region came back online -237 assertRegionIsBackOnline(hri); -238 } finally { -239 master.getRegionServerOperationQueue(). -240 unregisterRegionServerOperationListener(listener); -241 } -242 */ -243 } -244 -245 /** -246 * Test adding in a new server before old one on same host+port is dead. -247 * Make the test more onerous by having the server under test carry the meta. -248 * If confusion between old and new, purportedly meta never comes back. Test -249 * that meta gets redeployed. -250 */ -251 @Ignore @Test (timeout=300000) public void testAddingServerBeforeOldIsDead2413() -252 throws IOException { -253 /* -254 LOG.info("Running testAddingServerBeforeOldIsDead2413"); -255 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); -256 int count = count(); -257 int metaIndex = cluster.getServerWithMeta(); -258 MiniHBaseClusterRegionServer metaHRS = -259 (MiniHBaseClusterRegionServer)cluster.getRegionServer(metaIndex); -260 int port = metaHRS.getServerInfo().getServerAddress().getPort(); -261 Configuration c = TEST_UTIL.getConfiguration(); -262 String oldPort = c.get(HConstants.REGIONSERVER_PORT, "0"); -263 try { -264 LOG.info("KILLED=" + metaHRS); -265 metaHRS.kill(); -266 c.set(HConstants.REGIONSERVER_PORT, Integer.toString(port)); -267 // Try and start new regionserver. It might clash with the old -268 // regionserver port so keep trying to get past the BindException. -269 HRegionServer hrs = null; -270 while (true) { -271 try { -272 hrs = cluster.startRegionServer().getRegionServer(); -273 break; -274 } catch (IOException e) { -275 if (e.getCause() != null && e.getCause() instanceof InvocationTargetException) { -276 InvocationTargetException ee = (InvocationTargetException)e.getCause(); -277 if (ee.getCause() != null && ee.getCause() instanceof BindException) { -278 LOG.info("BindException; retrying: " + e.toString()); -279 } -280 } -281 } -282 } -283 LOG.info("STARTED=" + hrs); -284 // Wait until he's been given at least 3 regions before we go on to try -285 // and count rows in table. -286 while (hrs.getOnlineRegions().size() < 3) Threads.sleep(100); -287 LOG.info(hrs.toString() + " has " + hrs.getOnlineRegions().size() + -288 " regions"); -289 assertEquals(count, count()); -290 } finally { -291 c.set(HConstants.REGIONSERVER_PORT, oldPort); -292 } -293 */ -294 } -295 -296 /** -297 * HBase2482 is about outstanding region openings. If any are outstanding -298 * when a regionserver goes down, then they'll never deploy. They'll be -299 * stuck in the regions-in-transition list for ever. This listener looks -300 * for a region opening HMsg and if its from the server passed on construction, -301 * then we kill it. It also looks out for a close message on the victim -302 * server because that signifies start of the fireworks. -303 */ -304 /* -305 static class HBase2482Listener implements RegionServerOperationListener { -306 private final HRegionServer victim; -307 private boolean abortSent = false; -308 // We closed regions on new server. -309 private volatile boolean closed = false; -310 // Copy of regions on new server -311 private final Collection<HRegion> copyOfOnlineRegions; -312 // This is the region that was in transition on the server we aborted. Test -313 // passes if this region comes back online successfully. -314 private HRegionInfo regionToFind; -315 -316 HBase2482Listener(final HRegionServer victim) { -317 this.victim = victim; -318 // Copy regions currently open on this server so I can notice when -319 // there is a close. -320 this.copyOfOnlineRegions = -321 this.victim.getCopyOfOnlineRegionsSortedBySize().values(); -322 } -323 -324 @Override -325 public boolean process(HServerInfo serverInfo, HMsg incomingMsg) { -326 if (!victim.getServerInfo().equals(serverInfo) || -327 this.abortSent || !this.closed) { -328 return true; -329 } -330 if (!incomingMsg.isType(HMsg.Type.MSG_REPORT_PROCESS_OPEN)) return true; -331 // Save the region that is in transition so can test later it came back. -332 this.regionToFind = incomingMsg.getRegionInfo(); -333 String msg = "ABORTING " + this.victim + " because got a " + -334 HMsg.Type.MSG_REPORT_PROCESS_OPEN + " on this server for " + -335 incomingMsg.getRegionInfo().getRegionNameAsString(); -336 this.victim.abort(msg); -337 this.abortSent = true; -338 return true; -339 } -340 -341 @Override -342 public boolean process(RegionServerOperation op) throws IOException { -343 return true; -344 } -345 -346 @Override -347 public void processed(RegionServerOperation op) { -348 if (this.closed || !(op instanceof ProcessRegionClose)) return; -349 ProcessRegionClose close = (ProcessRegionClose)op; -350 for (HRegion r: this.copyOfOnlineRegions) { -351 if (r.getRegionInfo().equals(close.regionInfo)) { -352 // We've closed one of the regions that was on the victim server. -353 // Now can start testing for when all regions are back online again -354 LOG.info("Found close of " + -355 r.getRegionInfo().getRegionNameAsString() + -356 "; setting close happened flag"); -357 this.closed = true; -358 break; -359 } -360 } -361 } -362 } -363 */ -364 /** -365 * In 2482, a RS with an opening region on it dies. The said region is then -366 * stuck in the master's regions-in-transition and never leaves it. This -367 * test works by bringing up a new regionserver, waiting for the load -368 * balancer to give it some regions. Then, we close all on the new server. -369 * After sending all the close messages, we send the new regionserver the -370 * special blocking message so it can not process any more messages. -371 * Meantime reopening of the just-closed regions is backed up on the new -372 * server. Soon as master gets an opening region from the new regionserver, -373 * we kill it. We then wait on all regions to come back on line. If bug -374 * is fixed, this should happen soon as the processing of the killed server is -375 * done. -376 * @see <a href="https://issues.apache.org/jira/browse/HBASE-2482">HBASE-2482</a> -377 */ -378 @Ignore @Test (timeout=300000) public void testKillRSWithOpeningRegion2482() -379 throws Exception { -380 /* -381 LOG.info("Running testKillRSWithOpeningRegion2482"); -382 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); -383 if (cluster.getLiveRegionServerThreads().size() < 2) { -384 // Need at least two servers. -385 cluster.startRegionServer(); -386 } -387 // Count how many regions are online. They need to be all back online for -388 // this test to succeed. -389 int countOfMetaRegions = countOfMetaRegions(); -390 // Add a listener on the server. -391 HMaster m = cluster.getMaster(); -392 // Start new regionserver. -393 MiniHBaseClusterRegionServer hrs = -394 (MiniHBaseClusterRegionServer)cluster.startRegionServer().getRegionServer(); -395 LOG.info("Started new regionserver: " + hrs.toString()); -396 // Wait until has some regions before proceeding. Balancer will give it some. -397 int minimumRegions = -398 countOfMetaRegions/(cluster.getRegionServerThreads().size() * 2); -399 while (hrs.getOnlineRegions().size() < minimumRegions) Threads.sleep(100); -400 // Set the listener only after some regions have been opened on new server. -401 HBase2482Listener listener = new HBase2482Listener(hrs); -402 m.getRegionServerOperationQueue(). -403 registerRegionServerOperationListener(listener); -404 try { -405 // Go close all non-catalog regions on this new server -406 closeAllNonCatalogRegions(cluster, hrs); -407 // After all closes, add blocking message before the region opens start to -408 // come in. -409 cluster.addMessageToSendRegionServer(hrs, -410 new HMsg(HMsg.Type.TESTING_BLOCK_REGIONSERVER)); -411 // Wait till one of the above close messages has an effect before we start -412 // wait on all regions back online. -413 while (!listener.closed) Threads.sleep(100); -414 LOG.info("Past close"); -415 // Make sure the abort server message was sent. -416 while(!listener.abortSent) Threads.sleep(100); -417 LOG.info("Past abort send; waiting on all regions to redeploy"); -418 // Now wait for regions to come back online. -419 assertRegionIsBackOnline(listener.regionToFind); -420 } finally { -421 m.getRegionServerOperationQueue(). -422 unregisterRegionServerOperationListener(listener); -423 } -424 */ -425 } -426 -427 /* -428 * @return Count of all non-catalog regions on the designated server -429 */ -430 /* -431 private int closeAllNonCatalogRegions(final MiniHBaseCluster cluster, -432 final MiniHBaseCluster.MiniHBaseClusterRegionServer hrs) -433 throws IOException { -434 int countOfRegions = 0; -435 for (HRegion r: hrs.getOnlineRegions()) { -436 if (r.getRegionInfo().isMetaRegion()) continue; -437 cluster.addMessageToSendRegionServer(hrs, -438 new HMsg(HMsg.Type.MSG_REGION_CLOSE, r.getRegionInfo())); -439 LOG.info("Sent close of " + r.getRegionInfo().getRegionNameAsString() + -440 " on " + hrs.toString()); -441 countOfRegions++; -442 } -443 return countOfRegions; -444 } -445 -446 private void assertRegionIsBackOnline(final HRegionInfo hri) -447 throws IOException { -448 // Region should have an entry in its startkey because of addRowToEachRegion. -449 byte [] row = getStartKey(hri); -450 HTable t = new HTable(TEST_UTIL.getConfiguration(), TABLENAME); -451 Get g = new Get(row); -452 assertTrue((t.get(g)).size() > 0); -453 } -454 -455 /* -456 * @return Count of regions in meta table. -457 * @throws IOException -458 */ -459 /* -460 private static int countOfMetaRegions() -461 throws IOException { -462 HTable meta = new HTable(TEST_UTIL.getConfiguration(), -463 HConstants.META_TABLE_NAME); -464 int rows = 0; -465 Scan scan = new Scan(); -466 scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER); -467 ResultScanner s = meta.getScanner(scan); -468 for (Result r = null; (r = s.next()) != null;) { -469 byte [] b = -470 r.getValue(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER); -471 if (b == null || b.length <= 0) break; -472 rows++; -473 } -474 s.close(); -475 return rows; -476 } -477 */ -478 /* -479 * Add to each of the regions in hbase:meta a value. Key is the startrow of the -480 * region (except its 'aaa' for first region). Actual value is the row name. -481 * @param expected -482 * @return -483 * @throws IOException -484 */ -485 private static int addToEachStartKey(final int expected) throws IOException { -486 Table t = TEST_UTIL.getConnection().getTable(TABLENAME); -487 Table meta = TEST_UTIL.getConnection().getTable(TableName.META_TABLE_NAME); -488 int rows = 0; -489 Scan scan = new Scan(); -490 scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER); -491 ResultScanner s = meta.getScanner(scan); -492 for (Result r = null; (r = s.next()) != null;) { -493 HRegionInfo hri = HRegionInfo.getHRegionInfo(r); -494 if (hri == null) break; -495 if (!hri.getTable().equals(TABLENAME)) { -496 continue; -497 } -498 -499 // If start key, add 'aaa'. -500 if(!hri.getTable().equals(TABLENAME)) { -501 continue; -502 } -503 byte [] row = getStartKey(hri); -504 Put p = new Put(row); -505 p.setDurability(Durability.SKIP_WAL); -506 p.addColumn(getTestFamily(), getTestQualifier(), row); -507 t.put(p); -508 rows++; -509 } -510 s.close(); -511 Assert.assertEquals(expected, rows); -512 t.close(); -513 meta.close(); -514 return rows; -515 } -516 -517 /* -518 * @param hri -519 * @return Start key for hri (If start key is '', then return 'aaa'. -520 */ -521 private static byte [] getStartKey(final HRegionInfo hri) { -522 return Bytes.equals(HConstants.EMPTY_START_ROW, hri.getStartKey())? -523 Bytes.toBytes("aaa"): hri.getStartKey(); -524 } -525 -526 private static byte [] getTestFamily() { -527 return FAMILIES[0]; -528 } -529 -530 private static byte [] getTestQualifier() { -531 return getTestFamily(); -532 } -533 } +28 import org.apache.hadoop.hbase.MetaTableAccessor; +29 import org.apache.hadoop.hbase.TableName; +30 import org.apache.hadoop.hbase.client.Durability; +31 import org.apache.hadoop.hbase.client.Put; +32 import org.apache.hadoop.hbase.client.RegionLocator; +33 import org.apache.hadoop.hbase.client.Result; +34 import org.apache.hadoop.hbase.client.ResultScanner; +35 import org.apache.hadoop.hbase.client.Scan; +36 import org.apache.hadoop.hbase.client.Table; +37 import org.apache.hadoop.hbase.testclassification.LargeTests; +38 import org.apache.hadoop.hbase.testclassification.MasterTests; +39 import org.apache.hadoop.hbase.util.Bytes; +40 import org.junit.AfterClass; +41 import org.junit.Assert; +42 import org.junit.Before; +43 import org.junit.BeforeClass; +44 import org.junit.Ignore; +45 import org.junit.Test; +46 import org.junit.experimental.categories.Category; +47 +48 /** +49 * Test transitions of state across the master. Sets up the cluster once and +50 * then runs a couple of tests. +51 */ +52 @Category({MasterTests.class, LargeTests.class}) +53 public class TestMasterTransitions { +54 private static final Log LOG = LogFactory.getLog(TestMasterTransitions.class); +55 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); +56 private static final TableName TABLENAME = TableName.valueOf("master_transitions"); +57 private static final byte [][] FAMILIES = new byte [][] {Bytes.toBytes("a"), +58 Bytes.toBytes("b"), Bytes.toBytes("c")}; +59 +60 /** +61 * Start up a mini cluster and put a small table of many empty regions into it. +62 * @throws Exception +63 */ +64 @BeforeClass public static void beforeAllTests() throws Exception { +65 TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true); +66 TEST_UTIL.startMiniCluster(2); +67 // Create a table of three families. This will assign a region. +68 TEST_UTIL.createMultiRegionTable(TABLENAME, FAMILIES); +69 Table t = TEST_UTIL.getConnection().getTable(TABLENAME); +70 int countOfRegions = -1; +71 try (RegionLocator r = TEST_UTIL.getConnection().getRegionLocator(TABLENAME)) { +72 countOfRegions = r.getStartKeys().length; +73 } +74 TEST_UTIL.waitUntilAllRegionsAssigned(TABLENAME); +75 addToEachStartKey(countOfRegions); +76 t.close(); +77 } +78 +79 @AfterClass public static void afterAllTests() throws Exception { +80 TEST_UTIL.shutdownMiniCluster(); +81 } +82 +83 @Before public void setup() throws IOException { +84 TEST_UTIL.ensureSomeRegionServersAvailable(2); +85 } +86 +87 /** +88 * Listener for regionserver events testing hbase-2428 (Infinite loop of +89 * region closes if hbase:meta region is offline). In particular, listen +90 * for the close of the 'metaServer' and when it comes in, requeue it with a +91 * delay as though there were an issue processing the shutdown. As part of +92 * the requeuing, send over a close of a region on 'otherServer' so it comes +93 * into a master that has its meta region marked as offline. +94 */ +95 /* +96 static class HBase2428Listener implements RegionServerOperationListener { +97 // Map of what we've delayed so we don't do do repeated delays. +98 private final Set<RegionServerOperation> postponed = +99 new CopyOnWriteArraySet<RegionServerOperation>(); +100 private boolean done = false;; +101 private boolean metaShutdownReceived = false; +102 private final HServerAddress metaAddress; +103 private final MiniHBaseCluster cluster; +104 private final int otherServerIndex; +105 private final HRegionInfo hri; +106 private int closeCount = 0; +107 static final int SERVER_DURATION = 3 * 1000; +108 static final int CLOSE_DURATION = 1 * 1000; +109 +110 HBase2428Listener(final MiniHBaseCluster c, final HServerAddress metaAddress, +111 final HRegionInfo closingHRI, final int otherServerIndex) { +112 this.cluster = c; +113 this.metaAddress = metaAddress; +114 this.hri = closingHRI; +115 this.otherServerIndex = otherServerIndex; +116 } +117 +118 @Override +119 public boolean process(final RegionServerOperation op) throws IOException { +120 // If a regionserver shutdown and its of the meta server, then we want to +121 // delay the processing of the shutdown and send off a close of a region on +122 // the 'otherServer. +123 boolean result = true; +124 if (op instanceof ProcessServerShutdown) { +125 ProcessServerShutdown pss = (ProcessServerShutdown)op; +126 if (pss.getDeadServerAddress().equals(this.metaAddress)) { +127 // Don't postpone more than once. +128 if (!this.postponed.contains(pss)) { +129 // Close some region. +130 this.cluster.addMessageToSendRegionServer(this.otherServerIndex, +131 new HMsg(HMsg.Type.MSG_REGION_CLOSE, hri, +132 Bytes.toBytes("Forcing close in test"))); +133 this.postponed.add(pss); +134 // Put off the processing of the regionserver shutdown processing. +135 pss.setDelay(SERVER_DURATION); +136 this.metaShutdownReceived = true; +137 // Return false. This will add this op to the delayed queue. +138 result = false; +139 } +140 } +141 } else { +142 // Have the close run frequently. +143 if (isWantedCloseOperation(op) != null) { +144 op.setDelay(CLOSE_DURATION); +145 // Count how many times it comes through here. +146 this.closeCount++; +147 } +148 } +149 return result; +150 } +151 +152 public void processed(final RegionServerOperation op) { +153 if (isWantedCloseOperation(op) != null) return; +154 this.done = true; +155 } +156 */ +157 /* +158 * @param op +159 * @return Null if not the wanted ProcessRegionClose, else <code>op</code> +160 * cast as a ProcessRegionClose. +161 */ +162 /* +163 private ProcessRegionClose isWantedCloseOperation(final RegionServerOperation op) { +164 // Count every time we get a close operation. +165 if (op instanceof ProcessRegionClose) { +166 ProcessRegionClose c = (ProcessRegionClose)op; +167 if (c.regionInfo.equals(hri)) { +168 return c; +169 } +170 } +171 return null; +172 } +173 +174 boolean isDone() { +175 return this.done; +176 } +177 +178 boolean isMetaShutdownReceived() { +179 return metaShutdownReceived; +180 } +181 +182 int getCloseCount() { +183 return this.closeCount; +184 } +185 +186 @Override +187 public boolean process(HServerInfo serverInfo, HMsg incomingMsg) { +188 return true; +189 } +190 } +191 */ +192 /** +193 * In 2428, the meta region has just been set offline and then a close comes +194 * in. +195 * @see <a href="https://issues.apache.org/jira/browse/HBASE-2428">HBASE-2428</a> +196 */ +197 @Ignore @Test (timeout=300000) public void testRegionCloseWhenNoMetaHBase2428() +198 throws Exception { +199 /* +200 LOG.info("Running testRegionCloseWhenNoMetaHBase2428"); +201 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); +202 final HMaster master = cluster.getMaster(); +203 int metaIndex = cluster.getServerWithMeta(); +204 // Figure the index of the server that is not server the hbase:meta +205 int otherServerIndex = -1; +206 for (int i = 0; i < cluster.getRegionServerThreads().size(); i++) { +207 if (i == metaIndex) continue; +208 otherServerIndex = i; +209 break; +210 } +211 final HRegionServer otherServer = cluster.getRegionServer(otherServerIndex); +212 final HRegionServer metaHRS = cluster.getRegionServer(metaIndex); +213 +214 // Get a region out on the otherServer. +215 final HRegionInfo hri = +216 otherServer.getOnlineRegions().iterator().next().getRegionInfo(); +217 +218 // Add our RegionServerOperationsListener [... 320 lines stripped ...]