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