1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver;
19
20 import static org.junit.Assert.assertArrayEquals;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.NavigableMap;
30 import java.util.Random;
31 import java.util.Set;
32 import java.util.TreeSet;
33 import java.util.concurrent.TimeUnit;
34
35 import org.apache.commons.io.IOUtils;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.hadoop.conf.Configuration;
39 import org.apache.hadoop.hbase.ChoreService;
40 import org.apache.hadoop.hbase.HBaseTestingUtility;
41 import org.apache.hadoop.hbase.HColumnDescriptor;
42 import org.apache.hadoop.hbase.HConstants;
43 import org.apache.hadoop.hbase.HRegionInfo;
44 import org.apache.hadoop.hbase.HRegionLocation;
45 import org.apache.hadoop.hbase.HTableDescriptor;
46 import org.apache.hadoop.hbase.MetaTableAccessor;
47 import org.apache.hadoop.hbase.NotServingRegionException;
48 import org.apache.hadoop.hbase.ScheduledChore;
49 import org.apache.hadoop.hbase.ServerName;
50 import org.apache.hadoop.hbase.Stoppable;
51 import org.apache.hadoop.hbase.TableName;
52 import org.apache.hadoop.hbase.client.Admin;
53 import org.apache.hadoop.hbase.client.Connection;
54 import org.apache.hadoop.hbase.client.ConnectionFactory;
55 import org.apache.hadoop.hbase.client.Get;
56 import org.apache.hadoop.hbase.client.HTable;
57 import org.apache.hadoop.hbase.client.MetaScanner;
58 import org.apache.hadoop.hbase.client.Put;
59 import org.apache.hadoop.hbase.client.Result;
60 import org.apache.hadoop.hbase.client.Scan;
61 import org.apache.hadoop.hbase.client.Table;
62 import org.apache.hadoop.hbase.coordination.BaseCoordinatedStateManager;
63 import org.apache.hadoop.hbase.ipc.HBaseRpcControllerImpl;
64 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
65 import org.apache.hadoop.hbase.protobuf.RequestConverter;
66 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState;
67 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
68 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
69 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos;
70 import org.apache.hadoop.hbase.testclassification.LargeTests;
71 import org.apache.hadoop.hbase.util.Bytes;
72 import org.apache.hadoop.hbase.util.Pair;
73 import org.apache.hadoop.hbase.util.PairOfSameType;
74 import org.apache.hadoop.hbase.util.RetryCounter;
75 import org.apache.hadoop.hbase.util.StoppableImplementation;
76 import org.apache.hadoop.hbase.util.Threads;
77 import org.junit.AfterClass;
78 import org.junit.Assert;
79 import org.junit.BeforeClass;
80 import org.junit.Test;
81 import org.junit.experimental.categories.Category;
82
83 import com.google.common.collect.Iterators;
84 import com.google.common.collect.Maps;
85 import com.google.common.collect.Sets;
86 import com.google.protobuf.ServiceException;
87
88 @Category(LargeTests.class)
89 public class TestEndToEndSplitTransaction {
90 private static final Log LOG = LogFactory.getLog(TestEndToEndSplitTransaction.class);
91 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
92 private static final Configuration CONF = TEST_UTIL.getConfiguration();
93
94 @BeforeClass
95 public static void beforeAllTests() throws Exception {
96 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 5);
97 TEST_UTIL.startMiniCluster();
98 }
99
100 @AfterClass
101 public static void afterAllTests() throws Exception {
102 TEST_UTIL.shutdownMiniCluster();
103 }
104
105
106
107
108
109
110 @Test
111 public void testCanSplitJustAfterASplit() throws Exception {
112 LOG.info("Starting testCanSplitJustAfterASplit");
113 byte[] fam = Bytes.toBytes("cf_split");
114
115 TableName tableName = TableName.valueOf("CanSplitTable");
116 Table source = TEST_UTIL.getConnection().getTable(tableName);
117 Admin admin = TEST_UTIL.getHBaseAdmin();
118 Map<String, StoreFile.Reader> scanner = Maps.newHashMap();
119
120 try {
121 HTableDescriptor htd = new HTableDescriptor(tableName);
122 htd.addFamily(new HColumnDescriptor(fam));
123
124 admin.createTable(htd);
125 TEST_UTIL.loadTable(source, fam);
126 List<HRegion> regions = TEST_UTIL.getHBaseCluster().getRegions(tableName);
127 regions.get(0).forceSplit(null);
128 admin.split(tableName);
129
130 while (regions.size() <= 1) {
131 regions = TEST_UTIL.getHBaseCluster().getRegions(tableName);
132
133
134 for (HRegion region : regions) {
135 for (Store store : region.getStores()) {
136 for (StoreFile file : store.getStorefiles()) {
137 StoreFile.Reader reader = file.getReader();
138 reader.getStoreFileScanner(false, false, false, 0, 0, false);
139 scanner.put(region.getRegionInfo().getEncodedName(), reader);
140 LOG.info("Got reference to file = " + file.getPath() + ",for region = "
141 + region.getRegionInfo().getEncodedName());
142 }
143 }
144 }
145 }
146
147 Assert.assertTrue("Regions did not split properly", regions.size() > 1);
148 Assert.assertTrue("Could not get reference any of the store file", scanner.size() > 1);
149
150 RetryCounter retrier = new RetryCounter(30, 1, TimeUnit.SECONDS);
151 while (CompactionState.NONE != admin.getCompactionState(tableName) && retrier.shouldRetry()) {
152 retrier.sleepUntilNextRetry();
153 }
154
155 Assert.assertEquals("Compaction did not complete in 30 secs", CompactionState.NONE,
156 admin.getCompactionState(tableName));
157
158 for (HRegion region : regions) {
159 for (Store store : region.getStores()) {
160 Assert.assertTrue("Contains an open file reference which can be split",
161 !scanner.containsKey(region.getRegionInfo().getEncodedName()) || !store.canSplit());
162 }
163 }
164 } finally {
165 for (StoreFile.Reader s : scanner.values()) {
166 try {
167 s.close(true);
168 } catch (IOException e) {
169 e.printStackTrace();
170 }
171 }
172 scanner.clear();
173 if (source != null) source.close();
174 TEST_UTIL.deleteTableIfAny(tableName);
175 }
176 }
177
178 @Test
179 public void testMasterOpsWhileSplitting() throws Exception {
180 TableName tableName = TableName.valueOf("TestSplit");
181 byte[] familyName = Bytes.toBytes("fam");
182 try (HTable ht = TEST_UTIL.createTable(tableName, familyName)) {
183 TEST_UTIL.loadTable(ht, familyName, false);
184 }
185 HRegionServer server = TEST_UTIL.getHBaseCluster().getRegionServer(0);
186 byte[] firstRow = Bytes.toBytes("aaa");
187 byte[] splitRow = Bytes.toBytes("lll");
188 byte[] lastRow = Bytes.toBytes("zzz");
189 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
190
191 byte[] regionName = conn.getRegionLocator(tableName).getRegionLocation(splitRow)
192 .getRegionInfo().getRegionName();
193 Region region = server.getRegion(regionName);
194 SplitTransactionImpl split = new SplitTransactionImpl((HRegion) region, splitRow);
195 split.prepare();
196
197
198 PairOfSameType<Region> regions = split.createDaughters(server, server, null);
199 assertFalse(test(conn, tableName, firstRow, server));
200 assertFalse(test(conn, tableName, lastRow, server));
201
202
203
204 split.openDaughters(server, null, regions.getFirst(), regions.getSecond());
205 assertFalse(test(conn, tableName, firstRow, server));
206 assertFalse(test(conn, tableName, lastRow, server));
207
208
209
210
211 if (split.useZKForAssignment) {
212 server.postOpenDeployTasks(regions.getSecond());
213 } else {
214 server.reportRegionStateTransition(
215 RegionServerStatusProtos.RegionStateTransition.TransitionCode.SPLIT,
216 region.getRegionInfo(), regions.getFirst().getRegionInfo(),
217 regions.getSecond().getRegionInfo());
218 }
219
220
221 if (split.useZKForAssignment) {
222 server.postOpenDeployTasks(regions.getFirst());
223 }
224
225
226 server.addToOnlineRegions(regions.getSecond());
227
228
229 assertFalse(test(conn, tableName, firstRow, server));
230
231 assertTrue(test(conn, tableName, lastRow, server));
232
233
234 server.addToOnlineRegions(regions.getFirst());
235 assertTrue(test(conn, tableName, firstRow, server));
236 assertTrue(test(conn, tableName, lastRow, server));
237
238 if (split.useZKForAssignment) {
239
240 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
241 .getSplitTransactionCoordination().completeSplitTransaction(server, regions.getFirst(),
242 regions.getSecond(), split.std, region);
243 }
244
245 assertTrue(test(conn, tableName, firstRow, server));
246 assertTrue(test(conn, tableName, lastRow, server));
247 }
248 }
249
250 @Test
251 public void testTableAvailableWhileSplitting() throws Exception {
252 TableName tableName = TableName.valueOf("TestTableAvailableWhileSplitting");
253 byte[] familyName = Bytes.toBytes("fam");
254 try (HTable ht = TEST_UTIL.createTable(tableName, familyName)) {
255 TEST_UTIL.loadTable(ht, familyName, false);
256 }
257 Admin admin = TEST_UTIL.getHBaseAdmin();
258 HRegionServer server = TEST_UTIL.getHBaseCluster().getRegionServer(0);
259 byte[] splitRow = Bytes.toBytes("lll");
260 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
261 byte[] regionName = conn.getRegionLocator(tableName).getRegionLocation(splitRow)
262 .getRegionInfo().getRegionName();
263 Region region = server.getRegion(regionName);
264 SplitTransactionImpl split = new SplitTransactionImpl((HRegion) region, splitRow);
265 split.prepare();
266 assertTrue(admin.isTableAvailable(tableName));
267
268
269 PairOfSameType<Region> regions = split.createDaughters(server, server, null);
270
271 assertFalse(admin.isTableAvailable(tableName));
272
273
274
275 split.openDaughters(server, null, regions.getFirst(), regions.getSecond());
276 assertFalse(admin.isTableAvailable(tableName));
277
278
279
280 if (split.useZKForAssignment) {
281 server.postOpenDeployTasks(regions.getSecond());
282 } else {
283 server.reportRegionStateTransition(
284 RegionServerStatusProtos.RegionStateTransition.TransitionCode.SPLIT,
285 region.getRegionInfo(), regions.getFirst().getRegionInfo(),
286 regions.getSecond().getRegionInfo());
287 }
288
289
290 if (split.useZKForAssignment) {
291 server.postOpenDeployTasks(regions.getFirst());
292 }
293
294
295 assertTrue(admin.isTableAvailable(tableName));
296
297 server.addToOnlineRegions(regions.getSecond());
298 server.addToOnlineRegions(regions.getFirst());
299 assertTrue(admin.isTableAvailable(tableName));
300 } finally {
301 if (admin != null) {
302 admin.close();
303 }
304 }
305 }
306
307
308
309
310
311 private boolean test(Connection conn, TableName tableName, byte[] row,
312 HRegionServer server) {
313
314 try {
315 byte[] regionName = conn.getRegionLocator(tableName).getRegionLocation(row, true)
316 .getRegionInfo().getRegionName();
317
318 ClientProtos.GetRequest request =
319 RequestConverter.buildGetRequest(regionName, new Get(row));
320 server.getRSRpcServices().get(null, request);
321 ScanRequest scanRequest = RequestConverter.buildScanRequest(
322 regionName, new Scan(row), 1, true);
323 try {
324 server.getRSRpcServices().scan(
325 new HBaseRpcControllerImpl(), scanRequest);
326 } catch (ServiceException se) {
327 throw ProtobufUtil.getRemoteException(se);
328 }
329 } catch (IOException e) {
330 return false;
331 } catch (ServiceException e) {
332 return false;
333 }
334 return true;
335 }
336
337
338
339
340 @Test
341 public void testFromClientSideWhileSplitting() throws Throwable {
342 LOG.info("Starting testFromClientSideWhileSplitting");
343 final TableName TABLENAME =
344 TableName.valueOf("testFromClientSideWhileSplitting");
345 final byte[] FAMILY = Bytes.toBytes("family");
346
347
348
349 Table table = TEST_UTIL.createTable(TABLENAME, FAMILY);
350
351 Stoppable stopper = new StoppableImplementation();
352 RegionSplitter regionSplitter = new RegionSplitter(table);
353 RegionChecker regionChecker = new RegionChecker(CONF, stopper, TABLENAME);
354 final ChoreService choreService = new ChoreService("TEST_SERVER");
355
356 choreService.scheduleChore(regionChecker);
357 regionSplitter.start();
358
359
360 regionSplitter.join();
361 stopper.stop(null);
362
363 if (regionChecker.ex != null) {
364 throw regionChecker.ex;
365 }
366
367 if (regionSplitter.ex != null) {
368 throw regionSplitter.ex;
369 }
370
371
372 regionChecker.verify();
373 }
374
375 static class RegionSplitter extends Thread {
376 final Connection connection;
377 Throwable ex;
378 Table table;
379 TableName tableName;
380 byte[] family;
381 Admin admin;
382 HRegionServer rs;
383
384 RegionSplitter(Table table) throws IOException {
385 this.table = table;
386 this.tableName = table.getName();
387 this.family = table.getTableDescriptor().getFamiliesKeys().iterator().next();
388 admin = TEST_UTIL.getHBaseAdmin();
389 rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0);
390 connection = TEST_UTIL.getConnection();
391 }
392
393 @Override
394 public void run() {
395 try {
396 Random random = new Random();
397 for (int i= 0; i< 5; i++) {
398 NavigableMap<HRegionInfo, ServerName> regions =
399 MetaScanner.allTableRegions(connection, tableName);
400 if (regions.size() == 0) {
401 continue;
402 }
403 int regionIndex = random.nextInt(regions.size());
404
405
406 HRegionInfo region = Iterators.get(regions.keySet().iterator(), regionIndex);
407
408
409 int start = 0, end = Integer.MAX_VALUE;
410 if (region.getStartKey().length > 0) {
411 start = Bytes.toInt(region.getStartKey());
412 }
413 if (region.getEndKey().length > 0) {
414 end = Bytes.toInt(region.getEndKey());
415 }
416 int mid = start + ((end - start) / 2);
417 byte[] splitPoint = Bytes.toBytes(mid);
418
419
420 addData(start);
421 addData(mid);
422
423 flushAndBlockUntilDone(admin, rs, region.getRegionName());
424 compactAndBlockUntilDone(admin, rs, region.getRegionName());
425
426 log("Initiating region split for:" + region.getRegionNameAsString());
427 try {
428 admin.splitRegion(region.getRegionName(), splitPoint);
429
430 blockUntilRegionSplit(CONF, 50000, region.getRegionName(), true);
431
432 } catch (NotServingRegionException ex) {
433
434 }
435 }
436 } catch (Throwable ex) {
437 this.ex = ex;
438 }
439 }
440
441 void addData(int start) throws IOException {
442 List<Put> puts = new ArrayList<>();
443 for (int i=start; i< start + 100; i++) {
444 Put put = new Put(Bytes.toBytes(i));
445 put.addColumn(family, family, Bytes.toBytes(i));
446 puts.add(put);
447 }
448 table.put(puts);
449 }
450 }
451
452
453
454
455 static class RegionChecker extends ScheduledChore {
456 Connection connection;
457 Configuration conf;
458 TableName tableName;
459 Throwable ex;
460
461 RegionChecker(Configuration conf, Stoppable stopper, TableName tableName) throws IOException {
462 super("RegionChecker", stopper, 100);
463 this.conf = conf;
464 this.tableName = tableName;
465
466 this.connection = ConnectionFactory.createConnection(conf);
467 }
468
469
470 void verifyRegionsUsingMetaScanner() throws Exception {
471
472
473 NavigableMap<HRegionInfo, ServerName> regions = MetaScanner.allTableRegions(connection,
474 tableName);
475 verifyTableRegions(regions.keySet());
476
477
478 List<HRegionInfo> regionList = MetaScanner.listAllRegions(conf, connection, false);
479 verifyTableRegions(Sets.newTreeSet(regionList));
480 }
481
482
483 void verifyRegionsUsingHTable() throws IOException {
484 HTable table = null;
485 try {
486 table = (HTable) connection.getTable(tableName);
487 Pair<byte[][], byte[][]> keys = table.getRegionLocator().getStartEndKeys();
488 verifyStartEndKeys(keys);
489
490
491 Set<HRegionInfo> regions = new TreeSet<HRegionInfo>();
492 for (HRegionLocation loc : table.getRegionLocator().getAllRegionLocations()) {
493 regions.add(loc.getRegionInfo());
494 }
495 verifyTableRegions(regions);
496 } finally {
497 IOUtils.closeQuietly(table);
498 }
499 }
500
501 void verify() throws Exception {
502 verifyRegionsUsingMetaScanner();
503 verifyRegionsUsingHTable();
504 }
505
506 void verifyTableRegions(Set<HRegionInfo> regions) {
507 log("Verifying " + regions.size() + " regions: " + regions);
508
509 byte[][] startKeys = new byte[regions.size()][];
510 byte[][] endKeys = new byte[regions.size()][];
511
512 int i=0;
513 for (HRegionInfo region : regions) {
514 startKeys[i] = region.getStartKey();
515 endKeys[i] = region.getEndKey();
516 i++;
517 }
518
519 Pair<byte[][], byte[][]> keys = new Pair<byte[][], byte[][]>(startKeys, endKeys);
520 verifyStartEndKeys(keys);
521 }
522
523 void verifyStartEndKeys(Pair<byte[][], byte[][]> keys) {
524 byte[][] startKeys = keys.getFirst();
525 byte[][] endKeys = keys.getSecond();
526 assertEquals(startKeys.length, endKeys.length);
527 assertTrue("Found 0 regions for the table", startKeys.length > 0);
528
529 assertArrayEquals("Start key for the first region is not byte[0]",
530 HConstants.EMPTY_START_ROW, startKeys[0]);
531 byte[] prevEndKey = HConstants.EMPTY_START_ROW;
532
533
534 for (int i=0; i<startKeys.length; i++) {
535 assertArrayEquals(
536 "Hole in hbase:meta is detected. prevEndKey=" + Bytes.toStringBinary(prevEndKey)
537 + " ,regionStartKey=" + Bytes.toStringBinary(startKeys[i]), prevEndKey,
538 startKeys[i]);
539 prevEndKey = endKeys[i];
540 }
541 assertArrayEquals("End key for the last region is not byte[0]", HConstants.EMPTY_END_ROW,
542 endKeys[endKeys.length - 1]);
543 }
544
545 @Override
546 protected void chore() {
547 try {
548 verify();
549 } catch (Throwable ex) {
550 this.ex = ex;
551 getStopper().stop("caught exception");
552 }
553 }
554 }
555
556 public static void log(String msg) {
557 LOG.info(msg);
558 }
559
560
561
562 public static void flushAndBlockUntilDone(Admin admin, HRegionServer rs, byte[] regionName)
563 throws IOException, InterruptedException {
564 log("flushing region: " + Bytes.toStringBinary(regionName));
565 admin.flushRegion(regionName);
566 log("blocking until flush is complete: " + Bytes.toStringBinary(regionName));
567 Threads.sleepWithoutInterrupt(500);
568 while (rs.getOnlineRegion(regionName).getMemstoreSize() > 0) {
569 Threads.sleep(50);
570 }
571 }
572
573 public static void compactAndBlockUntilDone(Admin admin, HRegionServer rs, byte[] regionName)
574 throws IOException, InterruptedException {
575 log("Compacting region: " + Bytes.toStringBinary(regionName));
576 admin.majorCompactRegion(regionName);
577 log("blocking until compaction is complete: " + Bytes.toStringBinary(regionName));
578 Threads.sleepWithoutInterrupt(500);
579 outer: for (;;) {
580 for (Store store : rs.getOnlineRegion(regionName).getStores()) {
581 if (store.getStorefilesCount() > 1) {
582 Threads.sleep(50);
583 continue outer;
584 }
585 }
586 break;
587 }
588 }
589
590
591 public static void blockUntilRegionSplit(Configuration conf, long timeout,
592 final byte[] regionName, boolean waitForDaughters)
593 throws IOException, InterruptedException {
594 long start = System.currentTimeMillis();
595 log("blocking until region is split:" + Bytes.toStringBinary(regionName));
596 HRegionInfo daughterA = null, daughterB = null;
597 try (Connection conn = ConnectionFactory.createConnection(conf);
598 Table metaTable = conn.getTable(TableName.META_TABLE_NAME)) {
599 Result result = null;
600 HRegionInfo region = null;
601 while ((System.currentTimeMillis() - start) < timeout) {
602 result = metaTable.get(new Get(regionName));
603 if (result == null) {
604 break;
605 }
606
607 region = MetaTableAccessor.getHRegionInfo(result);
608 if (region.isSplitParent()) {
609 log("found parent region: " + region.toString());
610 PairOfSameType<HRegionInfo> pair = MetaTableAccessor.getDaughterRegions(result);
611 daughterA = pair.getFirst();
612 daughterB = pair.getSecond();
613 break;
614 }
615 Threads.sleep(100);
616 }
617 if (daughterA == null || daughterB == null) {
618 throw new IOException("Failed to get daughters, daughterA=" + daughterA + ", daughterB=" +
619 daughterB + ", timeout=" + timeout + ", result=" + result + ", regionName=" +
620 Bytes.toString(regionName) + ", region=" + region);
621 }
622
623
624 if (waitForDaughters) {
625 long rem = timeout - (System.currentTimeMillis() - start);
626 blockUntilRegionIsInMeta(conn, rem, daughterA);
627
628 rem = timeout - (System.currentTimeMillis() - start);
629 blockUntilRegionIsInMeta(conn, rem, daughterB);
630
631 rem = timeout - (System.currentTimeMillis() - start);
632 blockUntilRegionIsOpened(conf, rem, daughterA);
633
634 rem = timeout - (System.currentTimeMillis() - start);
635 blockUntilRegionIsOpened(conf, rem, daughterB);
636
637
638 compactAndBlockUntilDone(TEST_UTIL.getHBaseAdmin(),
639 TEST_UTIL.getMiniHBaseCluster().getRegionServer(0), daughterA.getRegionName());
640 compactAndBlockUntilDone(TEST_UTIL.getHBaseAdmin(),
641 TEST_UTIL.getMiniHBaseCluster().getRegionServer(0), daughterB.getRegionName());
642
643 removeCompactedfiles(conn, timeout, daughterA);
644 removeCompactedfiles(conn, timeout, daughterB);
645 }
646 }
647 }
648
649 public static void removeCompactedfiles(Connection conn, long timeout, HRegionInfo hri)
650 throws IOException, InterruptedException {
651 log("removeCompactedfiles for : " + hri.getRegionNameAsString());
652 List<HRegion> regions = TEST_UTIL.getHBaseCluster().getRegions(hri.getTable());
653 for (HRegion region : regions) {
654 try {
655 region.getStores().get(0).closeAndArchiveCompactedFiles();
656 } catch (IOException e) {
657 e.printStackTrace();
658 }
659 }
660 }
661
662 public static void blockUntilRegionIsInMeta(Connection conn, long timeout, HRegionInfo hri)
663 throws IOException, InterruptedException {
664 log("blocking until region is in META: " + hri.getRegionNameAsString());
665 long start = System.currentTimeMillis();
666 while (System.currentTimeMillis() - start < timeout) {
667 HRegionLocation loc = MetaTableAccessor.getRegionLocation(conn, hri);
668 if (loc != null && !loc.getRegionInfo().isOffline()) {
669 log("found region in META: " + hri.getRegionNameAsString());
670 break;
671 }
672 Threads.sleep(100);
673 }
674 }
675
676 public static void blockUntilRegionIsOpened(Configuration conf, long timeout, HRegionInfo hri)
677 throws IOException, InterruptedException {
678 log("blocking until region is opened for reading:" + hri.getRegionNameAsString());
679 long start = System.currentTimeMillis();
680 try (Connection conn = ConnectionFactory.createConnection(conf);
681 Table table = conn.getTable(hri.getTable())) {
682 byte[] row = hri.getStartKey();
683
684 if (row == null || row.length <= 0) row = new byte[] { '0' };
685 Get get = new Get(row);
686 while (System.currentTimeMillis() - start < timeout) {
687 try {
688 table.get(get);
689 break;
690 } catch (IOException ex) {
691
692 }
693 Threads.sleep(100);
694 }
695 }
696 }
697 }
698