1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client;
20
21 import javax.annotation.Nullable;
22
23 import java.io.IOException;
24 import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.assertErrors;
25 import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.doFsck;
26 import static org.junit.Assert.*;
27
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.List;
31 import java.util.concurrent.ExecutorService;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.hbase.Abortable;
37 import org.apache.hadoop.hbase.HBaseTestingUtility;
38 import org.apache.hadoop.hbase.HConstants;
39 import org.apache.hadoop.hbase.HRegionInfo;
40 import org.apache.hadoop.hbase.HRegionLocation;
41 import org.apache.hadoop.hbase.MetaTableAccessor;
42 import org.apache.hadoop.hbase.RegionLocations;
43 import org.apache.hadoop.hbase.ServerName;
44 import org.apache.hadoop.hbase.TableName;
45 import org.apache.hadoop.hbase.TableNotFoundException;
46 import org.apache.hadoop.hbase.Waiter;
47 import org.apache.hadoop.hbase.client.ConnectionManager.HConnectionImplementation;
48 import org.apache.hadoop.hbase.regionserver.StorefileRefresherChore;
49 import org.apache.hadoop.hbase.testclassification.MediumTests;
50 import org.apache.hadoop.hbase.util.Bytes;
51 import org.apache.hadoop.hbase.util.HBaseFsck;
52 import org.apache.hadoop.hbase.util.HBaseFsckRepair;
53 import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter.ERROR_CODE;
54 import org.apache.hadoop.hbase.util.hbck.HbckTestingUtil;
55 import org.apache.hadoop.hbase.zookeeper.LoadBalancerTracker;
56 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
57 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
58 import org.junit.After;
59 import org.junit.Before;
60 import org.junit.Test;
61 import org.junit.experimental.categories.Category;
62
63
64
65
66 @Category(MediumTests.class)
67 public class TestMetaWithReplicas {
68 static final Log LOG = LogFactory.getLog(TestMetaWithReplicas.class);
69 private final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
70
71 @Before
72 public void setup() throws Exception {
73 TEST_UTIL.getConfiguration().setInt("zookeeper.session.timeout", 30000);
74 TEST_UTIL.getConfiguration().setInt(HConstants.META_REPLICAS_NUM, 3);
75 TEST_UTIL.getConfiguration().setInt(
76 StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD, 1000);
77 TEST_UTIL.startMiniCluster(3);
78
79 LoadBalancerTracker l = new LoadBalancerTracker(TEST_UTIL.getZooKeeperWatcher(),
80 new Abortable() {
81 boolean aborted = false;
82 @Override
83 public boolean isAborted() {
84 return aborted;
85 }
86 @Override
87 public void abort(String why, Throwable e) {
88 aborted = true;
89 }
90 });
91 l.setBalancerOn(false);
92 for (int replicaId = 1; replicaId < 3; replicaId ++) {
93 HRegionInfo h = RegionReplicaUtil.getRegionInfoForReplica(HRegionInfo.FIRST_META_REGIONINFO,
94 replicaId);
95 TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager().waitForAssignment(h);
96 }
97 LOG.debug("All meta replicas assigned");
98 }
99
100 @After
101 public void tearDown() throws Exception {
102 TEST_UTIL.shutdownMiniCluster();
103 }
104
105 @Test
106 public void testMetaHTDReplicaCount() throws Exception {
107 assertTrue(TEST_UTIL.getHBaseAdmin().getTableDescriptor(TableName.META_TABLE_NAME)
108 .getRegionReplication() == 3);
109 }
110
111 @Test
112 public void testZookeeperNodesForReplicas() throws Exception {
113
114 ZooKeeperWatcher zkw = TEST_UTIL.getZooKeeperWatcher();
115 Configuration conf = TEST_UTIL.getConfiguration();
116 String baseZNode = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT,
117 HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT);
118 String primaryMetaZnode = ZKUtil.joinZNode(baseZNode,
119 conf.get("zookeeper.znode.metaserver", "meta-region-server"));
120
121 byte[] data = ZKUtil.getData(zkw, primaryMetaZnode);
122 ServerName.parseFrom(data);
123 for (int i = 1; i < 3; i++) {
124 String secZnode = ZKUtil.joinZNode(baseZNode,
125 conf.get("zookeeper.znode.metaserver", "meta-region-server") + "-" + i);
126 String str = zkw.getZNodeForReplica(i);
127 assertTrue(str.equals(secZnode));
128
129 data = ZKUtil.getData(zkw, secZnode);
130 ServerName.parseFrom(data);
131 }
132 }
133
134 @Test
135 public void testShutdownHandling() throws Exception {
136
137
138
139
140 shutdownMetaAndDoValidations(TEST_UTIL);
141 }
142
143 public static void shutdownMetaAndDoValidations(HBaseTestingUtility util) throws Exception {
144
145
146
147
148 ZooKeeperWatcher zkw = util.getZooKeeperWatcher();
149 Configuration conf = util.getConfiguration();
150 conf.setBoolean(HConstants.USE_META_REPLICAS, true);
151
152 String baseZNode = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT,
153 HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT);
154 String primaryMetaZnode = ZKUtil.joinZNode(baseZNode,
155 conf.get("zookeeper.znode.metaserver", "meta-region-server"));
156 byte[] data = ZKUtil.getData(zkw, primaryMetaZnode);
157 ServerName primary = ServerName.parseFrom(data);
158
159 byte[] TABLE = Bytes.toBytes("testShutdownHandling");
160 byte[][] FAMILIES = new byte[][] { Bytes.toBytes("foo") };
161 if (util.getHBaseAdmin().tableExists(TABLE)) {
162 util.getHBaseAdmin().disableTable(TABLE);
163 util.getHBaseAdmin().deleteTable(TABLE);
164 }
165 Table htable = util.createTable(TABLE, FAMILIES, conf);
166
167 util.getHBaseAdmin().flush(TableName.META_TABLE_NAME);
168 Thread.sleep(conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD,
169 30000) * 6);
170 Connection c = ConnectionFactory.createConnection(util.getConfiguration());
171 List<HRegionInfo> regions = MetaTableAccessor.getTableRegions(zkw, c,
172 TableName.valueOf(TABLE));
173 HRegionLocation hrl = MetaTableAccessor.getRegionLocation(c, regions.get(0));
174
175
176
177
178
179 if (hrl.getServerName().equals(primary)) {
180 util.getHBaseAdmin().move(hrl.getRegionInfo().getEncodedNameAsBytes(), null);
181
182 do {
183 Thread.sleep(10);
184 hrl = MetaTableAccessor.getRegionLocation(c, regions.get(0));
185 } while (primary.equals(hrl.getServerName()));
186 util.getHBaseAdmin().flush(TableName.META_TABLE_NAME);
187 Thread.sleep(conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD,
188 30000) * 3);
189 }
190 ServerName master = util.getHBaseClusterInterface().getClusterStatus().getMaster();
191
192
193 util.getHBaseClusterInterface().stopMaster(master);
194 util.getHBaseClusterInterface().waitForMasterToStop(master, 60000);
195 if (!master.equals(primary)) {
196 util.getHBaseClusterInterface().killRegionServer(primary);
197 util.getHBaseClusterInterface().waitForRegionServerToStop(primary, 60000);
198 }
199 ((ClusterConnection)c).clearRegionCache();
200 htable.close();
201 htable = c.getTable(TableName.valueOf(TABLE));
202 byte[] row = "test".getBytes();
203 Put put = new Put(row);
204 put.add("foo".getBytes(), row, row);
205 BufferedMutator m = c.getBufferedMutator(TableName.valueOf(TABLE));
206 m.mutate(put);
207 m.flush();
208
209 Get get = new Get(row);
210 Result r = htable.get(get);
211 assertTrue(Arrays.equals(r.getRow(), row));
212
213
214 util.getHBaseClusterInterface().startMaster(master.getHostname(), 0);
215 util.getHBaseClusterInterface().startRegionServer(primary.getHostname(), 0);
216 util.getHBaseClusterInterface().waitForActiveAndReadyMaster();
217 ((ClusterConnection)c).clearRegionCache();
218 htable.close();
219 conf.setBoolean(HConstants.USE_META_REPLICAS, false);
220 htable = c.getTable(TableName.valueOf(TABLE));
221 r = htable.get(get);
222 assertTrue(Arrays.equals(r.getRow(), row));
223 }
224
225 @Test
226 public void testMetaLookupThreadPoolCreated() throws Exception {
227 byte[] TABLE = Bytes.toBytes("testMetaLookupThreadPoolCreated");
228 byte[][] FAMILIES = new byte[][] { Bytes.toBytes("foo") };
229 if (TEST_UTIL.getHBaseAdmin().tableExists(TABLE)) {
230 TEST_UTIL.getHBaseAdmin().disableTable(TABLE);
231 TEST_UTIL.getHBaseAdmin().deleteTable(TABLE);
232 }
233 Table htable = TEST_UTIL.createTable(TABLE, FAMILIES, TEST_UTIL.getConfiguration());
234 byte[] row = "test".getBytes();
235 HConnectionImplementation c = ((HConnectionImplementation)((HTable)htable).connection);
236
237 c.relocateRegion(TABLE, row);
238 ExecutorService ex = c.getCurrentMetaLookupPool();
239 assert(ex != null);
240 }
241
242 @Test
243 public void testChangingReplicaCount() throws Exception {
244
245
246 stopMasterAndValidateReplicaCount(3, 2);
247
248 stopMasterAndValidateReplicaCount(2, 3);
249 }
250
251 private void stopMasterAndValidateReplicaCount(int originalReplicaCount, int newReplicaCount)
252 throws Exception {
253 ServerName sn = TEST_UTIL.getHBaseClusterInterface().getClusterStatus().getMaster();
254 TEST_UTIL.getHBaseClusterInterface().stopMaster(sn);
255 TEST_UTIL.getHBaseClusterInterface().waitForMasterToStop(sn, 60000);
256 List<String> metaZnodes = TEST_UTIL.getZooKeeperWatcher().getMetaReplicaNodes();
257 assert(metaZnodes.size() == originalReplicaCount);
258 TEST_UTIL.getHBaseClusterInterface().getConf().setInt(HConstants.META_REPLICAS_NUM,
259 newReplicaCount);
260 TEST_UTIL.getHBaseClusterInterface().startMaster(sn.getHostname(), 0);
261 TEST_UTIL.getHBaseClusterInterface().waitForActiveAndReadyMaster();
262 int count = 0;
263 do {
264 metaZnodes = TEST_UTIL.getZooKeeperWatcher().getMetaReplicaNodes();
265 Thread.sleep(10);
266 count++;
267
268
269
270 } while (metaZnodes.size() == originalReplicaCount && count < 1000);
271 assert(metaZnodes.size() == newReplicaCount);
272
273 TEST_UTIL.getConfiguration().setInt(HConstants.META_REPLICAS_NUM,
274 newReplicaCount);
275 HBaseFsck hbck = HbckTestingUtil.doFsck(TEST_UTIL.getConfiguration(), false);
276 HbckTestingUtil.assertNoErrors(hbck);
277 }
278
279 @Test
280 public void testHBaseFsckWithMetaReplicas() throws Exception {
281 HBaseFsck hbck = HbckTestingUtil.doFsck(TEST_UTIL.getConfiguration(), false);
282 HbckTestingUtil.assertNoErrors(hbck);
283 }
284
285 @Test
286 public void testHBaseFsckWithFewerMetaReplicas() throws Exception {
287 ClusterConnection c = (ClusterConnection)ConnectionFactory.createConnection(
288 TEST_UTIL.getConfiguration());
289 RegionLocations rl = c.locateRegion(TableName.META_TABLE_NAME, HConstants.EMPTY_START_ROW,
290 false, false);
291 HBaseFsckRepair.closeRegionSilentlyAndWait(c,
292 rl.getRegionLocation(1).getServerName(), rl.getRegionLocation(1).getRegionInfo());
293
294 HBaseFsck hbck = doFsck(TEST_UTIL.getConfiguration(), false);
295 assertErrors(hbck, new ERROR_CODE[]{ERROR_CODE.UNKNOWN,ERROR_CODE.NO_META_REGION});
296
297 hbck = doFsck(TEST_UTIL.getConfiguration(), true);
298
299 hbck = doFsck(TEST_UTIL.getConfiguration(), false);
300 assertErrors(hbck, new ERROR_CODE[]{});
301 }
302
303 @Test
304 public void testHBaseFsckWithFewerMetaReplicaZnodes() throws Exception {
305 ClusterConnection c = (ClusterConnection)ConnectionFactory.createConnection(
306 TEST_UTIL.getConfiguration());
307 RegionLocations rl = c.locateRegion(TableName.META_TABLE_NAME, HConstants.EMPTY_START_ROW,
308 false, false);
309 HBaseFsckRepair.closeRegionSilentlyAndWait(c,
310 rl.getRegionLocation(2).getServerName(), rl.getRegionLocation(2).getRegionInfo());
311 ZooKeeperWatcher zkw = TEST_UTIL.getZooKeeperWatcher();
312 ZKUtil.deleteNode(zkw, zkw.getZNodeForReplica(2));
313
314 HBaseFsck hbck = doFsck(TEST_UTIL.getConfiguration(), false);
315 assertErrors(hbck, new ERROR_CODE[]{ERROR_CODE.UNKNOWN,ERROR_CODE.NO_META_REGION});
316
317 hbck = doFsck(TEST_UTIL.getConfiguration(), true);
318
319 hbck = doFsck(TEST_UTIL.getConfiguration(), false);
320 assertErrors(hbck, new ERROR_CODE[]{});
321 }
322
323 @Test
324 public void testAccessingUnknownTables() throws Exception {
325 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
326 conf.setBoolean(HConstants.USE_META_REPLICAS, true);
327 Table table = TEST_UTIL.getConnection().getTable(TableName.valueOf("RandomTable"));
328 Get get = new Get(Bytes.toBytes("foo"));
329 try {
330 table.get(get);
331 } catch (TableNotFoundException t) {
332 return;
333 }
334 fail("Expected TableNotFoundException");
335 }
336
337 @Test
338 public void testMetaAddressChange() throws Exception {
339
340
341
342 Configuration conf = TEST_UTIL.getConfiguration();
343 ZooKeeperWatcher zkw = TEST_UTIL.getZooKeeperWatcher();
344 String baseZNode = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT,
345 HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT);
346 String primaryMetaZnode = ZKUtil.joinZNode(baseZNode,
347 conf.get("zookeeper.znode.metaserver", "meta-region-server"));
348
349 byte[] data = ZKUtil.getData(zkw, primaryMetaZnode);
350 ServerName currentServer = ServerName.parseFrom(data);
351 Collection<ServerName> liveServers = TEST_UTIL.getHBaseAdmin().getClusterStatus().getServers();
352 ServerName moveToServer = null;
353 for (ServerName s : liveServers) {
354 if (!currentServer.equals(s)) {
355 moveToServer = s;
356 }
357 }
358 assert(moveToServer != null);
359 String tableName = "randomTable5678";
360 TEST_UTIL.createTable(TableName.valueOf(tableName), "f");
361 assertTrue(TEST_UTIL.getHBaseAdmin().tableExists(tableName));
362 TEST_UTIL.getHBaseAdmin().move(HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes(),
363 Bytes.toBytes(moveToServer.getServerName()));
364 int i = 0;
365 do {
366 Thread.sleep(10);
367 data = ZKUtil.getData(zkw, primaryMetaZnode);
368 currentServer = ServerName.parseFrom(data);
369 i++;
370 } while (!moveToServer.equals(currentServer) && i < 1000);
371 assert(i != 1000);
372 TEST_UTIL.getHBaseAdmin().disableTable("randomTable5678");
373 assertTrue(TEST_UTIL.getHBaseAdmin().isTableDisabled("randomTable5678"));
374 }
375
376 @Test
377 public void testShutdownOfReplicaHolder() throws Exception {
378
379
380 RegionLocations rl = ConnectionManager.getConnectionInternal(TEST_UTIL.getConfiguration()).
381 locateRegion(TableName.META_TABLE_NAME, Bytes.toBytes(""), false, true);
382 HRegionLocation hrl = rl.getRegionLocation(1);
383 ServerName oldServer = hrl.getServerName();
384 TEST_UTIL.getHBaseClusterInterface().killRegionServer(oldServer);
385 int i = 0;
386 do {
387 LOG.debug("Waiting for the replica " + hrl.getRegionInfo() + " to come up");
388 Thread.sleep(30000);
389 rl = ConnectionManager.getConnectionInternal(TEST_UTIL.getConfiguration()).
390 locateRegion(TableName.META_TABLE_NAME, Bytes.toBytes(""), false, true);
391 hrl = rl.getRegionLocation(1);
392 i++;
393 } while ((hrl == null || hrl.getServerName().equals(oldServer)) && i < 3);
394 assertTrue(i != 3);
395 }
396
397 @Test
398 public void testHBaseFsckWithExcessMetaReplicas() throws Exception {
399 HBaseFsck hbck = new HBaseFsck(TEST_UTIL.getConfiguration());
400
401 HRegionInfo h = RegionReplicaUtil.getRegionInfoForReplica(
402 HRegionInfo.FIRST_META_REGIONINFO, 3);
403
404 TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager()
405 .getRegionStates().createRegionState(h);
406 TEST_UTIL.getMiniHBaseCluster().getMaster().assignRegion(h);
407 HBaseFsckRepair.waitUntilAssigned(TEST_UTIL.getHBaseAdmin(), h);
408
409 hbck = doFsck(TEST_UTIL.getConfiguration(), false);
410 assertErrors(hbck, new ERROR_CODE[]{ERROR_CODE.UNKNOWN, ERROR_CODE.SHOULD_NOT_BE_DEPLOYED});
411
412 hbck = doFsck(TEST_UTIL.getConfiguration(), true);
413
414 hbck = doFsck(TEST_UTIL.getConfiguration(), false);
415 assertErrors(hbck, new ERROR_CODE[]{});
416 }
417 }