1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertTrue;
24
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.hbase.HBaseTestingUtility;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.HRegionInfo;
34 import org.apache.hadoop.hbase.MiniHBaseCluster;
35 import org.apache.hadoop.hbase.ServerName;
36 import org.apache.hadoop.hbase.TableExistsException;
37 import org.apache.hadoop.hbase.TableName;
38 import org.apache.hadoop.hbase.client.Connection;
39 import org.apache.hadoop.hbase.client.ConnectionFactory;
40 import org.apache.hadoop.hbase.client.MetaScanner;
41 import org.apache.hadoop.hbase.executor.EventType;
42 import org.apache.hadoop.hbase.testclassification.LargeTests;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.apache.hadoop.hbase.util.JVMClusterUtil;
45 import org.apache.hadoop.hbase.util.Threads;
46 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
47 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
48 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
49 import org.junit.After;
50 import org.junit.Test;
51 import org.junit.experimental.categories.Category;
52
53 @Category(LargeTests.class)
54 public class TestRestartCluster {
55 private static final Log LOG = LogFactory.getLog(TestRestartCluster.class);
56 private HBaseTestingUtility UTIL = new HBaseTestingUtility();
57
58 private static final byte[] TABLENAME = Bytes.toBytes("master_transitions");
59 private static final byte [][] FAMILIES = {Bytes.toBytes("a")};
60 private static final TableName[] TABLES = {
61 TableName.valueOf("restartTableOne"),
62 TableName.valueOf("restartTableTwo"),
63 TableName.valueOf("restartTableThree")
64 };
65 private static final byte [] FAMILY = Bytes.toBytes("family");
66
67 @After public void tearDown() throws Exception {
68 UTIL.shutdownMiniCluster();
69 }
70
71 @Test (timeout=300000) public void testRestartClusterAfterKill()
72 throws Exception {
73 UTIL.getConfiguration().setBoolean("hbase.assignment.usezk", true);
74 UTIL.startMiniZKCluster();
75 ZooKeeperWatcher zooKeeper =
76 new ZooKeeperWatcher(UTIL.getConfiguration(), "cluster1", null, true);
77
78
79 String unassignedZNode = zooKeeper.assignmentZNode;
80 ZKUtil.createAndFailSilent(zooKeeper, unassignedZNode);
81
82 ServerName sn = ServerName.valueOf(HMaster.MASTER, 1, System.currentTimeMillis());
83
84 ZKAssign.createNodeOffline(zooKeeper, HRegionInfo.FIRST_META_REGIONINFO, sn);
85
86 LOG.debug("Created UNASSIGNED zNode for ROOT and hbase:meta regions in state " +
87 EventType.M_ZK_REGION_OFFLINE);
88
89
90 LOG.info("Starting HBase cluster...");
91 UTIL.startMiniCluster(2);
92
93 UTIL.createTable(TABLENAME, FAMILIES);
94 LOG.info("Created a table, waiting for table to be available...");
95 UTIL.waitTableAvailable(TABLENAME, 60*1000);
96
97 LOG.info("Master deleted unassigned region and started up successfully.");
98 }
99
100 @Test (timeout=300000)
101 public void testClusterRestart() throws Exception {
102 UTIL.startMiniCluster(3);
103 Connection connection = UTIL.getConnection();
104
105 while (!UTIL.getMiniHBaseCluster().getMaster().isInitialized()) {
106 Threads.sleep(1);
107 }
108 LOG.info("\n\nCreating tables");
109 for(TableName TABLE : TABLES) {
110 UTIL.createTable(TABLE, FAMILY);
111 }
112 for(TableName TABLE : TABLES) {
113 UTIL.waitTableEnabled(TABLE);
114 }
115
116 List<HRegionInfo> allRegions =
117 MetaScanner.listAllRegions(UTIL.getConfiguration(), connection, true);
118 assertEquals(4, allRegions.size());
119
120 LOG.info("\n\nShutting down cluster");
121 UTIL.shutdownMiniHBaseCluster();
122
123 LOG.info("\n\nSleeping a bit");
124 Thread.sleep(2000);
125
126 LOG.info("\n\nStarting cluster the second time");
127 UTIL.restartHBaseCluster(3);
128
129
130
131
132 connection = UTIL.getConnection();
133 allRegions =
134 MetaScanner.listAllRegions(new Configuration(UTIL.getConfiguration()), connection, true);
135 assertEquals(4, allRegions.size());
136 LOG.info("\n\nWaiting for tables to be available");
137 for(TableName TABLE: TABLES) {
138 try {
139 UTIL.createTable(TABLE, FAMILY);
140 assertTrue("Able to create table that should already exist", false);
141 } catch(TableExistsException tee) {
142 LOG.info("Table already exists as expected");
143 }
144 UTIL.waitTableAvailable(TABLE);
145 }
146 }
147
148
149
150
151 @Test (timeout=300000)
152 public void testRetainAssignmentOnRestart() throws Exception {
153 UTIL.startMiniCluster(2);
154 while (!UTIL.getMiniHBaseCluster().getMaster().isInitialized()) {
155 Threads.sleep(1);
156 }
157
158 UTIL.getMiniHBaseCluster().getMaster().
159 getMasterRpcServices().synchronousBalanceSwitch(false);
160 LOG.info("\n\nCreating tables");
161 for(TableName TABLE : TABLES) {
162 UTIL.createTable(TABLE, FAMILY);
163 }
164 for(TableName TABLE : TABLES) {
165 UTIL.waitTableEnabled(TABLE);
166 }
167
168 HMaster master = UTIL.getMiniHBaseCluster().getMaster();
169 AssignmentManager am = master.getAssignmentManager();
170 am.waitUntilNoRegionsInTransition(120000);
171
172
173
174 SnapshotOfRegionAssignmentFromMeta snapshot = new SnapshotOfRegionAssignmentFromMeta(
175 master.getConnection());
176 snapshot.initialize();
177 Map<HRegionInfo, ServerName> regionToRegionServerMap
178 = snapshot.getRegionToRegionServerMap();
179
180 MiniHBaseCluster cluster = UTIL.getHBaseCluster();
181 List<JVMClusterUtil.RegionServerThread> threads = cluster.getLiveRegionServerThreads();
182 assertEquals(2, threads.size());
183 int[] rsPorts = new int[2];
184 for (int i = 0; i < 2; i++) {
185 rsPorts[i] = threads.get(i).getRegionServer().getServerName().getPort();
186 }
187 for (ServerName serverName: regionToRegionServerMap.values()) {
188 boolean found = false;
189 for (int k = 0; k < 2 && !found; k++) {
190 found = serverName.getPort() == rsPorts[k];
191 }
192 assertTrue(found);
193 }
194
195 LOG.info("\n\nShutting down HBase cluster");
196 cluster.shutdown();
197 cluster.waitUntilShutDown();
198
199 LOG.info("\n\nSleeping a bit");
200 Thread.sleep(2000);
201
202 LOG.info("\n\nStarting cluster the second time with the same ports");
203 try {
204 cluster.getConf().setInt(
205 ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, 2);
206 master = cluster.startMaster().getMaster();
207 for (int i = 0; i < 2; i++) {
208 cluster.getConf().setInt(HConstants.REGIONSERVER_PORT, rsPorts[i]);
209 cluster.startRegionServer();
210 }
211 } finally {
212
213 cluster.getConf().setInt(HConstants.REGIONSERVER_PORT, 0);
214 cluster.getConf().setInt(
215 ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, 1);
216 }
217
218
219 List<ServerName> localServers = master.getServerManager().getOnlineServersList();
220 assertEquals(2, localServers.size());
221 for (int i = 0; i < 2; i++) {
222 boolean found = false;
223 for (ServerName serverName: localServers) {
224 if (serverName.getPort() == rsPorts[i]) {
225 found = true;
226 break;
227 }
228 }
229 assertTrue(found);
230 }
231
232
233 RegionStates regionStates = master.getAssignmentManager().getRegionStates();
234 int expectedRegions = regionToRegionServerMap.size() + 1;
235 while (!master.isInitialized()
236 || regionStates.getRegionAssignments().size() != expectedRegions) {
237 Threads.sleep(100);
238 }
239
240 snapshot =new SnapshotOfRegionAssignmentFromMeta(master.getConnection());
241 snapshot.initialize();
242 Map<HRegionInfo, ServerName> newRegionToRegionServerMap =
243 snapshot.getRegionToRegionServerMap();
244 assertEquals(regionToRegionServerMap.size(), newRegionToRegionServerMap.size());
245 for (Map.Entry<HRegionInfo, ServerName> entry: newRegionToRegionServerMap.entrySet()) {
246 if (TableName.NAMESPACE_TABLE_NAME.equals(entry.getKey().getTable())) continue;
247 ServerName oldServer = regionToRegionServerMap.get(entry.getKey());
248 ServerName currentServer = entry.getValue();
249 assertEquals(oldServer.getHostAndPort(), currentServer.getHostAndPort());
250 assertNotEquals(oldServer.getStartcode(), currentServer.getStartcode());
251 }
252 }
253 }