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 java.io.IOException;
22 import java.io.InterruptedIOException;
23 import java.net.SocketTimeoutException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.LinkedList;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.concurrent.atomic.AtomicInteger;
32 import java.util.concurrent.atomic.AtomicReference;
33 import java.util.regex.Pattern;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.hadoop.conf.Configuration;
38 import org.apache.hadoop.hbase.Abortable;
39 import org.apache.hadoop.hbase.ClusterStatus;
40 import org.apache.hadoop.hbase.DoNotRetryIOException;
41 import org.apache.hadoop.hbase.HBaseConfiguration;
42 import org.apache.hadoop.hbase.HColumnDescriptor;
43 import org.apache.hadoop.hbase.HConstants;
44 import org.apache.hadoop.hbase.HRegionInfo;
45 import org.apache.hadoop.hbase.HRegionLocation;
46 import org.apache.hadoop.hbase.HTableDescriptor;
47 import org.apache.hadoop.hbase.MasterNotRunningException;
48 import org.apache.hadoop.hbase.MetaTableAccessor;
49 import org.apache.hadoop.hbase.NamespaceDescriptor;
50 import org.apache.hadoop.hbase.NotServingRegionException;
51 import org.apache.hadoop.hbase.RegionException;
52 import org.apache.hadoop.hbase.RegionLocations;
53 import org.apache.hadoop.hbase.ServerName;
54 import org.apache.hadoop.hbase.TableExistsException;
55 import org.apache.hadoop.hbase.TableName;
56 import org.apache.hadoop.hbase.TableNotDisabledException;
57 import org.apache.hadoop.hbase.TableNotEnabledException;
58 import org.apache.hadoop.hbase.TableNotFoundException;
59 import org.apache.hadoop.hbase.UnknownRegionException;
60 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
61 import org.apache.hadoop.hbase.classification.InterfaceAudience;
62 import org.apache.hadoop.hbase.classification.InterfaceStability;
63 import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitor;
64 import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitorBase;
65 import org.apache.hadoop.hbase.exceptions.DeserializationException;
66 import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
67 import org.apache.hadoop.hbase.ipc.MasterCoprocessorRpcChannel;
68 import org.apache.hadoop.hbase.ipc.RegionServerCoprocessorRpcChannel;
69 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
70 import org.apache.hadoop.hbase.protobuf.RequestConverter;
71 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.AdminService;
72 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
73 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionResponse;
74 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
75 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
76 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
77 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse;
78 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState;
79 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
80 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterResponse;
81 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
82 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateConfigurationRequest;
83 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
84 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameStringPair;
85 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ProcedureDescription;
86 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
87 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema;
88 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AddColumnRequest;
89 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AssignRegionRequest;
90 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateNamespaceRequest;
91 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
92 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteColumnRequest;
93 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteNamespaceRequest;
94 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteSnapshotRequest;
95 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteTableRequest;
96 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableRequest;
97 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
98 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableRequest;
99 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ExecProcedureRequest;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ExecProcedureResponse;
101 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest;
102 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetCompletedSnapshotsRequest;
103 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetNamespaceDescriptorRequest;
104 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
105 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusResponse;
106 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
107 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse;
108 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
109 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsProcedureDoneRequest;
110 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsProcedureDoneResponse;
111 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsRestoreSnapshotDoneRequest;
112 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsRestoreSnapshotDoneResponse;
113 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneRequest;
114 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneResponse;
115 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ListNamespaceDescriptorsRequest;
116 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest;
117 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ListTableNamesByNamespaceRequest;
118 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
119 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyNamespaceRequest;
120 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
121 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
122 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRequest;
123 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
124 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
125 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ShutdownRequest;
126 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotRequest;
127 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotResponse;
128 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.StopMasterRequest;
129 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.TruncateTableRequest;
130 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
131 import org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException;
132 import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
133 import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException;
134 import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException;
135 import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
136 import org.apache.hadoop.hbase.snapshot.UnknownSnapshotException;
137 import org.apache.hadoop.hbase.util.Addressing;
138 import org.apache.hadoop.hbase.util.Bytes;
139 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
140 import org.apache.hadoop.hbase.util.Pair;
141 import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
142 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
143 import org.apache.hadoop.ipc.RemoteException;
144 import org.apache.hadoop.util.StringUtils;
145 import org.apache.zookeeper.KeeperException;
146
147 import com.google.protobuf.ByteString;
148 import com.google.protobuf.ServiceException;
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166 @InterfaceAudience.Private
167 @InterfaceStability.Evolving
168 public class HBaseAdmin implements Admin {
169 private static final Log LOG = LogFactory.getLog(HBaseAdmin.class);
170
171 private static final String ZK_IDENTIFIER_PREFIX = "hbase-admin-on-";
172
173 private ClusterConnection connection;
174
175 private volatile Configuration conf;
176 private final long pause;
177 private final int numRetries;
178
179
180
181 private final int retryLongerMultiplier;
182 private boolean aborted;
183 private boolean cleanupConnectionOnClose = false;
184 private boolean closed = false;
185 private int operationTimeout;
186
187 private RpcRetryingCallerFactory rpcCallerFactory;
188
189
190
191
192
193
194
195
196
197 @Deprecated
198 public HBaseAdmin(Configuration c)
199 throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
200
201
202 this(ConnectionManager.getConnectionInternal(new Configuration(c)));
203 this.cleanupConnectionOnClose = true;
204 }
205
206 @Override
207 public int getOperationTimeout() {
208 return operationTimeout;
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222 @Deprecated
223 public HBaseAdmin(Connection connection)
224 throws MasterNotRunningException, ZooKeeperConnectionException {
225 this((ClusterConnection)connection);
226 }
227
228 HBaseAdmin(ClusterConnection connection) {
229 this.conf = connection.getConfiguration();
230 this.connection = connection;
231
232 this.pause = this.conf.getLong(HConstants.HBASE_CLIENT_PAUSE,
233 HConstants.DEFAULT_HBASE_CLIENT_PAUSE);
234 this.numRetries = this.conf.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
235 HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
236 this.retryLongerMultiplier = this.conf.getInt(
237 "hbase.client.retries.longer.multiplier", 10);
238 this.operationTimeout = this.conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
239 HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
240
241 this.rpcCallerFactory = RpcRetryingCallerFactory.instantiate(this.conf);
242 }
243
244 @Override
245 public void abort(String why, Throwable e) {
246
247 this.aborted = true;
248 throw new RuntimeException(why, e);
249 }
250
251 @Override
252 public boolean isAborted(){
253 return this.aborted;
254 }
255
256
257 @Override
258 public HConnection getConnection() {
259 return connection;
260 }
261
262
263
264
265
266
267
268 @Deprecated
269 public boolean isMasterRunning()
270 throws MasterNotRunningException, ZooKeeperConnectionException {
271 return connection.isMasterRunning();
272 }
273
274
275
276
277
278
279 @Override
280 public boolean tableExists(final TableName tableName) throws IOException {
281 return MetaTableAccessor.tableExists(connection, tableName);
282 }
283
284 public boolean tableExists(final byte[] tableName)
285 throws IOException {
286 return tableExists(TableName.valueOf(tableName));
287 }
288
289 public boolean tableExists(final String tableName)
290 throws IOException {
291 return tableExists(TableName.valueOf(tableName));
292 }
293
294 @Override
295 public HTableDescriptor[] listTables() throws IOException {
296 return listTables((Pattern)null, false);
297 }
298
299 @Override
300 public HTableDescriptor[] listTables(Pattern pattern) throws IOException {
301 return listTables(pattern, false);
302 }
303
304 @Override
305 public HTableDescriptor[] listTables(String regex) throws IOException {
306 return listTables(Pattern.compile(regex), false);
307 }
308
309 @Override
310 public HTableDescriptor[] listTables(final Pattern pattern, final boolean includeSysTables)
311 throws IOException {
312 return executeCallable(new MasterCallable<HTableDescriptor[]>(getConnection()) {
313 @Override
314 public HTableDescriptor[] call(int callTimeout) throws ServiceException {
315 GetTableDescriptorsRequest req =
316 RequestConverter.buildGetTableDescriptorsRequest(pattern, includeSysTables);
317 return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(null, req));
318 }
319 });
320 }
321
322 @Override
323 public HTableDescriptor[] listTables(String regex, boolean includeSysTables)
324 throws IOException {
325 return listTables(Pattern.compile(regex), includeSysTables);
326 }
327
328
329
330
331
332
333
334 @Deprecated
335 public String[] getTableNames() throws IOException {
336 TableName[] tableNames = listTableNames();
337 String result[] = new String[tableNames.length];
338 for (int i = 0; i < tableNames.length; i++) {
339 result[i] = tableNames[i].getNameAsString();
340 }
341 return result;
342 }
343
344
345
346
347
348
349
350
351 @Deprecated
352 public String[] getTableNames(Pattern pattern) throws IOException {
353 TableName[] tableNames = listTableNames(pattern);
354 String result[] = new String[tableNames.length];
355 for (int i = 0; i < tableNames.length; i++) {
356 result[i] = tableNames[i].getNameAsString();
357 }
358 return result;
359 }
360
361
362
363
364
365
366
367
368 @Deprecated
369 public String[] getTableNames(String regex) throws IOException {
370 return getTableNames(Pattern.compile(regex));
371 }
372
373 @Override
374 public TableName[] listTableNames() throws IOException {
375 return listTableNames((Pattern)null, false);
376 }
377
378 @Override
379 public TableName[] listTableNames(Pattern pattern) throws IOException {
380 return listTableNames(pattern, false);
381 }
382
383 @Override
384 public TableName[] listTableNames(String regex) throws IOException {
385 return listTableNames(Pattern.compile(regex), false);
386 }
387
388 @Override
389 public TableName[] listTableNames(final Pattern pattern, final boolean includeSysTables)
390 throws IOException {
391 return executeCallable(new MasterCallable<TableName[]>(getConnection()) {
392 @Override
393 public TableName[] call(int callTimeout) throws ServiceException {
394 GetTableNamesRequest req =
395 RequestConverter.buildGetTableNamesRequest(pattern, includeSysTables);
396 return ProtobufUtil.getTableNameArray(master.getTableNames(null, req)
397 .getTableNamesList());
398 }
399 });
400 }
401
402 @Override
403 public TableName[] listTableNames(final String regex, final boolean includeSysTables)
404 throws IOException {
405 return listTableNames(Pattern.compile(regex), includeSysTables);
406 }
407
408
409
410
411
412
413
414
415 @Override
416 public HTableDescriptor getTableDescriptor(final TableName tableName)
417 throws TableNotFoundException, IOException {
418 if (tableName == null) return null;
419 if (tableName.equals(TableName.META_TABLE_NAME)) {
420 return HTableDescriptor.META_TABLEDESC;
421 }
422 HTableDescriptor htd = executeCallable(new MasterCallable<HTableDescriptor>(getConnection()) {
423 @Override
424 public HTableDescriptor call(int callTimeout) throws ServiceException {
425 GetTableDescriptorsResponse htds;
426 GetTableDescriptorsRequest req =
427 RequestConverter.buildGetTableDescriptorsRequest(tableName);
428 htds = master.getTableDescriptors(null, req);
429
430 if (!htds.getTableSchemaList().isEmpty()) {
431 return HTableDescriptor.convert(htds.getTableSchemaList().get(0));
432 }
433 return null;
434 }
435 });
436 if (htd != null) {
437 return htd;
438 }
439 throw new TableNotFoundException(tableName.getNameAsString());
440 }
441
442 public HTableDescriptor getTableDescriptor(final byte[] tableName)
443 throws TableNotFoundException, IOException {
444 return getTableDescriptor(TableName.valueOf(tableName));
445 }
446
447 private long getPauseTime(int tries) {
448 int triesCount = tries;
449 if (triesCount >= HConstants.RETRY_BACKOFF.length) {
450 triesCount = HConstants.RETRY_BACKOFF.length - 1;
451 }
452 return this.pause * HConstants.RETRY_BACKOFF[triesCount];
453 }
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468 @Override
469 public void createTable(HTableDescriptor desc)
470 throws IOException {
471 createTable(desc, null);
472 }
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498 @Override
499 public void createTable(HTableDescriptor desc, byte [] startKey,
500 byte [] endKey, int numRegions)
501 throws IOException {
502 if(numRegions < 3) {
503 throw new IllegalArgumentException("Must create at least three regions");
504 } else if(Bytes.compareTo(startKey, endKey) >= 0) {
505 throw new IllegalArgumentException("Start key must be smaller than end key");
506 }
507 if (numRegions == 3) {
508 createTable(desc, new byte[][]{startKey, endKey});
509 return;
510 }
511 byte [][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3);
512 if(splitKeys == null || splitKeys.length != numRegions - 1) {
513 throw new IllegalArgumentException("Unable to split key range into enough regions");
514 }
515 createTable(desc, splitKeys);
516 }
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535 @Override
536 public void createTable(final HTableDescriptor desc, byte [][] splitKeys)
537 throws IOException {
538 try {
539 createTableAsync(desc, splitKeys);
540 } catch (SocketTimeoutException ste) {
541 LOG.warn("Creating " + desc.getTableName() + " took too long", ste);
542 }
543 int numRegs = (splitKeys == null ? 1 : splitKeys.length + 1) * desc.getRegionReplication();
544 int prevRegCount = 0;
545 boolean doneWithMetaScan = false;
546 for (int tries = 0; tries < this.numRetries * this.retryLongerMultiplier;
547 ++tries) {
548 if (!doneWithMetaScan) {
549
550 final AtomicInteger actualRegCount = new AtomicInteger(0);
551 MetaScannerVisitor visitor = new MetaScannerVisitorBase() {
552 @Override
553 public boolean processRow(Result rowResult) throws IOException {
554 RegionLocations list = MetaTableAccessor.getRegionLocations(rowResult);
555 if (list == null) {
556 LOG.warn("No serialized HRegionInfo in " + rowResult);
557 return true;
558 }
559 HRegionLocation l = list.getRegionLocation();
560 if (l == null) {
561 return true;
562 }
563 if (!l.getRegionInfo().getTable().equals(desc.getTableName())) {
564 return false;
565 }
566 if (l.getRegionInfo().isOffline() || l.getRegionInfo().isSplit()) return true;
567 HRegionLocation[] locations = list.getRegionLocations();
568 for (HRegionLocation location : locations) {
569 if (location == null) continue;
570 ServerName serverName = location.getServerName();
571
572 if (serverName != null && serverName.getHostAndPort() != null) {
573 actualRegCount.incrementAndGet();
574 }
575 }
576 return true;
577 }
578 };
579 MetaScanner.metaScan(connection, visitor, desc.getTableName());
580 if (actualRegCount.get() < numRegs) {
581 if (tries == this.numRetries * this.retryLongerMultiplier - 1) {
582 throw new RegionOfflineException("Only " + actualRegCount.get() +
583 " of " + numRegs + " regions are online; retries exhausted.");
584 }
585 try {
586 Thread.sleep(getPauseTime(tries));
587 } catch (InterruptedException e) {
588 throw new InterruptedIOException("Interrupted when opening" +
589 " regions; " + actualRegCount.get() + " of " + numRegs +
590 " regions processed so far");
591 }
592 if (actualRegCount.get() > prevRegCount) {
593 prevRegCount = actualRegCount.get();
594 tries = -1;
595 }
596 } else {
597 doneWithMetaScan = true;
598 tries = -1;
599 }
600 } else if (isTableEnabled(desc.getTableName())) {
601 return;
602 } else {
603 try {
604 Thread.sleep(getPauseTime(tries));
605 } catch (InterruptedException e) {
606 throw new InterruptedIOException("Interrupted when waiting" +
607 " for table to be enabled; meta scan was done");
608 }
609 }
610 }
611 throw new TableNotEnabledException(
612 "Retries exhausted while still waiting for table: "
613 + desc.getTableName() + " to be enabled");
614 }
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632 @Override
633 public void createTableAsync(
634 final HTableDescriptor desc, final byte [][] splitKeys)
635 throws IOException {
636 if(desc.getTableName() == null) {
637 throw new IllegalArgumentException("TableName cannot be null");
638 }
639 if(splitKeys != null && splitKeys.length > 0) {
640 Arrays.sort(splitKeys, Bytes.BYTES_COMPARATOR);
641
642 byte [] lastKey = null;
643 for(byte [] splitKey : splitKeys) {
644 if (Bytes.compareTo(splitKey, HConstants.EMPTY_BYTE_ARRAY) == 0) {
645 throw new IllegalArgumentException(
646 "Empty split key must not be passed in the split keys.");
647 }
648 if(lastKey != null && Bytes.equals(splitKey, lastKey)) {
649 throw new IllegalArgumentException("All split keys must be unique, " +
650 "found duplicate: " + Bytes.toStringBinary(splitKey) +
651 ", " + Bytes.toStringBinary(lastKey));
652 }
653 lastKey = splitKey;
654 }
655 }
656
657 executeCallable(new MasterCallable<Void>(getConnection()) {
658 @Override
659 public Void call(int callTimeout) throws ServiceException {
660 CreateTableRequest request = RequestConverter.buildCreateTableRequest(desc, splitKeys);
661 master.createTable(null, request);
662 return null;
663 }
664 });
665 }
666
667 public void deleteTable(final String tableName) throws IOException {
668 deleteTable(TableName.valueOf(tableName));
669 }
670
671 public void deleteTable(final byte[] tableName) throws IOException {
672 deleteTable(TableName.valueOf(tableName));
673 }
674
675
676
677
678
679
680
681
682 @Override
683 public void deleteTable(final TableName tableName) throws IOException {
684 boolean tableExists = true;
685
686 executeCallable(new MasterCallable<Void>(getConnection()) {
687 @Override
688 public Void call(int callTimeout) throws ServiceException {
689 DeleteTableRequest req = RequestConverter.buildDeleteTableRequest(tableName);
690 master.deleteTable(null,req);
691 return null;
692 }
693 });
694
695 int failures = 0;
696
697 for (int tries = 0; tries < (this.numRetries * this.retryLongerMultiplier); tries++) {
698 try {
699
700 List<RegionLocations> regionLations =
701 MetaScanner.listTableRegionLocations(conf, connection, tableName);
702
703
704
705 if (regionLations == null || regionLations.size() == 0) {
706 HTableDescriptor htd = getTableDescriptorByTableName(tableName);
707
708 if (htd == null) {
709
710 tableExists = false;
711 break;
712 }
713 }
714 } catch (IOException ex) {
715 failures++;
716 if(failures >= numRetries - 1) {
717 if (ex instanceof RemoteException) {
718 throw ((RemoteException) ex).unwrapRemoteException();
719 } else {
720 throw ex;
721 }
722 }
723 }
724 try {
725 Thread.sleep(getPauseTime(tries));
726 } catch (InterruptedException e) {
727 throw new InterruptedIOException("Interrupted when waiting" +
728 " for table to be deleted");
729 }
730 }
731
732 if (tableExists) {
733 throw new IOException("Retries exhausted, it took too long to wait"+
734 " for the table " + tableName + " to be deleted.");
735 }
736
737 this.connection.clearRegionCache(tableName);
738 LOG.info("Deleted " + tableName);
739 }
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754 @Override
755 public HTableDescriptor[] deleteTables(String regex) throws IOException {
756 return deleteTables(Pattern.compile(regex));
757 }
758
759
760
761
762
763
764
765
766
767
768
769
770 @Override
771 public HTableDescriptor[] deleteTables(Pattern pattern) throws IOException {
772 List<HTableDescriptor> failed = new LinkedList<HTableDescriptor>();
773 for (HTableDescriptor table : listTables(pattern)) {
774 try {
775 deleteTable(table.getTableName());
776 } catch (IOException ex) {
777 LOG.info("Failed to delete table " + table.getTableName(), ex);
778 failed.add(table);
779 }
780 }
781 return failed.toArray(new HTableDescriptor[failed.size()]);
782 }
783
784
785
786
787
788
789
790
791
792 @Override
793 public void truncateTable(final TableName tableName, final boolean preserveSplits)
794 throws IOException {
795 executeCallable(new MasterCallable<Void>(getConnection()) {
796 @Override
797 public Void call(int callTimeout) throws ServiceException {
798 TruncateTableRequest req = RequestConverter.buildTruncateTableRequest(
799 tableName, preserveSplits);
800 master.truncateTable(null, req);
801 return null;
802 }
803 });
804 }
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819 @Override
820 public void enableTable(final TableName tableName)
821 throws IOException {
822 enableTableAsync(tableName);
823
824
825 waitUntilTableIsEnabled(tableName);
826
827 LOG.info("Enabled table " + tableName);
828 }
829
830 public void enableTable(final byte[] tableName)
831 throws IOException {
832 enableTable(TableName.valueOf(tableName));
833 }
834
835 public void enableTable(final String tableName)
836 throws IOException {
837 enableTable(TableName.valueOf(tableName));
838 }
839
840
841
842
843
844
845
846
847 private void waitUntilTableIsEnabled(final TableName tableName) throws IOException {
848 boolean enabled = false;
849 long start = EnvironmentEdgeManager.currentTime();
850 for (int tries = 0; tries < (this.numRetries * this.retryLongerMultiplier); tries++) {
851 try {
852 enabled = isTableEnabled(tableName);
853 } catch (TableNotFoundException tnfe) {
854
855 enabled = false;
856 }
857 enabled = enabled && isTableAvailable(tableName);
858 if (enabled) {
859 break;
860 }
861 long sleep = getPauseTime(tries);
862 if (LOG.isDebugEnabled()) {
863 LOG.debug("Sleeping= " + sleep + "ms, waiting for all regions to be " +
864 "enabled in " + tableName);
865 }
866 try {
867 Thread.sleep(sleep);
868 } catch (InterruptedException e) {
869
870
871 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
872 }
873 }
874 if (!enabled) {
875 long msec = EnvironmentEdgeManager.currentTime() - start;
876 throw new IOException("Table '" + tableName +
877 "' not yet enabled, after " + msec + "ms.");
878 }
879 }
880
881
882
883
884
885
886
887
888
889
890
891 @Override
892 public void enableTableAsync(final TableName tableName)
893 throws IOException {
894 TableName.isLegalFullyQualifiedTableName(tableName.getName());
895 executeCallable(new MasterCallable<Void>(getConnection()) {
896 @Override
897 public Void call(int callTimeout) throws ServiceException {
898 LOG.info("Started enable of " + tableName);
899 EnableTableRequest req = RequestConverter.buildEnableTableRequest(tableName);
900 master.enableTable(null,req);
901 return null;
902 }
903 });
904 }
905
906 public void enableTableAsync(final byte[] tableName)
907 throws IOException {
908 enableTable(TableName.valueOf(tableName));
909 }
910
911 public void enableTableAsync(final String tableName)
912 throws IOException {
913 enableTableAsync(TableName.valueOf(tableName));
914 }
915
916
917
918
919
920
921
922
923
924
925
926
927
928 @Override
929 public HTableDescriptor[] enableTables(String regex) throws IOException {
930 return enableTables(Pattern.compile(regex));
931 }
932
933
934
935
936
937
938
939
940
941
942
943 @Override
944 public HTableDescriptor[] enableTables(Pattern pattern) throws IOException {
945 List<HTableDescriptor> failed = new LinkedList<HTableDescriptor>();
946 for (HTableDescriptor table : listTables(pattern)) {
947 if (isTableDisabled(table.getTableName())) {
948 try {
949 enableTable(table.getTableName());
950 } catch (IOException ex) {
951 LOG.info("Failed to enable table " + table.getTableName(), ex);
952 failed.add(table);
953 }
954 }
955 }
956 return failed.toArray(new HTableDescriptor[failed.size()]);
957 }
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972 @Override
973 public void disableTableAsync(final TableName tableName) throws IOException {
974 TableName.isLegalFullyQualifiedTableName(tableName.getName());
975 executeCallable(new MasterCallable<Void>(getConnection()) {
976 @Override
977 public Void call(int callTimeout) throws ServiceException {
978 LOG.info("Started disable of " + tableName);
979 DisableTableRequest req = RequestConverter.buildDisableTableRequest(tableName);
980 master.disableTable(null,req);
981 return null;
982 }
983 });
984 }
985
986 public void disableTableAsync(final byte[] tableName) throws IOException {
987 disableTableAsync(TableName.valueOf(tableName));
988 }
989
990 public void disableTableAsync(final String tableName) throws IOException {
991 disableTableAsync(TableName.valueOf(tableName));
992 }
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005 @Override
1006 public void disableTable(final TableName tableName)
1007 throws IOException {
1008 disableTableAsync(tableName);
1009
1010 boolean disabled = false;
1011 for (int tries = 0; tries < (this.numRetries * this.retryLongerMultiplier); tries++) {
1012 disabled = isTableDisabled(tableName);
1013 if (disabled) {
1014 break;
1015 }
1016 long sleep = getPauseTime(tries);
1017 if (LOG.isDebugEnabled()) {
1018 LOG.debug("Sleeping= " + sleep + "ms, waiting for all regions to be " +
1019 "disabled in " + tableName);
1020 }
1021 try {
1022 Thread.sleep(sleep);
1023 } catch (InterruptedException e) {
1024
1025
1026 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
1027 }
1028 }
1029 if (!disabled) {
1030 throw new RegionException("Retries exhausted, it took too long to wait"+
1031 " for the table " + tableName + " to be disabled.");
1032 }
1033 LOG.info("Disabled " + tableName);
1034 }
1035
1036 public void disableTable(final byte[] tableName)
1037 throws IOException {
1038 disableTable(TableName.valueOf(tableName));
1039 }
1040
1041 public void disableTable(final String tableName)
1042 throws IOException {
1043 disableTable(TableName.valueOf(tableName));
1044 }
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059 @Override
1060 public HTableDescriptor[] disableTables(String regex) throws IOException {
1061 return disableTables(Pattern.compile(regex));
1062 }
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 @Override
1076 public HTableDescriptor[] disableTables(Pattern pattern) throws IOException {
1077 List<HTableDescriptor> failed = new LinkedList<HTableDescriptor>();
1078 for (HTableDescriptor table : listTables(pattern)) {
1079 if (isTableEnabled(table.getTableName())) {
1080 try {
1081 disableTable(table.getTableName());
1082 } catch (IOException ex) {
1083 LOG.info("Failed to disable table " + table.getTableName(), ex);
1084 failed.add(table);
1085 }
1086 }
1087 }
1088 return failed.toArray(new HTableDescriptor[failed.size()]);
1089 }
1090
1091
1092
1093
1094
1095 private void checkTableExistence(TableName tableName) throws IOException {
1096 if (!tableExists(tableName)) {
1097 throw new TableNotFoundException(tableName);
1098 }
1099 }
1100
1101
1102
1103
1104
1105
1106 @Override
1107 public boolean isTableEnabled(TableName tableName) throws IOException {
1108 checkTableExistence(tableName);
1109 return connection.isTableEnabled(tableName);
1110 }
1111
1112 public boolean isTableEnabled(byte[] tableName) throws IOException {
1113 return isTableEnabled(TableName.valueOf(tableName));
1114 }
1115
1116 public boolean isTableEnabled(String tableName) throws IOException {
1117 return isTableEnabled(TableName.valueOf(tableName));
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127 @Override
1128 public boolean isTableDisabled(TableName tableName) throws IOException {
1129 checkTableExistence(tableName);
1130 return connection.isTableDisabled(tableName);
1131 }
1132
1133 public boolean isTableDisabled(byte[] tableName) throws IOException {
1134 return isTableDisabled(TableName.valueOf(tableName));
1135 }
1136
1137 public boolean isTableDisabled(String tableName) throws IOException {
1138 return isTableDisabled(TableName.valueOf(tableName));
1139 }
1140
1141
1142
1143
1144
1145
1146 @Override
1147 public boolean isTableAvailable(TableName tableName) throws IOException {
1148 return connection.isTableAvailable(tableName);
1149 }
1150
1151 public boolean isTableAvailable(byte[] tableName) throws IOException {
1152 return isTableAvailable(TableName.valueOf(tableName));
1153 }
1154
1155 public boolean isTableAvailable(String tableName) throws IOException {
1156 return isTableAvailable(TableName.valueOf(tableName));
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171 @Override
1172 public boolean isTableAvailable(TableName tableName,
1173 byte[][] splitKeys) throws IOException {
1174 return connection.isTableAvailable(tableName, splitKeys);
1175 }
1176
1177 public boolean isTableAvailable(byte[] tableName,
1178 byte[][] splitKeys) throws IOException {
1179 return isTableAvailable(TableName.valueOf(tableName), splitKeys);
1180 }
1181
1182 public boolean isTableAvailable(String tableName,
1183 byte[][] splitKeys) throws IOException {
1184 return isTableAvailable(TableName.valueOf(tableName), splitKeys);
1185 }
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 @Override
1199 public Pair<Integer, Integer> getAlterStatus(final TableName tableName)
1200 throws IOException {
1201 return executeCallable(new MasterCallable<Pair<Integer, Integer>>(getConnection()) {
1202 @Override
1203 public Pair<Integer, Integer> call(int callTimeout) throws ServiceException {
1204 GetSchemaAlterStatusRequest req = RequestConverter
1205 .buildGetSchemaAlterStatusRequest(tableName);
1206 GetSchemaAlterStatusResponse ret = master.getSchemaAlterStatus(null, req);
1207 Pair<Integer, Integer> pair = new Pair<Integer, Integer>(Integer.valueOf(ret
1208 .getYetToUpdateRegions()), Integer.valueOf(ret.getTotalRegions()));
1209 return pair;
1210 }
1211 });
1212 }
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 @Override
1227 public Pair<Integer, Integer> getAlterStatus(final byte[] tableName)
1228 throws IOException {
1229 return getAlterStatus(TableName.valueOf(tableName));
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240 public void addColumn(final byte[] tableName, HColumnDescriptor column)
1241 throws IOException {
1242 addColumn(TableName.valueOf(tableName), column);
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254 public void addColumn(final String tableName, HColumnDescriptor column)
1255 throws IOException {
1256 addColumn(TableName.valueOf(tableName), column);
1257 }
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267 @Override
1268 public void addColumn(final TableName tableName, final HColumnDescriptor column)
1269 throws IOException {
1270 executeCallable(new MasterCallable<Void>(getConnection()) {
1271 @Override
1272 public Void call(int callTimeout) throws ServiceException {
1273 AddColumnRequest req = RequestConverter.buildAddColumnRequest(tableName, column);
1274 master.addColumn(null,req);
1275 return null;
1276 }
1277 });
1278 }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288 public void deleteColumn(final byte[] tableName, final String columnName)
1289 throws IOException {
1290 deleteColumn(TableName.valueOf(tableName), Bytes.toBytes(columnName));
1291 }
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301 public void deleteColumn(final String tableName, final String columnName)
1302 throws IOException {
1303 deleteColumn(TableName.valueOf(tableName), Bytes.toBytes(columnName));
1304 }
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314 @Override
1315 public void deleteColumn(final TableName tableName, final byte [] columnName)
1316 throws IOException {
1317 executeCallable(new MasterCallable<Void>(getConnection()) {
1318 @Override
1319 public Void call(int callTimeout) throws ServiceException {
1320 DeleteColumnRequest req = RequestConverter.buildDeleteColumnRequest(tableName, columnName);
1321 master.deleteColumn(null,req);
1322 return null;
1323 }
1324 });
1325 }
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335 public void modifyColumn(final String tableName, HColumnDescriptor descriptor)
1336 throws IOException {
1337 modifyColumn(TableName.valueOf(tableName), descriptor);
1338 }
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348 public void modifyColumn(final byte[] tableName, HColumnDescriptor descriptor)
1349 throws IOException {
1350 modifyColumn(TableName.valueOf(tableName), descriptor);
1351 }
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363 @Override
1364 public void modifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
1365 throws IOException {
1366 executeCallable(new MasterCallable<Void>(getConnection()) {
1367 @Override
1368 public Void call(int callTimeout) throws ServiceException {
1369 ModifyColumnRequest req = RequestConverter.buildModifyColumnRequest(tableName, descriptor);
1370 master.modifyColumn(null,req);
1371 return null;
1372 }
1373 });
1374 }
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384 @Override
1385 public void closeRegion(final String regionname, final String serverName)
1386 throws IOException {
1387 closeRegion(Bytes.toBytes(regionname), serverName);
1388 }
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400 @Override
1401 public void closeRegion(final byte [] regionname, final String serverName)
1402 throws IOException {
1403 if (serverName != null) {
1404 Pair<HRegionInfo, ServerName> pair = MetaTableAccessor.getRegion(connection, regionname);
1405 if (pair == null || pair.getFirst() == null) {
1406 throw new UnknownRegionException(Bytes.toStringBinary(regionname));
1407 } else {
1408 closeRegion(ServerName.valueOf(serverName), pair.getFirst());
1409 }
1410 } else {
1411 Pair<HRegionInfo, ServerName> pair = MetaTableAccessor.getRegion(connection, regionname);
1412 if (pair == null) {
1413 throw new UnknownRegionException(Bytes.toStringBinary(regionname));
1414 } else if (pair.getSecond() == null) {
1415 throw new NoServerForRegionException(Bytes.toStringBinary(regionname));
1416 } else {
1417 closeRegion(pair.getSecond(), pair.getFirst());
1418 }
1419 }
1420 }
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443 @Override
1444 public boolean closeRegionWithEncodedRegionName(final String encodedRegionName,
1445 final String serverName) throws IOException {
1446 if (null == serverName || ("").equals(serverName.trim())) {
1447 throw new IllegalArgumentException(
1448 "The servername cannot be null or empty.");
1449 }
1450 ServerName sn = ServerName.valueOf(serverName);
1451 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1452
1453 CloseRegionRequest request =
1454 RequestConverter.buildCloseRegionRequest(sn, encodedRegionName, false);
1455 try {
1456 CloseRegionResponse response = admin.closeRegion(null, request);
1457 boolean isRegionClosed = response.getClosed();
1458 if (false == isRegionClosed) {
1459 LOG.error("Not able to close the region " + encodedRegionName + ".");
1460 }
1461 return isRegionClosed;
1462 } catch (ServiceException se) {
1463 throw ProtobufUtil.getRemoteException(se);
1464 }
1465 }
1466
1467
1468
1469
1470
1471
1472
1473
1474 @Override
1475 public void closeRegion(final ServerName sn, final HRegionInfo hri)
1476 throws IOException {
1477 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1478
1479 ProtobufUtil.closeRegion(admin, sn, hri.getRegionName(), false);
1480 }
1481
1482
1483
1484
1485 @Override
1486 public List<HRegionInfo> getOnlineRegions(final ServerName sn) throws IOException {
1487 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1488 return ProtobufUtil.getOnlineRegions(admin);
1489 }
1490
1491
1492
1493
1494 @Override
1495 public void flush(final TableName tableName) throws IOException {
1496 checkTableExists(tableName);
1497 if (isTableDisabled(tableName)) {
1498 LOG.info("Table is disabled: " + tableName.getNameAsString());
1499 return;
1500 }
1501 execProcedure("flush-table-proc", tableName.getNameAsString(),
1502 new HashMap<String, String>());
1503 }
1504
1505
1506
1507
1508 @Override
1509 public void flushRegion(final byte[] regionName) throws IOException {
1510 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
1511 if (regionServerPair == null) {
1512 throw new IllegalArgumentException("Unknown regionname: " + Bytes.toStringBinary(regionName));
1513 }
1514 if (regionServerPair.getSecond() == null) {
1515 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
1516 }
1517 flush(regionServerPair.getSecond(), regionServerPair.getFirst());
1518 }
1519
1520
1521
1522
1523
1524 @Deprecated
1525 public void flush(final String tableNameOrRegionName)
1526 throws IOException, InterruptedException {
1527 flush(Bytes.toBytes(tableNameOrRegionName));
1528 }
1529
1530
1531
1532
1533
1534 @Deprecated
1535 public void flush(final byte[] tableNameOrRegionName)
1536 throws IOException, InterruptedException {
1537 try {
1538 flushRegion(tableNameOrRegionName);
1539 } catch (IllegalArgumentException e) {
1540
1541 flush(TableName.valueOf(tableNameOrRegionName));
1542 }
1543 }
1544
1545 private void flush(final ServerName sn, final HRegionInfo hri)
1546 throws IOException {
1547 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1548 FlushRegionRequest request =
1549 RequestConverter.buildFlushRegionRequest(hri.getRegionName());
1550 try {
1551 admin.flushRegion(null, request);
1552 } catch (ServiceException se) {
1553 throw ProtobufUtil.getRemoteException(se);
1554 }
1555 }
1556
1557
1558
1559
1560 @Override
1561 public void compact(final TableName tableName)
1562 throws IOException {
1563 compact(tableName, null, false);
1564 }
1565
1566
1567
1568
1569 @Override
1570 public void compactRegion(final byte[] regionName)
1571 throws IOException {
1572 compactRegion(regionName, null, false);
1573 }
1574
1575
1576
1577
1578
1579 @Deprecated
1580 public void compact(final String tableNameOrRegionName)
1581 throws IOException {
1582 compact(Bytes.toBytes(tableNameOrRegionName));
1583 }
1584
1585
1586
1587
1588
1589 @Deprecated
1590 public void compact(final byte[] tableNameOrRegionName)
1591 throws IOException {
1592 try {
1593 compactRegion(tableNameOrRegionName, null, false);
1594 } catch (IllegalArgumentException e) {
1595 compact(TableName.valueOf(tableNameOrRegionName), null, false);
1596 }
1597 }
1598
1599
1600
1601
1602 @Override
1603 public void compact(final TableName tableName, final byte[] columnFamily)
1604 throws IOException {
1605 compact(tableName, columnFamily, false);
1606 }
1607
1608
1609
1610
1611 @Override
1612 public void compactRegion(final byte[] regionName, final byte[] columnFamily)
1613 throws IOException {
1614 compactRegion(regionName, columnFamily, false);
1615 }
1616
1617
1618
1619
1620
1621 @Deprecated
1622 public void compact(String tableOrRegionName, String columnFamily)
1623 throws IOException {
1624 compact(Bytes.toBytes(tableOrRegionName), Bytes.toBytes(columnFamily));
1625 }
1626
1627
1628
1629
1630
1631 @Deprecated
1632 public void compact(final byte[] tableNameOrRegionName, final byte[] columnFamily)
1633 throws IOException {
1634 try {
1635 compactRegion(tableNameOrRegionName, columnFamily, false);
1636 } catch (IllegalArgumentException e) {
1637
1638 compact(TableName.valueOf(tableNameOrRegionName), columnFamily, false);
1639 }
1640 }
1641
1642
1643
1644
1645 @Override
1646 public void compactRegionServer(final ServerName sn, boolean major)
1647 throws IOException, InterruptedException {
1648 for (HRegionInfo region : getOnlineRegions(sn)) {
1649 compact(sn, region, major, null);
1650 }
1651 }
1652
1653
1654
1655
1656 @Override
1657 public void majorCompact(final TableName tableName)
1658 throws IOException {
1659 compact(tableName, null, true);
1660 }
1661
1662
1663
1664
1665 @Override
1666 public void majorCompactRegion(final byte[] regionName)
1667 throws IOException {
1668 compactRegion(regionName, null, true);
1669 }
1670
1671
1672
1673
1674
1675 @Deprecated
1676 public void majorCompact(final String tableNameOrRegionName)
1677 throws IOException {
1678 majorCompact(Bytes.toBytes(tableNameOrRegionName));
1679 }
1680
1681
1682
1683
1684
1685 @Deprecated
1686 public void majorCompact(final byte[] tableNameOrRegionName)
1687 throws IOException {
1688 try {
1689 compactRegion(tableNameOrRegionName, null, true);
1690 } catch (IllegalArgumentException e) {
1691
1692 compact(TableName.valueOf(tableNameOrRegionName), null, true);
1693 }
1694 }
1695
1696
1697
1698
1699 @Override
1700 public void majorCompact(final TableName tableName, final byte[] columnFamily)
1701 throws IOException {
1702 compact(tableName, columnFamily, true);
1703 }
1704
1705
1706
1707
1708 @Override
1709 public void majorCompactRegion(final byte[] regionName, final byte[] columnFamily)
1710 throws IOException {
1711 compactRegion(regionName, columnFamily, true);
1712 }
1713
1714
1715
1716
1717
1718 @Deprecated
1719 public void majorCompact(final String tableNameOrRegionName, final String columnFamily)
1720 throws IOException {
1721 majorCompact(Bytes.toBytes(tableNameOrRegionName), Bytes.toBytes(columnFamily));
1722 }
1723
1724
1725
1726
1727
1728 @Deprecated
1729 public void majorCompact(final byte[] tableNameOrRegionName, final byte[] columnFamily)
1730 throws IOException {
1731 try {
1732 compactRegion(tableNameOrRegionName, columnFamily, true);
1733 } catch (IllegalArgumentException e) {
1734
1735 compact(TableName.valueOf(tableNameOrRegionName), columnFamily, true);
1736 }
1737 }
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749 private void compact(final TableName tableName, final byte[] columnFamily,final boolean major)
1750 throws IOException {
1751 ZooKeeperWatcher zookeeper = null;
1752 try {
1753 checkTableExists(tableName);
1754 zookeeper = new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
1755 new ThrowableAbortable());
1756 List<Pair<HRegionInfo, ServerName>> pairs =
1757 MetaTableAccessor.getTableRegionsAndLocations(zookeeper, connection, tableName);
1758 for (Pair<HRegionInfo, ServerName> pair: pairs) {
1759 if (pair.getFirst().isOffline()) continue;
1760 if (pair.getSecond() == null) continue;
1761 try {
1762 compact(pair.getSecond(), pair.getFirst(), major, columnFamily);
1763 } catch (NotServingRegionException e) {
1764 if (LOG.isDebugEnabled()) {
1765 LOG.debug("Trying to" + (major ? " major" : "") + " compact " +
1766 pair.getFirst() + ": " +
1767 StringUtils.stringifyException(e));
1768 }
1769 }
1770 }
1771 } finally {
1772 if (zookeeper != null) {
1773 zookeeper.close();
1774 }
1775 }
1776 }
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788 private void compactRegion(final byte[] regionName, final byte[] columnFamily,final boolean major)
1789 throws IOException {
1790 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
1791 if (regionServerPair == null) {
1792 throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName));
1793 }
1794 if (regionServerPair.getSecond() == null) {
1795 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
1796 }
1797 compact(regionServerPair.getSecond(), regionServerPair.getFirst(), major, columnFamily);
1798 }
1799
1800 private void compact(final ServerName sn, final HRegionInfo hri,
1801 final boolean major, final byte [] family)
1802 throws IOException {
1803 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1804 CompactRegionRequest request =
1805 RequestConverter.buildCompactRegionRequest(hri.getRegionName(), major, family);
1806 try {
1807 admin.compactRegion(null, request);
1808 } catch (ServiceException se) {
1809 throw ProtobufUtil.getRemoteException(se);
1810 }
1811 }
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826 @Override
1827 public void move(final byte [] encodedRegionName, final byte [] destServerName)
1828 throws IOException {
1829
1830 executeCallable(new MasterCallable<Void>(getConnection()) {
1831 @Override
1832 public Void call(int callTimeout) throws ServiceException {
1833 try {
1834 MoveRegionRequest request =
1835 RequestConverter.buildMoveRegionRequest(encodedRegionName, destServerName);
1836 master.moveRegion(null, request);
1837 } catch (DeserializationException de) {
1838 LOG.error("Could not parse destination server name: " + de);
1839 throw new ServiceException(new DoNotRetryIOException(de));
1840 }
1841 return null;
1842 }
1843 });
1844 }
1845
1846
1847
1848
1849
1850
1851
1852
1853 @Override
1854 public void assign(final byte[] regionName) throws MasterNotRunningException,
1855 ZooKeeperConnectionException, IOException {
1856 final byte[] toBeAssigned = getRegionName(regionName);
1857 executeCallable(new MasterCallable<Void>(getConnection()) {
1858 @Override
1859 public Void call(int callTimeout) throws ServiceException {
1860 AssignRegionRequest request =
1861 RequestConverter.buildAssignRegionRequest(toBeAssigned);
1862 master.assignRegion(null,request);
1863 return null;
1864 }
1865 });
1866 }
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882 @Override
1883 public void unassign(final byte [] regionName, final boolean force)
1884 throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
1885 final byte[] toBeUnassigned = getRegionName(regionName);
1886 executeCallable(new MasterCallable<Void>(getConnection()) {
1887 @Override
1888 public Void call(int callTimeout) throws ServiceException {
1889 UnassignRegionRequest request =
1890 RequestConverter.buildUnassignRegionRequest(toBeUnassigned, force);
1891 master.unassignRegion(null, request);
1892 return null;
1893 }
1894 });
1895 }
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909 @Override
1910 public void offline(final byte [] regionName)
1911 throws IOException {
1912 executeCallable(new MasterCallable<Void>(getConnection()) {
1913 @Override
1914 public Void call(int callTimeout) throws ServiceException {
1915 master.offlineRegion(null,RequestConverter.buildOfflineRegionRequest(regionName));
1916 return null;
1917 }
1918 });
1919 }
1920
1921
1922
1923
1924
1925
1926
1927 @Override
1928 public boolean setBalancerRunning(final boolean on, final boolean synchronous)
1929 throws IOException {
1930 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
1931 @Override
1932 public Boolean call(int callTimeout) throws ServiceException {
1933 SetBalancerRunningRequest req =
1934 RequestConverter.buildSetBalancerRunningRequest(on, synchronous);
1935 return master.setBalancerRunning(null, req).getPrevBalanceValue();
1936 }
1937 });
1938 }
1939
1940
1941
1942
1943
1944
1945
1946 @Override
1947 public boolean balancer() throws IOException {
1948 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
1949 @Override
1950 public Boolean call(int callTimeout) throws ServiceException {
1951 return master.balance(null, RequestConverter.buildBalanceRequest()).getBalancerRan();
1952 }
1953 });
1954 }
1955
1956
1957
1958
1959
1960
1961
1962 @Override
1963 public boolean enableCatalogJanitor(final boolean enable)
1964 throws IOException {
1965 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
1966 @Override
1967 public Boolean call(int callTimeout) throws ServiceException {
1968 return master.enableCatalogJanitor(null,
1969 RequestConverter.buildEnableCatalogJanitorRequest(enable)).getPrevValue();
1970 }
1971 });
1972 }
1973
1974
1975
1976
1977
1978
1979 @Override
1980 public int runCatalogScan() throws IOException {
1981 return executeCallable(new MasterCallable<Integer>(getConnection()) {
1982 @Override
1983 public Integer call(int callTimeout) throws ServiceException {
1984 return master.runCatalogScan(null,
1985 RequestConverter.buildCatalogScanRequest()).getScanResult();
1986 }
1987 });
1988 }
1989
1990
1991
1992
1993
1994 @Override
1995 public boolean isCatalogJanitorEnabled() throws IOException {
1996 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
1997 @Override
1998 public Boolean call(int callTimeout) throws ServiceException {
1999 return master.isCatalogJanitorEnabled(null,
2000 RequestConverter.buildIsCatalogJanitorEnabledRequest()).getValue();
2001 }
2002 });
2003 }
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013 @Override
2014 public void mergeRegions(final byte[] encodedNameOfRegionA,
2015 final byte[] encodedNameOfRegionB, final boolean forcible)
2016 throws IOException {
2017
2018 executeCallable(new MasterCallable<Void>(getConnection()) {
2019 @Override
2020 public Void call(int callTimeout) throws ServiceException {
2021 try {
2022 DispatchMergingRegionsRequest request = RequestConverter
2023 .buildDispatchMergingRegionsRequest(encodedNameOfRegionA,
2024 encodedNameOfRegionB, forcible);
2025 master.dispatchMergingRegions(null, request);
2026 } catch (DeserializationException de) {
2027 LOG.error("Could not parse destination server name: " + de);
2028 }
2029 return null;
2030 }
2031 });
2032 }
2033
2034
2035
2036
2037 @Override
2038 public void split(final TableName tableName)
2039 throws IOException {
2040 split(tableName, null);
2041 }
2042
2043
2044
2045
2046 @Override
2047 public void splitRegion(final byte[] regionName)
2048 throws IOException {
2049 splitRegion(regionName, null);
2050 }
2051
2052
2053
2054
2055
2056 @Deprecated
2057 public void split(final String tableNameOrRegionName)
2058 throws IOException, InterruptedException {
2059 split(Bytes.toBytes(tableNameOrRegionName));
2060 }
2061
2062
2063
2064
2065
2066 @Deprecated
2067 public void split(final byte[] tableNameOrRegionName)
2068 throws IOException, InterruptedException {
2069 split(tableNameOrRegionName, null);
2070 }
2071
2072
2073
2074
2075 @Override
2076 public void split(final TableName tableName, final byte [] splitPoint)
2077 throws IOException {
2078 ZooKeeperWatcher zookeeper = null;
2079 try {
2080 checkTableExists(tableName);
2081 zookeeper = new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
2082 new ThrowableAbortable());
2083 List<Pair<HRegionInfo, ServerName>> pairs =
2084 MetaTableAccessor.getTableRegionsAndLocations(zookeeper, connection, tableName);
2085 for (Pair<HRegionInfo, ServerName> pair: pairs) {
2086
2087 if (pair.getSecond() == null) continue;
2088 HRegionInfo r = pair.getFirst();
2089
2090 if (r.isSplitParent()) continue;
2091
2092 if (splitPoint != null && !r.containsRow(splitPoint)) continue;
2093
2094 split(pair.getSecond(), pair.getFirst(), splitPoint);
2095 }
2096 } finally {
2097 if (zookeeper != null) {
2098 zookeeper.close();
2099 }
2100 }
2101 }
2102
2103
2104
2105
2106 @Override
2107 public void splitRegion(final byte[] regionName, final byte [] splitPoint)
2108 throws IOException {
2109 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
2110 if (regionServerPair == null) {
2111 throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName));
2112 }
2113 if (regionServerPair.getSecond() == null) {
2114 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
2115 }
2116 split(regionServerPair.getSecond(), regionServerPair.getFirst(), splitPoint);
2117 }
2118
2119
2120
2121
2122
2123 @Deprecated
2124 public void split(final String tableNameOrRegionName,
2125 final String splitPoint) throws IOException {
2126 split(Bytes.toBytes(tableNameOrRegionName), Bytes.toBytes(splitPoint));
2127 }
2128
2129
2130
2131
2132
2133 @Deprecated
2134 public void split(final byte[] tableNameOrRegionName,
2135 final byte [] splitPoint) throws IOException {
2136 try {
2137 splitRegion(tableNameOrRegionName, splitPoint);
2138 } catch (IllegalArgumentException e) {
2139
2140 split(TableName.valueOf(tableNameOrRegionName), splitPoint);
2141 }
2142 }
2143
2144 private void split(final ServerName sn, final HRegionInfo hri,
2145 byte[] splitPoint) throws IOException {
2146 if (hri.getStartKey() != null && splitPoint != null &&
2147 Bytes.compareTo(hri.getStartKey(), splitPoint) == 0) {
2148 throw new IOException("should not give a splitkey which equals to startkey!");
2149 }
2150
2151 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
2152 ProtobufUtil.split(admin, hri, splitPoint);
2153 }
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164 @Override
2165 public void modifyTable(final TableName tableName, final HTableDescriptor htd)
2166 throws IOException {
2167 if (!tableName.equals(htd.getTableName())) {
2168 throw new IllegalArgumentException("the specified table name '" + tableName +
2169 "' doesn't match with the HTD one: " + htd.getTableName());
2170 }
2171
2172 executeCallable(new MasterCallable<Void>(getConnection()) {
2173 @Override
2174 public Void call(int callTimeout) throws ServiceException {
2175 ModifyTableRequest request = RequestConverter.buildModifyTableRequest(tableName, htd);
2176 master.modifyTable(null, request);
2177 return null;
2178 }
2179 });
2180 }
2181
2182 public void modifyTable(final byte[] tableName, final HTableDescriptor htd)
2183 throws IOException {
2184 modifyTable(TableName.valueOf(tableName), htd);
2185 }
2186
2187 public void modifyTable(final String tableName, final HTableDescriptor htd)
2188 throws IOException {
2189 modifyTable(TableName.valueOf(tableName), htd);
2190 }
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201 Pair<HRegionInfo, ServerName> getRegion(final byte[] regionName) throws IOException {
2202 if (regionName == null) {
2203 throw new IllegalArgumentException("Pass a table name or region name");
2204 }
2205 Pair<HRegionInfo, ServerName> pair =
2206 MetaTableAccessor.getRegion(connection, regionName);
2207 if (pair == null) {
2208 final AtomicReference<Pair<HRegionInfo, ServerName>> result =
2209 new AtomicReference<Pair<HRegionInfo, ServerName>>(null);
2210 final String encodedName = Bytes.toString(regionName);
2211 MetaScannerVisitor visitor = new MetaScannerVisitorBase() {
2212 @Override
2213 public boolean processRow(Result data) throws IOException {
2214 HRegionInfo info = HRegionInfo.getHRegionInfo(data);
2215 if (info == null) {
2216 LOG.warn("No serialized HRegionInfo in " + data);
2217 return true;
2218 }
2219 if (!encodedName.equals(info.getEncodedName())) return true;
2220 ServerName sn = HRegionInfo.getServerName(data);
2221 result.set(new Pair<HRegionInfo, ServerName>(info, sn));
2222 return false;
2223 }
2224 };
2225
2226 MetaScanner.metaScan(connection, visitor, null);
2227 pair = result.get();
2228 }
2229 return pair;
2230 }
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240 private byte[] getRegionName(
2241 final byte[] regionNameOrEncodedRegionName) throws IOException {
2242 if (Bytes.equals(regionNameOrEncodedRegionName,
2243 HRegionInfo.FIRST_META_REGIONINFO.getRegionName())
2244 || Bytes.equals(regionNameOrEncodedRegionName,
2245 HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes())) {
2246 return HRegionInfo.FIRST_META_REGIONINFO.getRegionName();
2247 }
2248 byte[] tmp = regionNameOrEncodedRegionName;
2249 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionNameOrEncodedRegionName);
2250 if (regionServerPair != null && regionServerPair.getFirst() != null) {
2251 tmp = regionServerPair.getFirst().getRegionName();
2252 }
2253 return tmp;
2254 }
2255
2256
2257
2258
2259
2260
2261
2262
2263 private TableName checkTableExists(final TableName tableName)
2264 throws IOException {
2265 if (!MetaTableAccessor.tableExists(connection, tableName)) {
2266 throw new TableNotFoundException(tableName);
2267 }
2268 return tableName;
2269 }
2270
2271
2272
2273
2274
2275 @Override
2276 public synchronized void shutdown() throws IOException {
2277 executeCallable(new MasterCallable<Void>(getConnection()) {
2278 @Override
2279 public Void call(int callTimeout) throws ServiceException {
2280 master.shutdown(null,ShutdownRequest.newBuilder().build());
2281 return null;
2282 }
2283 });
2284 }
2285
2286
2287
2288
2289
2290
2291
2292 @Override
2293 public synchronized void stopMaster() throws IOException {
2294 executeCallable(new MasterCallable<Void>(getConnection()) {
2295 @Override
2296 public Void call(int callTimeout) throws ServiceException {
2297 master.stopMaster(null, StopMasterRequest.newBuilder().build());
2298 return null;
2299 }
2300 });
2301 }
2302
2303
2304
2305
2306
2307
2308
2309 @Override
2310 public synchronized void stopRegionServer(final String hostnamePort)
2311 throws IOException {
2312 String hostname = Addressing.parseHostname(hostnamePort);
2313 int port = Addressing.parsePort(hostnamePort);
2314 AdminService.BlockingInterface admin =
2315 this.connection.getAdmin(ServerName.valueOf(hostname, port, 0));
2316 StopServerRequest request = RequestConverter.buildStopServerRequest(
2317 "Called by admin client " + this.connection.toString());
2318 try {
2319 admin.stopServer(null, request);
2320 } catch (ServiceException se) {
2321 throw ProtobufUtil.getRemoteException(se);
2322 }
2323 }
2324
2325
2326
2327
2328
2329
2330 @Override
2331 public ClusterStatus getClusterStatus() throws IOException {
2332 return executeCallable(new MasterCallable<ClusterStatus>(getConnection()) {
2333 @Override
2334 public ClusterStatus call(int callTimeout) throws ServiceException {
2335 GetClusterStatusRequest req = RequestConverter.buildGetClusterStatusRequest();
2336 return ClusterStatus.convert(master.getClusterStatus(null, req).getClusterStatus());
2337 }
2338 });
2339 }
2340
2341
2342
2343
2344 @Override
2345 public Configuration getConfiguration() {
2346 return this.conf;
2347 }
2348
2349
2350
2351
2352
2353
2354 @Override
2355 public void createNamespace(final NamespaceDescriptor descriptor) throws IOException {
2356 executeCallable(new MasterCallable<Void>(getConnection()) {
2357 @Override
2358 public Void call(int callTimeout) throws Exception {
2359 master.createNamespace(null,
2360 CreateNamespaceRequest.newBuilder()
2361 .setNamespaceDescriptor(ProtobufUtil
2362 .toProtoNamespaceDescriptor(descriptor)).build()
2363 );
2364 return null;
2365 }
2366 });
2367 }
2368
2369
2370
2371
2372
2373
2374 @Override
2375 public void modifyNamespace(final NamespaceDescriptor descriptor) throws IOException {
2376 executeCallable(new MasterCallable<Void>(getConnection()) {
2377 @Override
2378 public Void call(int callTimeout) throws Exception {
2379 master.modifyNamespace(null, ModifyNamespaceRequest.newBuilder().
2380 setNamespaceDescriptor(ProtobufUtil.toProtoNamespaceDescriptor(descriptor)).build());
2381 return null;
2382 }
2383 });
2384 }
2385
2386
2387
2388
2389
2390
2391 @Override
2392 public void deleteNamespace(final String name) throws IOException {
2393 executeCallable(new MasterCallable<Void>(getConnection()) {
2394 @Override
2395 public Void call(int callTimeout) throws Exception {
2396 master.deleteNamespace(null, DeleteNamespaceRequest.newBuilder().
2397 setNamespaceName(name).build());
2398 return null;
2399 }
2400 });
2401 }
2402
2403
2404
2405
2406
2407
2408
2409 @Override
2410 public NamespaceDescriptor getNamespaceDescriptor(final String name) throws IOException {
2411 return
2412 executeCallable(new MasterCallable<NamespaceDescriptor>(getConnection()) {
2413 @Override
2414 public NamespaceDescriptor call(int callTimeout) throws Exception {
2415 return ProtobufUtil.toNamespaceDescriptor(
2416 master.getNamespaceDescriptor(null, GetNamespaceDescriptorRequest.newBuilder().
2417 setNamespaceName(name).build()).getNamespaceDescriptor());
2418 }
2419 });
2420 }
2421
2422
2423
2424
2425
2426
2427 @Override
2428 public NamespaceDescriptor[] listNamespaceDescriptors() throws IOException {
2429 return
2430 executeCallable(new MasterCallable<NamespaceDescriptor[]>(getConnection()) {
2431 @Override
2432 public NamespaceDescriptor[] call(int callTimeout) throws Exception {
2433 List<HBaseProtos.NamespaceDescriptor> list =
2434 master.listNamespaceDescriptors(null, ListNamespaceDescriptorsRequest.newBuilder().
2435 build()).getNamespaceDescriptorList();
2436 NamespaceDescriptor[] res = new NamespaceDescriptor[list.size()];
2437 for(int i = 0; i < list.size(); i++) {
2438 res[i] = ProtobufUtil.toNamespaceDescriptor(list.get(i));
2439 }
2440 return res;
2441 }
2442 });
2443 }
2444
2445
2446
2447
2448
2449
2450
2451 @Override
2452 public HTableDescriptor[] listTableDescriptorsByNamespace(final String name) throws IOException {
2453 return
2454 executeCallable(new MasterCallable<HTableDescriptor[]>(getConnection()) {
2455 @Override
2456 public HTableDescriptor[] call(int callTimeout) throws Exception {
2457 List<TableSchema> list =
2458 master.listTableDescriptorsByNamespace(null, ListTableDescriptorsByNamespaceRequest.
2459 newBuilder().setNamespaceName(name).build()).getTableSchemaList();
2460 HTableDescriptor[] res = new HTableDescriptor[list.size()];
2461 for(int i=0; i < list.size(); i++) {
2462
2463 res[i] = HTableDescriptor.convert(list.get(i));
2464 }
2465 return res;
2466 }
2467 });
2468 }
2469
2470
2471
2472
2473
2474
2475
2476 @Override
2477 public TableName[] listTableNamesByNamespace(final String name) throws IOException {
2478 return
2479 executeCallable(new MasterCallable<TableName[]>(getConnection()) {
2480 @Override
2481 public TableName[] call(int callTimeout) throws Exception {
2482 List<HBaseProtos.TableName> tableNames =
2483 master.listTableNamesByNamespace(null, ListTableNamesByNamespaceRequest.
2484 newBuilder().setNamespaceName(name).build())
2485 .getTableNameList();
2486 TableName[] result = new TableName[tableNames.size()];
2487 for (int i = 0; i < tableNames.size(); i++) {
2488 result[i] = ProtobufUtil.toTableName(tableNames.get(i));
2489 }
2490 return result;
2491 }
2492 });
2493 }
2494
2495
2496
2497
2498
2499
2500
2501
2502 public static void checkHBaseAvailable(Configuration conf)
2503 throws MasterNotRunningException, ZooKeeperConnectionException, ServiceException, IOException {
2504 Configuration copyOfConf = HBaseConfiguration.create(conf);
2505
2506 copyOfConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
2507 copyOfConf.setInt("zookeeper.recovery.retry", 0);
2508 try (ClusterConnection connection =
2509 (ClusterConnection)ConnectionFactory.createConnection(copyOfConf)) {
2510
2511
2512 ZooKeeperKeepAliveConnection zkw = null;
2513 try {
2514
2515 zkw = ((ConnectionManager.HConnectionImplementation)connection).
2516 getKeepAliveZooKeeperWatcher();
2517 zkw.getRecoverableZooKeeper().getZooKeeper().exists(zkw.baseZNode, false);
2518 } catch (IOException e) {
2519 throw new ZooKeeperConnectionException("Can't connect to ZooKeeper", e);
2520 } catch (InterruptedException e) {
2521 throw (InterruptedIOException)
2522 new InterruptedIOException("Can't connect to ZooKeeper").initCause(e);
2523 } catch (KeeperException e) {
2524 throw new ZooKeeperConnectionException("Can't connect to ZooKeeper", e);
2525 } finally {
2526 if (zkw != null) {
2527 zkw.close();
2528 }
2529 }
2530 connection.isMasterRunning();
2531 }
2532 }
2533
2534
2535
2536
2537
2538
2539
2540
2541 @Override
2542 public List<HRegionInfo> getTableRegions(final TableName tableName)
2543 throws IOException {
2544 ZooKeeperWatcher zookeeper =
2545 new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
2546 new ThrowableAbortable());
2547 List<HRegionInfo> Regions = null;
2548 try {
2549 Regions = MetaTableAccessor.getTableRegions(zookeeper, connection, tableName, true);
2550 } finally {
2551 zookeeper.close();
2552 }
2553 return Regions;
2554 }
2555
2556 public List<HRegionInfo> getTableRegions(final byte[] tableName)
2557 throws IOException {
2558 return getTableRegions(TableName.valueOf(tableName));
2559 }
2560
2561 @Override
2562 public synchronized void close() throws IOException {
2563 if (cleanupConnectionOnClose && this.connection != null && !this.closed) {
2564 this.connection.close();
2565 this.closed = true;
2566 }
2567 }
2568
2569
2570
2571
2572
2573
2574
2575 @Override
2576 public HTableDescriptor[] getTableDescriptorsByTableName(final List<TableName> tableNames)
2577 throws IOException {
2578 return executeCallable(new MasterCallable<HTableDescriptor[]>(getConnection()) {
2579 @Override
2580 public HTableDescriptor[] call(int callTimeout) throws Exception {
2581 GetTableDescriptorsRequest req =
2582 RequestConverter.buildGetTableDescriptorsRequest(tableNames);
2583 return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(null, req));
2584 }
2585 });
2586 }
2587
2588
2589
2590
2591
2592
2593
2594 private HTableDescriptor getTableDescriptorByTableName(TableName tableName)
2595 throws IOException {
2596 List<TableName> tableNames = new ArrayList<TableName>(1);
2597 tableNames.add(tableName);
2598
2599 HTableDescriptor[] htdl = getTableDescriptorsByTableName(tableNames);
2600
2601 if (htdl == null || htdl.length == 0) {
2602 return null;
2603 }
2604 else {
2605 return htdl[0];
2606 }
2607 }
2608
2609
2610
2611
2612
2613
2614
2615 @Override
2616 public HTableDescriptor[] getTableDescriptors(List<String> names)
2617 throws IOException {
2618 List<TableName> tableNames = new ArrayList<TableName>(names.size());
2619 for(String name : names) {
2620 tableNames.add(TableName.valueOf(name));
2621 }
2622 return getTableDescriptorsByTableName(tableNames);
2623 }
2624
2625 private RollWALWriterResponse rollWALWriterImpl(final ServerName sn) throws IOException,
2626 FailedLogCloseException {
2627 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
2628 RollWALWriterRequest request = RequestConverter.buildRollWALWriterRequest();
2629 try {
2630 return admin.rollWALWriter(null, request);
2631 } catch (ServiceException se) {
2632 throw ProtobufUtil.getRemoteException(se);
2633 }
2634 }
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658 @Deprecated
2659 public synchronized byte[][] rollHLogWriter(String serverName)
2660 throws IOException, FailedLogCloseException {
2661 ServerName sn = ServerName.valueOf(serverName);
2662 final RollWALWriterResponse response = rollWALWriterImpl(sn);
2663 int regionCount = response.getRegionToFlushCount();
2664 if (0 == regionCount) {
2665 return null;
2666 }
2667 byte[][] regionsToFlush = new byte[regionCount][];
2668 for (int i = 0; i < regionCount; i++) {
2669 ByteString region = response.getRegionToFlush(i);
2670 regionsToFlush[i] = region.toByteArray();
2671 }
2672 return regionsToFlush;
2673 }
2674
2675 @Override
2676 public synchronized void rollWALWriter(ServerName serverName)
2677 throws IOException, FailedLogCloseException {
2678 rollWALWriterImpl(serverName);
2679 }
2680
2681 @Override
2682 public String[] getMasterCoprocessors() {
2683 try {
2684 return getClusterStatus().getMasterCoprocessors();
2685 } catch (IOException e) {
2686 LOG.error("Could not getClusterStatus()",e);
2687 return null;
2688 }
2689 }
2690
2691
2692
2693
2694 @Override
2695 public CompactionState getCompactionState(final TableName tableName)
2696 throws IOException {
2697 CompactionState state = CompactionState.NONE;
2698 ZooKeeperWatcher zookeeper =
2699 new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
2700 new ThrowableAbortable());
2701 try {
2702 checkTableExists(tableName);
2703 List<Pair<HRegionInfo, ServerName>> pairs =
2704 MetaTableAccessor.getTableRegionsAndLocations(zookeeper, connection, tableName);
2705 for (Pair<HRegionInfo, ServerName> pair: pairs) {
2706 if (pair.getFirst().isOffline()) continue;
2707 if (pair.getSecond() == null) continue;
2708 try {
2709 ServerName sn = pair.getSecond();
2710 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
2711 GetRegionInfoRequest request = RequestConverter.buildGetRegionInfoRequest(
2712 pair.getFirst().getRegionName(), true);
2713 GetRegionInfoResponse response = admin.getRegionInfo(null, request);
2714 switch (response.getCompactionState()) {
2715 case MAJOR_AND_MINOR:
2716 return CompactionState.MAJOR_AND_MINOR;
2717 case MAJOR:
2718 if (state == CompactionState.MINOR) {
2719 return CompactionState.MAJOR_AND_MINOR;
2720 }
2721 state = CompactionState.MAJOR;
2722 break;
2723 case MINOR:
2724 if (state == CompactionState.MAJOR) {
2725 return CompactionState.MAJOR_AND_MINOR;
2726 }
2727 state = CompactionState.MINOR;
2728 break;
2729 case NONE:
2730 default:
2731 }
2732 } catch (NotServingRegionException e) {
2733 if (LOG.isDebugEnabled()) {
2734 LOG.debug("Trying to get compaction state of " +
2735 pair.getFirst() + ": " +
2736 StringUtils.stringifyException(e));
2737 }
2738 } catch (RemoteException e) {
2739 if (e.getMessage().indexOf(NotServingRegionException.class.getName()) >= 0) {
2740 if (LOG.isDebugEnabled()) {
2741 LOG.debug("Trying to get compaction state of " + pair.getFirst() + ": "
2742 + StringUtils.stringifyException(e));
2743 }
2744 } else {
2745 throw e;
2746 }
2747 }
2748 }
2749 } catch (ServiceException se) {
2750 throw ProtobufUtil.getRemoteException(se);
2751 } finally {
2752 zookeeper.close();
2753 }
2754 return state;
2755 }
2756
2757
2758
2759
2760 @Override
2761 public CompactionState getCompactionStateForRegion(final byte[] regionName)
2762 throws IOException {
2763 try {
2764 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
2765 if (regionServerPair == null) {
2766 throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName));
2767 }
2768 if (regionServerPair.getSecond() == null) {
2769 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
2770 }
2771 ServerName sn = regionServerPair.getSecond();
2772 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
2773 GetRegionInfoRequest request = RequestConverter.buildGetRegionInfoRequest(
2774 regionServerPair.getFirst().getRegionName(), true);
2775 GetRegionInfoResponse response = admin.getRegionInfo(null, request);
2776 return response.getCompactionState();
2777 } catch (ServiceException se) {
2778 throw ProtobufUtil.getRemoteException(se);
2779 }
2780 }
2781
2782
2783
2784
2785
2786 @Deprecated
2787 public CompactionState getCompactionState(final String tableNameOrRegionName)
2788 throws IOException, InterruptedException {
2789 return getCompactionState(Bytes.toBytes(tableNameOrRegionName));
2790 }
2791
2792
2793
2794
2795
2796 @Deprecated
2797 public CompactionState getCompactionState(final byte[] tableNameOrRegionName)
2798 throws IOException, InterruptedException {
2799 try {
2800 return getCompactionStateForRegion(tableNameOrRegionName);
2801 } catch (IllegalArgumentException e) {
2802
2803 return getCompactionState(TableName.valueOf(tableNameOrRegionName));
2804 }
2805 }
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823 @Override
2824 public void snapshot(final String snapshotName,
2825 final TableName tableName) throws IOException,
2826 SnapshotCreationException, IllegalArgumentException {
2827 snapshot(snapshotName, tableName, SnapshotDescription.Type.FLUSH);
2828 }
2829
2830 public void snapshot(final String snapshotName,
2831 final String tableName) throws IOException,
2832 SnapshotCreationException, IllegalArgumentException {
2833 snapshot(snapshotName, TableName.valueOf(tableName),
2834 SnapshotDescription.Type.FLUSH);
2835 }
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852 public void snapshot(final byte[] snapshotName, final byte[] tableName,
2853 final SnapshotDescription.Type flushType) throws
2854 IOException, SnapshotCreationException, IllegalArgumentException {
2855 snapshot(Bytes.toString(snapshotName), Bytes.toString(tableName), flushType);
2856 }
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873 @Override
2874 public void snapshot(final byte[] snapshotName,
2875 final TableName tableName) throws IOException,
2876 SnapshotCreationException, IllegalArgumentException {
2877 snapshot(Bytes.toString(snapshotName), tableName, SnapshotDescription.Type.FLUSH);
2878 }
2879
2880 public void snapshot(final byte[] snapshotName,
2881 final byte[] tableName) throws IOException,
2882 SnapshotCreationException, IllegalArgumentException {
2883 snapshot(Bytes.toString(snapshotName), TableName.valueOf(tableName),
2884 SnapshotDescription.Type.FLUSH);
2885 }
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905 @Override
2906 public void snapshot(final String snapshotName,
2907 final TableName tableName,
2908 SnapshotDescription.Type type) throws IOException, SnapshotCreationException,
2909 IllegalArgumentException {
2910 SnapshotDescription.Builder builder = SnapshotDescription.newBuilder();
2911 builder.setTable(tableName.getNameAsString());
2912 builder.setName(snapshotName);
2913 builder.setType(type);
2914 snapshot(builder.build());
2915 }
2916
2917 public void snapshot(final String snapshotName,
2918 final String tableName,
2919 SnapshotDescription.Type type) throws IOException, SnapshotCreationException,
2920 IllegalArgumentException {
2921 snapshot(snapshotName, TableName.valueOf(tableName), type);
2922 }
2923
2924 public void snapshot(final String snapshotName,
2925 final byte[] tableName,
2926 SnapshotDescription.Type type) throws IOException, SnapshotCreationException,
2927 IllegalArgumentException {
2928 snapshot(snapshotName, TableName.valueOf(tableName), type);
2929 }
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952 @Override
2953 public void snapshot(SnapshotDescription snapshot) throws IOException, SnapshotCreationException,
2954 IllegalArgumentException {
2955
2956 SnapshotResponse response = takeSnapshotAsync(snapshot);
2957 final IsSnapshotDoneRequest request = IsSnapshotDoneRequest.newBuilder().setSnapshot(snapshot)
2958 .build();
2959 IsSnapshotDoneResponse done = null;
2960 long start = EnvironmentEdgeManager.currentTime();
2961 long max = response.getExpectedTimeout();
2962 long maxPauseTime = max / this.numRetries;
2963 int tries = 0;
2964 LOG.debug("Waiting a max of " + max + " ms for snapshot '" +
2965 ClientSnapshotDescriptionUtils.toString(snapshot) + "'' to complete. (max " +
2966 maxPauseTime + " ms per retry)");
2967 while (tries == 0
2968 || ((EnvironmentEdgeManager.currentTime() - start) < max && !done.getDone())) {
2969 try {
2970
2971 long sleep = getPauseTime(tries++);
2972 sleep = sleep > maxPauseTime ? maxPauseTime : sleep;
2973 LOG.debug("(#" + tries + ") Sleeping: " + sleep +
2974 "ms while waiting for snapshot completion.");
2975 Thread.sleep(sleep);
2976 } catch (InterruptedException e) {
2977 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
2978 }
2979 LOG.debug("Getting current status of snapshot from master...");
2980 done = executeCallable(new MasterCallable<IsSnapshotDoneResponse>(getConnection()) {
2981 @Override
2982 public IsSnapshotDoneResponse call(int callTimeout) throws ServiceException {
2983 return master.isSnapshotDone(null, request);
2984 }
2985 });
2986 }
2987 if (!done.getDone()) {
2988 throw new SnapshotCreationException("Snapshot '" + snapshot.getName()
2989 + "' wasn't completed in expectedTime:" + max + " ms", snapshot);
2990 }
2991 }
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003 @Override
3004 public SnapshotResponse takeSnapshotAsync(SnapshotDescription snapshot) throws IOException,
3005 SnapshotCreationException {
3006 ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot);
3007 final SnapshotRequest request = SnapshotRequest.newBuilder().setSnapshot(snapshot)
3008 .build();
3009
3010 return executeCallable(new MasterCallable<SnapshotResponse>(getConnection()) {
3011 @Override
3012 public SnapshotResponse call(int callTimeout) throws ServiceException {
3013 return master.snapshot(null, request);
3014 }
3015 });
3016 }
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038 @Override
3039 public boolean isSnapshotFinished(final SnapshotDescription snapshot)
3040 throws IOException, HBaseSnapshotException, UnknownSnapshotException {
3041
3042 return executeCallable(new MasterCallable<IsSnapshotDoneResponse>(getConnection()) {
3043 @Override
3044 public IsSnapshotDoneResponse call(int callTimeout) throws ServiceException {
3045 return master.isSnapshotDone(null,
3046 IsSnapshotDoneRequest.newBuilder().setSnapshot(snapshot).build());
3047 }
3048 }).getDone();
3049 }
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064 @Override
3065 public void restoreSnapshot(final byte[] snapshotName)
3066 throws IOException, RestoreSnapshotException {
3067 restoreSnapshot(Bytes.toString(snapshotName));
3068 }
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083 @Override
3084 public void restoreSnapshot(final String snapshotName)
3085 throws IOException, RestoreSnapshotException {
3086 boolean takeFailSafeSnapshot =
3087 conf.getBoolean("hbase.snapshot.restore.take.failsafe.snapshot", false);
3088 restoreSnapshot(snapshotName, takeFailSafeSnapshot);
3089 }
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107 @Override
3108 public void restoreSnapshot(final byte[] snapshotName, final boolean takeFailSafeSnapshot)
3109 throws IOException, RestoreSnapshotException {
3110 restoreSnapshot(Bytes.toString(snapshotName), takeFailSafeSnapshot);
3111 }
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129 @Override
3130 public void restoreSnapshot(final String snapshotName, boolean takeFailSafeSnapshot)
3131 throws IOException, RestoreSnapshotException {
3132 TableName tableName = null;
3133 for (SnapshotDescription snapshotInfo: listSnapshots()) {
3134 if (snapshotInfo.getName().equals(snapshotName)) {
3135 tableName = TableName.valueOf(snapshotInfo.getTable());
3136 break;
3137 }
3138 }
3139
3140 if (tableName == null) {
3141 throw new RestoreSnapshotException(
3142 "Unable to find the table name for snapshot=" + snapshotName);
3143 }
3144
3145
3146 if (!tableExists(tableName)) {
3147 cloneSnapshot(snapshotName, tableName);
3148 return;
3149 }
3150
3151
3152 if (!isTableDisabled(tableName)) {
3153 throw new TableNotDisabledException(tableName);
3154 }
3155
3156
3157 String failSafeSnapshotSnapshotName = null;
3158 if (takeFailSafeSnapshot) {
3159 failSafeSnapshotSnapshotName = conf.get("hbase.snapshot.restore.failsafe.name",
3160 "hbase-failsafe-{snapshot.name}-{restore.timestamp}");
3161 failSafeSnapshotSnapshotName = failSafeSnapshotSnapshotName
3162 .replace("{snapshot.name}", snapshotName)
3163 .replace("{table.name}", tableName.toString().replace(TableName.NAMESPACE_DELIM, '.'))
3164 .replace("{restore.timestamp}", String.valueOf(EnvironmentEdgeManager.currentTime()));
3165 LOG.info("Taking restore-failsafe snapshot: " + failSafeSnapshotSnapshotName);
3166 snapshot(failSafeSnapshotSnapshotName, tableName);
3167 }
3168
3169 try {
3170
3171 internalRestoreSnapshot(snapshotName, tableName);
3172 } catch (IOException e) {
3173
3174
3175 if (takeFailSafeSnapshot) {
3176 try {
3177 internalRestoreSnapshot(failSafeSnapshotSnapshotName, tableName);
3178 String msg = "Restore snapshot=" + snapshotName +
3179 " failed. Rollback to snapshot=" + failSafeSnapshotSnapshotName + " succeeded.";
3180 LOG.error(msg, e);
3181 throw new RestoreSnapshotException(msg, e);
3182 } catch (IOException ex) {
3183 String msg = "Failed to restore and rollback to snapshot=" + failSafeSnapshotSnapshotName;
3184 LOG.error(msg, ex);
3185 throw new RestoreSnapshotException(msg, e);
3186 }
3187 } else {
3188 throw new RestoreSnapshotException("Failed to restore snapshot=" + snapshotName, e);
3189 }
3190 }
3191
3192
3193 if (takeFailSafeSnapshot) {
3194 try {
3195 LOG.info("Deleting restore-failsafe snapshot: " + failSafeSnapshotSnapshotName);
3196 deleteSnapshot(failSafeSnapshotSnapshotName);
3197 } catch (IOException e) {
3198 LOG.error("Unable to remove the failsafe snapshot: " + failSafeSnapshotSnapshotName, e);
3199 }
3200 }
3201 }
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213 public void cloneSnapshot(final byte[] snapshotName, final byte[] tableName)
3214 throws IOException, TableExistsException, RestoreSnapshotException {
3215 cloneSnapshot(Bytes.toString(snapshotName), TableName.valueOf(tableName));
3216 }
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228 @Override
3229 public void cloneSnapshot(final byte[] snapshotName, final TableName tableName)
3230 throws IOException, TableExistsException, RestoreSnapshotException {
3231 cloneSnapshot(Bytes.toString(snapshotName), tableName);
3232 }
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246 public void cloneSnapshot(final String snapshotName, final String tableName)
3247 throws IOException, TableExistsException, RestoreSnapshotException, InterruptedException {
3248 cloneSnapshot(snapshotName, TableName.valueOf(tableName));
3249 }
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261 @Override
3262 public void cloneSnapshot(final String snapshotName, final TableName tableName)
3263 throws IOException, TableExistsException, RestoreSnapshotException {
3264 if (tableExists(tableName)) {
3265 throw new TableExistsException(tableName);
3266 }
3267 internalRestoreSnapshot(snapshotName, tableName);
3268 waitUntilTableIsEnabled(tableName);
3269 }
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282 @Override
3283 public byte[] execProcedureWithRet(String signature, String instance,
3284 Map<String, String> props) throws IOException {
3285 ProcedureDescription.Builder builder = ProcedureDescription.newBuilder();
3286 builder.setSignature(signature).setInstance(instance);
3287 for (Entry<String, String> entry : props.entrySet()) {
3288 NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey())
3289 .setValue(entry.getValue()).build();
3290 builder.addConfiguration(pair);
3291 }
3292
3293 final ExecProcedureRequest request = ExecProcedureRequest.newBuilder()
3294 .setProcedure(builder.build()).build();
3295
3296 ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>(
3297 getConnection()) {
3298 @Override
3299 public ExecProcedureResponse call(int callTimeout) throws ServiceException {
3300 return master.execProcedureWithRet(null, request);
3301 }
3302 });
3303
3304 return response.hasReturnData() ? response.getReturnData().toByteArray() : null;
3305 }
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316 @Override
3317 public void execProcedure(String signature, String instance,
3318 Map<String, String> props) throws IOException {
3319 ProcedureDescription.Builder builder = ProcedureDescription.newBuilder();
3320 builder.setSignature(signature).setInstance(instance);
3321 for (Entry<String, String> entry : props.entrySet()) {
3322 NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey())
3323 .setValue(entry.getValue()).build();
3324 builder.addConfiguration(pair);
3325 }
3326
3327 final ExecProcedureRequest request = ExecProcedureRequest.newBuilder()
3328 .setProcedure(builder.build()).build();
3329
3330 ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>(
3331 getConnection()) {
3332 @Override
3333 public ExecProcedureResponse call(int callTimeout) throws ServiceException {
3334 return master.execProcedure(null, request);
3335 }
3336 });
3337
3338 long start = EnvironmentEdgeManager.currentTime();
3339 long max = response.getExpectedTimeout();
3340 long maxPauseTime = max / this.numRetries;
3341 int tries = 0;
3342 LOG.debug("Waiting a max of " + max + " ms for procedure '" +
3343 signature + " : " + instance + "'' to complete. (max " + maxPauseTime + " ms per retry)");
3344 boolean done = false;
3345 while (tries == 0
3346 || ((EnvironmentEdgeManager.currentTime() - start) < max && !done)) {
3347 try {
3348
3349 long sleep = getPauseTime(tries++);
3350 sleep = sleep > maxPauseTime ? maxPauseTime : sleep;
3351 LOG.debug("(#" + tries + ") Sleeping: " + sleep +
3352 "ms while waiting for procedure completion.");
3353 Thread.sleep(sleep);
3354 } catch (InterruptedException e) {
3355 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
3356 }
3357 LOG.debug("Getting current status of procedure from master...");
3358 done = isProcedureFinished(signature, instance, props);
3359 }
3360 if (!done) {
3361 throw new IOException("Procedure '" + signature + " : " + instance
3362 + "' wasn't completed in expectedTime:" + max + " ms");
3363 }
3364 }
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383 @Override
3384 public boolean isProcedureFinished(String signature, String instance, Map<String, String> props)
3385 throws IOException {
3386 final ProcedureDescription.Builder builder = ProcedureDescription.newBuilder();
3387 builder.setSignature(signature).setInstance(instance);
3388 for (Entry<String, String> entry : props.entrySet()) {
3389 NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey())
3390 .setValue(entry.getValue()).build();
3391 builder.addConfiguration(pair);
3392 }
3393 final ProcedureDescription desc = builder.build();
3394 return executeCallable(
3395 new MasterCallable<IsProcedureDoneResponse>(getConnection()) {
3396 @Override
3397 public IsProcedureDoneResponse call(int callTimeout) throws ServiceException {
3398 return master.isProcedureDone(null, IsProcedureDoneRequest
3399 .newBuilder().setProcedure(desc).build());
3400 }
3401 }).getDone();
3402 }
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414 private void internalRestoreSnapshot(final String snapshotName, final TableName
3415 tableName)
3416 throws IOException, RestoreSnapshotException {
3417 SnapshotDescription snapshot = SnapshotDescription.newBuilder()
3418 .setName(snapshotName).setTable(tableName.getNameAsString()).build();
3419
3420
3421 internalRestoreSnapshotAsync(snapshot);
3422
3423 final IsRestoreSnapshotDoneRequest request = IsRestoreSnapshotDoneRequest.newBuilder()
3424 .setSnapshot(snapshot).build();
3425 IsRestoreSnapshotDoneResponse done = IsRestoreSnapshotDoneResponse.newBuilder()
3426 .setDone(false).buildPartial();
3427 final long maxPauseTime = 5000;
3428 int tries = 0;
3429 while (!done.getDone()) {
3430 try {
3431
3432 long sleep = getPauseTime(tries++);
3433 sleep = sleep > maxPauseTime ? maxPauseTime : sleep;
3434 LOG.debug(tries + ") Sleeping: " + sleep + " ms while we wait for snapshot restore to complete.");
3435 Thread.sleep(sleep);
3436 } catch (InterruptedException e) {
3437 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
3438 }
3439 LOG.debug("Getting current status of snapshot restore from master...");
3440 done = executeCallable(new MasterCallable<IsRestoreSnapshotDoneResponse>(
3441 getConnection()) {
3442 @Override
3443 public IsRestoreSnapshotDoneResponse call(int callTimeout) throws ServiceException {
3444 return master.isRestoreSnapshotDone(null, request);
3445 }
3446 });
3447 }
3448 if (!done.getDone()) {
3449 throw new RestoreSnapshotException("Snapshot '" + snapshot.getName() + "' wasn't restored.");
3450 }
3451 }
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463 private RestoreSnapshotResponse internalRestoreSnapshotAsync(final SnapshotDescription snapshot)
3464 throws IOException, RestoreSnapshotException {
3465 ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot);
3466
3467 final RestoreSnapshotRequest request = RestoreSnapshotRequest.newBuilder().setSnapshot(snapshot)
3468 .build();
3469
3470
3471 return executeCallable(new MasterCallable<RestoreSnapshotResponse>(getConnection()) {
3472 @Override
3473 public RestoreSnapshotResponse call(int callTimeout) throws ServiceException {
3474 return master.restoreSnapshot(null, request);
3475 }
3476 });
3477 }
3478
3479
3480
3481
3482
3483
3484 @Override
3485 public List<SnapshotDescription> listSnapshots() throws IOException {
3486 return executeCallable(new MasterCallable<List<SnapshotDescription>>(getConnection()) {
3487 @Override
3488 public List<SnapshotDescription> call(int callTimeout) throws ServiceException {
3489 return master.getCompletedSnapshots(null, GetCompletedSnapshotsRequest.newBuilder().build())
3490 .getSnapshotsList();
3491 }
3492 });
3493 }
3494
3495
3496
3497
3498
3499
3500
3501
3502 @Override
3503 public List<SnapshotDescription> listSnapshots(String regex) throws IOException {
3504 return listSnapshots(Pattern.compile(regex));
3505 }
3506
3507
3508
3509
3510
3511
3512
3513
3514 @Override
3515 public List<SnapshotDescription> listSnapshots(Pattern pattern) throws IOException {
3516 List<SnapshotDescription> matched = new LinkedList<SnapshotDescription>();
3517 List<SnapshotDescription> snapshots = listSnapshots();
3518 for (SnapshotDescription snapshot : snapshots) {
3519 if (pattern.matcher(snapshot.getName()).matches()) {
3520 matched.add(snapshot);
3521 }
3522 }
3523 return matched;
3524 }
3525
3526
3527
3528
3529
3530
3531 @Override
3532 public void deleteSnapshot(final byte[] snapshotName) throws IOException {
3533 deleteSnapshot(Bytes.toString(snapshotName));
3534 }
3535
3536
3537
3538
3539
3540
3541 @Override
3542 public void deleteSnapshot(final String snapshotName) throws IOException {
3543
3544 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(snapshotName));
3545
3546 executeCallable(new MasterCallable<Void>(getConnection()) {
3547 @Override
3548 public Void call(int callTimeout) throws ServiceException {
3549 master.deleteSnapshot(null,
3550 DeleteSnapshotRequest.newBuilder().
3551 setSnapshot(SnapshotDescription.newBuilder().setName(snapshotName).build()).build()
3552 );
3553 return null;
3554 }
3555 });
3556 }
3557
3558
3559
3560
3561
3562
3563 @Override
3564 public void deleteSnapshots(final String regex) throws IOException {
3565 deleteSnapshots(Pattern.compile(regex));
3566 }
3567
3568
3569
3570
3571
3572
3573 @Override
3574 public void deleteSnapshots(final Pattern pattern) throws IOException {
3575 List<SnapshotDescription> snapshots = listSnapshots(pattern);
3576 for (final SnapshotDescription snapshot : snapshots) {
3577 try {
3578 internalDeleteSnapshot(snapshot);
3579 } catch (IOException ex) {
3580 LOG.info(
3581 "Failed to delete snapshot " + snapshot.getName() + " for table " + snapshot.getTable(),
3582 ex);
3583 }
3584 }
3585 }
3586
3587 private void internalDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
3588 executeCallable(new MasterCallable<Void>(getConnection()) {
3589 @Override
3590 public Void call(int callTimeout) throws ServiceException {
3591 this.master.deleteSnapshot(null, DeleteSnapshotRequest.newBuilder().setSnapshot(snapshot)
3592 .build());
3593 return null;
3594 }
3595 });
3596 }
3597
3598 private <V> V executeCallable(MasterCallable<V> callable) throws IOException {
3599 RpcRetryingCaller<V> caller = rpcCallerFactory.newCaller();
3600 try {
3601 return caller.callWithRetries(callable, operationTimeout);
3602 } finally {
3603 callable.close();
3604 }
3605 }
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628 @Override
3629 public CoprocessorRpcChannel coprocessorService() {
3630 return new MasterCoprocessorRpcChannel(connection);
3631 }
3632
3633
3634
3635
3636 private static class ThrowableAbortable implements Abortable {
3637
3638 @Override
3639 public void abort(String why, Throwable e) {
3640 throw new RuntimeException(why, e);
3641 }
3642
3643 @Override
3644 public boolean isAborted() {
3645 return true;
3646 }
3647 }
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671 @Override
3672 public CoprocessorRpcChannel coprocessorService(ServerName sn) {
3673 return new RegionServerCoprocessorRpcChannel(connection, sn);
3674 }
3675
3676 @Override
3677 public void updateConfiguration(ServerName server) throws IOException {
3678 try {
3679 this.connection.getAdmin(server).updateConfiguration(null,
3680 UpdateConfigurationRequest.getDefaultInstance());
3681 } catch (ServiceException e) {
3682 throw ProtobufUtil.getRemoteException(e);
3683 }
3684 }
3685
3686 @Override
3687 public void updateConfiguration() throws IOException {
3688 for (ServerName server : this.getClusterStatus().getServers()) {
3689 updateConfiguration(server);
3690 }
3691 }
3692
3693 @Override
3694 public int getMasterInfoPort() throws IOException {
3695
3696 ConnectionManager.HConnectionImplementation connection =
3697 (ConnectionManager.HConnectionImplementation)this.connection;
3698 ZooKeeperKeepAliveConnection zkw = connection.getKeepAliveZooKeeperWatcher();
3699 try {
3700 return MasterAddressTracker.getMasterInfoPort(zkw);
3701 } catch (KeeperException e) {
3702 throw new IOException("Failed to get master info port from MasterAddressTracker", e);
3703 }
3704 }
3705 }