View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.master;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertNotEquals;
22  import static org.junit.Assert.assertTrue;
23  import java.io.IOException;
24  import org.apache.hadoop.conf.Configuration;
25  import org.apache.hadoop.hbase.CoordinatedStateManager;
26  import org.apache.hadoop.hbase.HBaseTestingUtility;
27  import org.apache.hadoop.hbase.HRegionInfo;
28  import org.apache.hadoop.hbase.testclassification.MediumTests;
29  import org.apache.hadoop.hbase.MiniHBaseCluster;
30  import org.apache.hadoop.hbase.MiniHBaseCluster.MiniHBaseClusterRegionServer;
31  import org.apache.hadoop.hbase.ServerName;
32  import org.apache.hadoop.hbase.Waiter;
33  import org.apache.hadoop.hbase.util.Bytes;
34  import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
35  import org.apache.hadoop.hbase.zookeeper.ZKUtil;
36  import org.apache.zookeeper.KeeperException;
37  import org.junit.AfterClass;
38  import org.junit.BeforeClass;
39  import org.junit.Test;
40  import org.junit.experimental.categories.Category;
41  
42  /**
43   * Tests handling of meta-carrying region server failover.
44   */
45  @Category(MediumTests.class)
46  public class TestMetaShutdownHandler {
47    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
48    final static Configuration conf = TEST_UTIL.getConfiguration();
49  
50    @BeforeClass
51    public static void setUpBeforeClass() throws Exception {
52      TEST_UTIL.startMiniCluster(1, 3, null, null, MyRegionServer.class);
53    }
54  
55    @AfterClass
56    public static void tearDownAfterClass() throws Exception {
57      TEST_UTIL.shutdownMiniCluster();
58    }
59  
60    /**
61     * This test will test the expire handling of a meta-carrying
62     * region server.
63     * After HBaseMiniCluster is up, we will delete the ephemeral
64     * node of the meta-carrying region server, which will trigger
65     * the expire of this region server on the master.
66     * On the other hand, we will slow down the abort process on
67     * the region server so that it is still up during the master SSH.
68     * We will check that the master SSH is still successfully done.
69     */
70    @Test (timeout=180000)
71    public void testExpireMetaRegionServer() throws Exception {
72      MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
73  
74      HMaster master = cluster.getMaster();
75      RegionStates regionStates = master.getAssignmentManager().getRegionStates();
76      ServerName metaServerName = regionStates.getRegionServerOfRegion(
77        HRegionInfo.FIRST_META_REGIONINFO);
78      if (master.getServerName().equals(metaServerName) || metaServerName == null
79          || !metaServerName.equals(cluster.getServerHoldingMeta())) {
80        // Move meta off master
81        metaServerName = cluster.getLiveRegionServerThreads()
82            .get(0).getRegionServer().getServerName();
83        master.move(HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes(),
84          Bytes.toBytes(metaServerName.getServerName()));
85        TEST_UTIL.waitUntilNoRegionsInTransition(60000);
86      }
87      RegionState metaState =
88          MetaTableLocator.getMetaRegionState(master.getZooKeeper());
89      assertEquals("Meta should be not in transition",
90        metaState.getState(), RegionState.State.OPEN);
91      assertNotEquals("Meta should be moved off master",
92        metaServerName, master.getServerName());
93  
94      // Delete the ephemeral node of the meta-carrying region server.
95      // This is trigger the expire of this region server on the master.
96      String rsEphemeralNodePath =
97          ZKUtil.joinZNode(master.getZooKeeper().rsZNode, metaServerName.toString());
98      ZKUtil.deleteNode(master.getZooKeeper(), rsEphemeralNodePath);
99      // Wait for SSH to finish
100     final ServerManager serverManager = master.getServerManager();
101     final ServerName priorMetaServerName = metaServerName;
102     TEST_UTIL.waitFor(120000, 200, new Waiter.Predicate<Exception>() {
103       @Override
104       public boolean evaluate() throws Exception {
105         return !serverManager.isServerOnline(priorMetaServerName)
106             && !serverManager.areDeadServersInProgress();
107       }
108     });
109 
110     TEST_UTIL.waitUntilNoRegionsInTransition(60000);
111     // Now, make sure meta is assigned
112     assertTrue("Meta should be assigned",
113       regionStates.isRegionOnline(HRegionInfo.FIRST_META_REGIONINFO));
114     // Now, make sure meta is registered in zk
115     metaState = MetaTableLocator.getMetaRegionState(master.getZooKeeper());
116     assertEquals("Meta should be not in transition",
117       metaState.getState(), RegionState.State.OPEN);
118     assertEquals("Meta should be assigned", metaState.getServerName(),
119       regionStates.getRegionServerOfRegion(HRegionInfo.FIRST_META_REGIONINFO));
120     assertNotEquals("Meta should be assigned on a different server",
121       metaState.getServerName(), metaServerName);
122   }
123 
124   public static class MyRegionServer extends MiniHBaseClusterRegionServer {
125 
126     public MyRegionServer(Configuration conf, CoordinatedStateManager cp)
127       throws IOException, KeeperException,
128         InterruptedException {
129       super(conf, cp);
130     }
131 
132     @Override
133     public void abort(String reason, Throwable cause) {
134       // sleep to slow down the region server abort
135       try {
136         Thread.sleep(30*1000);
137       } catch (InterruptedException e) {
138         return;
139       }
140       super.abort(reason, cause);
141     }
142   }
143 }