1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.catalog;
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.NavigableMap;
27 import java.util.Set;
28 import java.util.TreeMap;
29 import java.util.TreeSet;
30
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.HRegionInfo;
33 import org.apache.hadoop.hbase.HServerAddress;
34 import org.apache.hadoop.hbase.HServerInfo;
35 import org.apache.hadoop.hbase.HTableDescriptor;
36 import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
37 import org.apache.hadoop.hbase.NotServingRegionException;
38 import org.apache.hadoop.hbase.client.Get;
39 import org.apache.hadoop.hbase.client.Result;
40 import org.apache.hadoop.hbase.client.Scan;
41 import org.apache.hadoop.hbase.ipc.HRegionInterface;
42 import org.apache.hadoop.hbase.util.Bytes;
43 import org.apache.hadoop.hbase.util.Pair;
44 import org.apache.hadoop.hbase.util.Writables;
45 import org.apache.hadoop.ipc.RemoteException;
46
47
48
49
50
51
52
53 public class MetaReader {
54 public static final byte [] META_REGION_PREFIX;
55 static {
56
57
58 int len = HRegionInfo.FIRST_META_REGIONINFO.getRegionName().length - 2;
59 META_REGION_PREFIX = new byte [len];
60 System.arraycopy(HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), 0,
61 META_REGION_PREFIX, 0, len);
62 }
63
64
65
66
67
68
69
70
71
72 private static HRegionInterface getCatalogRegionInterface(final CatalogTracker ct,
73 final byte [] tableName)
74 throws NotAllMetaRegionsOnlineException, IOException {
75 return Bytes.equals(HConstants.META_TABLE_NAME, tableName)?
76 ct.waitForRootServerConnectionDefault():
77 ct.waitForMetaServerConnectionDefault();
78 }
79
80
81
82
83
84
85
86
87 private static byte [] getCatalogRegionNameForTable(final byte [] tableName) {
88 return Bytes.equals(HConstants.META_TABLE_NAME, tableName)?
89 HRegionInfo.ROOT_REGIONINFO.getRegionName():
90 HRegionInfo.FIRST_META_REGIONINFO.getRegionName();
91 }
92
93
94
95
96
97
98
99
100 private static byte [] getCatalogRegionNameForRegion(final byte [] regionName) {
101 return isMetaRegion(regionName)?
102 HRegionInfo.ROOT_REGIONINFO.getRegionName():
103 HRegionInfo.FIRST_META_REGIONINFO.getRegionName();
104 }
105
106
107
108
109
110 private static boolean isMetaRegion(final byte [] regionName) {
111 if (regionName.length < META_REGION_PREFIX.length + 2
112
113 return false;
114 }
115
116
117 return Bytes.compareTo(regionName, 0, META_REGION_PREFIX.length,
118 META_REGION_PREFIX, 0, META_REGION_PREFIX.length) == 0;
119 }
120
121
122
123
124
125
126
127
128
129
130
131 public static Map<HRegionInfo,HServerAddress> fullScan(
132 CatalogTracker catalogTracker)
133 throws IOException {
134 return fullScan(catalogTracker, new TreeSet<String>());
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 public static Map<HRegionInfo,HServerAddress> fullScan(
151 CatalogTracker catalogTracker, final Set<String> disabledTables)
152 throws IOException {
153 return fullScan(catalogTracker, disabledTables, false);
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 public static Map<HRegionInfo,HServerAddress> fullScan(
172 CatalogTracker catalogTracker, final Set<String> disabledTables,
173 final boolean excludeOfflinedSplitParents)
174 throws IOException {
175 final Map<HRegionInfo,HServerAddress> regions =
176 new TreeMap<HRegionInfo,HServerAddress>();
177 Visitor v = new Visitor() {
178 @Override
179 public boolean visit(Result r) throws IOException {
180 if (r == null || r.isEmpty()) return true;
181 Pair<HRegionInfo,HServerAddress> region = metaRowToRegionPair(r);
182 if (region == null) return true;
183 HRegionInfo hri = region.getFirst();
184 if (disabledTables.contains(
185 hri.getTableDesc().getNameAsString())) return true;
186
187 if (excludeOfflinedSplitParents && hri.isSplitParent()) return true;
188 regions.put(hri, region.getSecond());
189 return true;
190 }
191 };
192 fullScan(catalogTracker, v);
193 return regions;
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208 public static List<Result> fullScanOfResults(
209 CatalogTracker catalogTracker)
210 throws IOException {
211 final List<Result> regions = new ArrayList<Result>();
212 Visitor v = new Visitor() {
213 @Override
214 public boolean visit(Result r) throws IOException {
215 if (r == null || r.isEmpty()) return true;
216 regions.add(r);
217 return true;
218 }
219 };
220 fullScan(catalogTracker, v);
221 return regions;
222 }
223
224
225
226
227
228
229
230
231
232
233
234 public static void fullScan(CatalogTracker catalogTracker,
235 final Visitor visitor)
236 throws IOException {
237 fullScan(catalogTracker, visitor, null);
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252 public static void fullScan(CatalogTracker catalogTracker,
253 final Visitor visitor, final byte [] startrow)
254 throws IOException {
255 HRegionInterface metaServer =
256 catalogTracker.waitForMetaServerConnectionDefault();
257 Scan scan = new Scan();
258 if (startrow != null) scan.setStartRow(startrow);
259 scan.addFamily(HConstants.CATALOG_FAMILY);
260 long scannerid = metaServer.openScanner(
261 HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
262 try {
263 Result data;
264 while((data = metaServer.next(scannerid)) != null) {
265 if (!data.isEmpty()) visitor.visit(data);
266 }
267 } finally {
268 metaServer.close(scannerid);
269 }
270 return;
271 }
272
273
274
275
276
277
278
279 public static HServerAddress readMetaLocation(HRegionInterface metaServer)
280 throws IOException {
281 return readLocation(metaServer, CatalogTracker.ROOT_REGION,
282 CatalogTracker.META_REGION);
283 }
284
285
286
287
288
289
290
291
292 public static HServerAddress readRegionLocation(CatalogTracker catalogTracker,
293 byte [] regionName)
294 throws IOException {
295 if (isMetaRegion(regionName)) throw new IllegalArgumentException("See readMetaLocation");
296 return readLocation(catalogTracker.waitForMetaServerConnectionDefault(),
297 CatalogTracker.META_REGION, regionName);
298 }
299
300 private static HServerAddress readLocation(HRegionInterface metaServer,
301 byte [] catalogRegionName, byte [] regionName)
302 throws IOException {
303 Result r = null;
304 try {
305 r = metaServer.get(catalogRegionName,
306 new Get(regionName).addColumn(HConstants.CATALOG_FAMILY,
307 HConstants.SERVER_QUALIFIER));
308 } catch (java.net.SocketTimeoutException e) {
309
310
311 } catch (java.net.ConnectException e) {
312 if (e.getMessage() != null &&
313 e.getMessage().contains("Connection refused")) {
314
315
316 } else {
317 throw e;
318 }
319 } catch (RemoteException re) {
320 IOException ioe = re.unwrapRemoteException();
321 if (ioe instanceof NotServingRegionException) {
322
323
324 } else if (ioe.getMessage().contains("Server not running")) {
325
326 } else {
327 throw re;
328 }
329 } catch (IOException e) {
330 if (e.getCause() != null && e.getCause() instanceof IOException &&
331 e.getCause().getMessage() != null &&
332 e.getCause().getMessage().contains("Connection reset by peer")) {
333
334
335 } else {
336 throw e;
337 }
338 }
339 if (r == null || r.isEmpty()) {
340 return null;
341 }
342 byte [] value = r.getValue(HConstants.CATALOG_FAMILY,
343 HConstants.SERVER_QUALIFIER);
344 return new HServerAddress(Bytes.toString(value));
345 }
346
347
348
349
350
351
352
353
354 public static Pair<HRegionInfo, HServerAddress> getRegion(
355 CatalogTracker catalogTracker, byte [] regionName)
356 throws IOException {
357 Get get = new Get(regionName);
358 get.addFamily(HConstants.CATALOG_FAMILY);
359 byte [] meta = getCatalogRegionNameForRegion(regionName);
360 Result r = catalogTracker.waitForMetaServerConnectionDefault().get(meta, get);
361 if(r == null || r.isEmpty()) {
362 return null;
363 }
364 return metaRowToRegionPair(r);
365 }
366
367
368
369
370
371
372
373
374 public static Pair<HRegionInfo, HServerAddress> metaRowToRegionPair(
375 Result data) throws IOException {
376 byte [] bytes =
377 data.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
378 if (bytes == null) return null;
379 HRegionInfo info = Writables.getHRegionInfo(bytes);
380 final byte[] value = data.getValue(HConstants.CATALOG_FAMILY,
381 HConstants.SERVER_QUALIFIER);
382 if (value != null && value.length > 0) {
383 HServerAddress server = new HServerAddress(Bytes.toString(value));
384 return new Pair<HRegionInfo,HServerAddress>(info, server);
385 } else {
386 return new Pair<HRegionInfo, HServerAddress>(info, null);
387 }
388 }
389
390
391
392
393
394
395
396 public static Pair<HRegionInfo, HServerInfo> metaRowToRegionPairWithInfo(
397 Result data) throws IOException {
398 byte [] bytes = data.getValue(HConstants.CATALOG_FAMILY,
399 HConstants.REGIONINFO_QUALIFIER);
400 if (bytes == null) return null;
401 HRegionInfo info = Writables.getHRegionInfo(bytes);
402 final byte[] value = data.getValue(HConstants.CATALOG_FAMILY,
403 HConstants.SERVER_QUALIFIER);
404 if (value != null && value.length > 0) {
405 final long startCode = Bytes.toLong(data.getValue(HConstants.CATALOG_FAMILY,
406 HConstants.STARTCODE_QUALIFIER));
407 HServerAddress server = new HServerAddress(Bytes.toString(value));
408 HServerInfo hsi = new HServerInfo(server, startCode, 0,
409 server.getHostname());
410 return new Pair<HRegionInfo,HServerInfo>(info, hsi);
411 } else {
412 return new Pair<HRegionInfo, HServerInfo>(info, null);
413 }
414 }
415
416
417
418
419
420
421
422
423
424 public static boolean tableExists(CatalogTracker catalogTracker,
425 String tableName)
426 throws IOException {
427 if (tableName.equals(HTableDescriptor.ROOT_TABLEDESC.getNameAsString()) ||
428 tableName.equals(HTableDescriptor.META_TABLEDESC.getNameAsString())) {
429
430 return true;
431 }
432 HRegionInterface metaServer =
433 catalogTracker.waitForMetaServerConnectionDefault();
434 byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
435 Scan scan = new Scan(firstRowInTable);
436 scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
437 long scannerid = metaServer.openScanner(
438 HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
439 try {
440 Result data = metaServer.next(scannerid);
441 if (data != null && data.size() > 0) {
442 HRegionInfo info = Writables.getHRegionInfo(
443 data.getValue(HConstants.CATALOG_FAMILY,
444 HConstants.REGIONINFO_QUALIFIER));
445 if (info.getTableDesc().getNameAsString().equals(tableName)) {
446
447 return true;
448 }
449 }
450 return false;
451 } finally {
452 metaServer.close(scannerid);
453 }
454 }
455
456
457
458
459
460
461
462
463 public static List<HRegionInfo> getTableRegions(CatalogTracker catalogTracker,
464 byte [] tableName)
465 throws IOException {
466 return getTableRegions(catalogTracker, tableName, false);
467 }
468
469
470
471
472
473
474
475
476
477
478 public static List<HRegionInfo> getTableRegions(CatalogTracker catalogTracker,
479 byte [] tableName, final boolean excludeOfflinedSplitParents)
480 throws IOException {
481 if (Bytes.equals(tableName, HConstants.ROOT_TABLE_NAME)) {
482
483 List<HRegionInfo> list = new ArrayList<HRegionInfo>();
484 list.add(HRegionInfo.ROOT_REGIONINFO);
485 return list;
486 } else if (Bytes.equals(tableName, HConstants.META_TABLE_NAME)) {
487
488 List<HRegionInfo> list = new ArrayList<HRegionInfo>();
489 list.add(HRegionInfo.FIRST_META_REGIONINFO);
490 return list;
491 }
492
493
494 HRegionInterface metaServer =
495 getCatalogRegionInterface(catalogTracker, tableName);
496 List<HRegionInfo> regions = new ArrayList<HRegionInfo>();
497 String tableString = Bytes.toString(tableName);
498 byte[] firstRowInTable = Bytes.toBytes(tableString + ",,");
499 Scan scan = new Scan(firstRowInTable);
500 scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
501 long scannerid =
502 metaServer.openScanner(getCatalogRegionNameForTable(tableName), scan);
503 try {
504 Result data;
505 while((data = metaServer.next(scannerid)) != null) {
506 if (data != null && data.size() > 0) {
507 HRegionInfo info = Writables.getHRegionInfo(
508 data.getValue(HConstants.CATALOG_FAMILY,
509 HConstants.REGIONINFO_QUALIFIER));
510 if (info.getTableDesc().getNameAsString().equals(tableString)) {
511
512 if (excludeOfflinedSplitParents && info.isSplitParent()) continue;
513 regions.add(info);
514 } else {
515 break;
516 }
517 }
518 }
519 return regions;
520 } finally {
521 metaServer.close(scannerid);
522 }
523 }
524
525
526
527
528
529
530
531
532 public static List<Pair<HRegionInfo, HServerAddress>>
533 getTableRegionsAndLocations(CatalogTracker catalogTracker, String tableName)
534 throws IOException, InterruptedException {
535 byte [] tableNameBytes = Bytes.toBytes(tableName);
536 if (Bytes.equals(tableNameBytes, HConstants.ROOT_TABLE_NAME)) {
537
538 HServerAddress hsa = catalogTracker.getRootLocation();
539 List<Pair<HRegionInfo, HServerAddress>> list =
540 new ArrayList<Pair<HRegionInfo, HServerAddress>>();
541 list.add(new Pair<HRegionInfo, HServerAddress>(HRegionInfo.ROOT_REGIONINFO, hsa));
542 return list;
543 }
544 HRegionInterface metaServer =
545 getCatalogRegionInterface(catalogTracker, tableNameBytes);
546 List<Pair<HRegionInfo, HServerAddress>> regions =
547 new ArrayList<Pair<HRegionInfo, HServerAddress>>();
548 byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
549 Scan scan = new Scan(firstRowInTable);
550 scan.addFamily(HConstants.CATALOG_FAMILY);
551 long scannerid =
552 metaServer.openScanner(getCatalogRegionNameForTable(tableNameBytes), scan);
553 try {
554 Result data;
555 while((data = metaServer.next(scannerid)) != null) {
556 if (data != null && data.size() > 0) {
557 Pair<HRegionInfo, HServerAddress> region = metaRowToRegionPair(data);
558 if (region == null) continue;
559 if (region.getFirst().getTableDesc().getNameAsString().equals(
560 tableName)) {
561 regions.add(region);
562 } else {
563 break;
564 }
565 }
566 }
567 return regions;
568 } finally {
569 metaServer.close(scannerid);
570 }
571 }
572
573
574
575
576
577
578
579
580 public static NavigableMap<HRegionInfo, Result>
581 getServerUserRegions(CatalogTracker catalogTracker, final HServerInfo hsi)
582 throws IOException {
583 HRegionInterface metaServer =
584 catalogTracker.waitForMetaServerConnectionDefault();
585 NavigableMap<HRegionInfo, Result> hris = new TreeMap<HRegionInfo, Result>();
586 Scan scan = new Scan();
587 scan.addFamily(HConstants.CATALOG_FAMILY);
588 long scannerid = metaServer.openScanner(
589 HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
590 try {
591 Result result;
592 while((result = metaServer.next(scannerid)) != null) {
593 if (result != null && result.size() > 0) {
594 Pair<HRegionInfo, HServerInfo> pair =
595 metaRowToRegionPairWithInfo(result);
596 if (pair == null) continue;
597 if (pair.getSecond() == null || !pair.getSecond().equals(hsi)) {
598 continue;
599 }
600 hris.put(pair.getFirst(), result);
601 }
602 }
603 return hris;
604 } finally {
605 metaServer.close(scannerid);
606 }
607 }
608
609
610
611
612 public interface Visitor {
613
614
615
616
617
618
619 public boolean visit(final Result r) throws IOException;
620 }
621 }