use of org.apache.hadoop.hbase.snapshot.RestoreSnapshotException in project hbase by apache.
the class SnapshotManager method restoreSnapshot.
/**
* Restore the specified snapshot.
* The restore will fail if the destination table has a snapshot or restore in progress.
*
* @param snapshot Snapshot Descriptor
* @param hTableDescriptor Table Descriptor
* @param nonceKey unique identifier to prevent duplicated RPC
* @return procId the ID of the restore snapshot procedure
*/
private synchronized long restoreSnapshot(final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor, final NonceKey nonceKey) throws HBaseSnapshotException {
final TableName tableName = hTableDescriptor.getTableName();
// make sure we aren't running a snapshot on the same table
if (isTakingSnapshot(tableName)) {
throw new RestoreSnapshotException("Snapshot in progress on the restore table=" + tableName);
}
// make sure we aren't running a restore on the same table
if (isRestoringTable(tableName)) {
throw new RestoreSnapshotException("Restore already in progress on the table=" + tableName);
}
try {
long procId = master.getMasterProcedureExecutor().submitProcedure(new RestoreSnapshotProcedure(master.getMasterProcedureExecutor().getEnvironment(), hTableDescriptor, snapshot), nonceKey);
this.restoreTableToProcIdMap.put(tableName, procId);
return procId;
} catch (Exception e) {
String msg = "Couldn't restore the snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) + " on table=" + tableName;
LOG.error(msg, e);
throw new RestoreSnapshotException(msg, e);
}
}
use of org.apache.hadoop.hbase.snapshot.RestoreSnapshotException in project hbase by apache.
the class HBaseAdmin method internalRestoreSnapshotAsync.
/**
* Execute Restore/Clone snapshot and wait for the server to complete (blocking).
* To check if the cloned table exists, use {@link #isTableAvailable} -- it is not safe to
* create an HTable instance to this table before it is available.
* @param snapshotName snapshot to restore
* @param tableName table name to restore the snapshot on
* @throws IOException if a remote or network exception occurs
* @throws RestoreSnapshotException if snapshot failed to be restored
* @throws IllegalArgumentException if the restore request is formatted incorrectly
*/
private Future<Void> internalRestoreSnapshotAsync(final String snapshotName, final TableName tableName) throws IOException, RestoreSnapshotException {
final HBaseProtos.SnapshotDescription snapshot = HBaseProtos.SnapshotDescription.newBuilder().setName(snapshotName).setTable(tableName.getNameAsString()).build();
// actually restore the snapshot
ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot);
RestoreSnapshotResponse response = executeCallable(new MasterCallable<RestoreSnapshotResponse>(getConnection(), getRpcControllerFactory()) {
@Override
protected RestoreSnapshotResponse rpcCall() throws Exception {
final RestoreSnapshotRequest request = RestoreSnapshotRequest.newBuilder().setSnapshot(snapshot).setNonceGroup(ng.getNonceGroup()).setNonce(ng.newNonce()).build();
return master.restoreSnapshot(getRpcController(), request);
}
});
return new RestoreSnapshotFuture(this, snapshot, tableName, response);
}
use of org.apache.hadoop.hbase.snapshot.RestoreSnapshotException in project hbase by apache.
the class HBaseAdmin method restoreSnapshot.
@Override
public void restoreSnapshot(final String snapshotName, final boolean takeFailSafeSnapshot) throws IOException, RestoreSnapshotException {
TableName tableName = getTableNameBeforeRestoreSnapshot(snapshotName);
// The table does not exists, switch to clone.
if (!tableExists(tableName)) {
cloneSnapshot(snapshotName, tableName);
return;
}
// Check if the table is disabled
if (!isTableDisabled(tableName)) {
throw new TableNotDisabledException(tableName);
}
// Take a snapshot of the current state
String failSafeSnapshotSnapshotName = null;
if (takeFailSafeSnapshot) {
failSafeSnapshotSnapshotName = conf.get("hbase.snapshot.restore.failsafe.name", "hbase-failsafe-{snapshot.name}-{restore.timestamp}");
failSafeSnapshotSnapshotName = failSafeSnapshotSnapshotName.replace("{snapshot.name}", snapshotName).replace("{table.name}", tableName.toString().replace(TableName.NAMESPACE_DELIM, '.')).replace("{restore.timestamp}", String.valueOf(EnvironmentEdgeManager.currentTime()));
LOG.info("Taking restore-failsafe snapshot: " + failSafeSnapshotSnapshotName);
snapshot(failSafeSnapshotSnapshotName, tableName);
}
try {
// Restore snapshot
get(internalRestoreSnapshotAsync(snapshotName, tableName), syncWaitTimeout, TimeUnit.MILLISECONDS);
} catch (IOException e) {
// if the pre-restore snapshot is available try to rollback
if (takeFailSafeSnapshot) {
try {
get(internalRestoreSnapshotAsync(failSafeSnapshotSnapshotName, tableName), syncWaitTimeout, TimeUnit.MILLISECONDS);
String msg = "Restore snapshot=" + snapshotName + " failed. Rollback to snapshot=" + failSafeSnapshotSnapshotName + " succeeded.";
LOG.error(msg, e);
throw new RestoreSnapshotException(msg, e);
} catch (IOException ex) {
String msg = "Failed to restore and rollback to snapshot=" + failSafeSnapshotSnapshotName;
LOG.error(msg, ex);
throw new RestoreSnapshotException(msg, e);
}
} else {
throw new RestoreSnapshotException("Failed to restore snapshot=" + snapshotName, e);
}
}
// If the restore is succeeded, delete the pre-restore snapshot
if (takeFailSafeSnapshot) {
try {
LOG.info("Deleting restore-failsafe snapshot: " + failSafeSnapshotSnapshotName);
deleteSnapshot(failSafeSnapshotSnapshotName);
} catch (IOException e) {
LOG.error("Unable to remove the failsafe snapshot: " + failSafeSnapshotSnapshotName, e);
}
}
}
use of org.apache.hadoop.hbase.snapshot.RestoreSnapshotException in project hbase by apache.
the class CloneSnapshotProcedure method createFilesystemLayout.
/**
* Create regions in file system.
* @param env MasterProcedureEnv
* @throws IOException
*/
private List<RegionInfo> createFilesystemLayout(final MasterProcedureEnv env, final TableDescriptor tableDescriptor, final List<RegionInfo> newRegions) throws IOException {
return createFsLayout(env, tableDescriptor, newRegions, new CreateHdfsRegions() {
@Override
public List<RegionInfo> createHdfsRegions(final MasterProcedureEnv env, final Path tableRootDir, final TableName tableName, final List<RegionInfo> newRegions) throws IOException {
final MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem();
final FileSystem fs = mfs.getFileSystem();
final Path rootDir = mfs.getRootDir();
final Configuration conf = env.getMasterConfiguration();
final ForeignExceptionDispatcher monitorException = new ForeignExceptionDispatcher();
getMonitorStatus().setStatus("Clone snapshot - creating regions for table: " + tableName);
try {
// 1. Execute the on-disk Clone
Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshot, rootDir);
SnapshotManifest manifest = SnapshotManifest.open(conf, fs, snapshotDir, snapshot);
RestoreSnapshotHelper restoreHelper = new RestoreSnapshotHelper(conf, fs, manifest, tableDescriptor, tableRootDir, monitorException, monitorStatus);
RestoreSnapshotHelper.RestoreMetaChanges metaChanges = restoreHelper.restoreHdfsRegions();
// Clone operation should not have stuff to restore or remove
Preconditions.checkArgument(!metaChanges.hasRegionsToRestore(), "A clone should not have regions to restore");
Preconditions.checkArgument(!metaChanges.hasRegionsToRemove(), "A clone should not have regions to remove");
// At this point the clone is complete. Next step is enabling the table.
String msg = "Clone snapshot=" + snapshot.getName() + " on table=" + tableName + " completed!";
LOG.info(msg);
monitorStatus.setStatus(msg + " Waiting for table to be enabled...");
// 2. Let the next step to add the regions to meta
return metaChanges.getRegionsToAdd();
} catch (Exception e) {
String msg = "clone snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) + " failed because " + e.getMessage();
LOG.error(msg, e);
IOException rse = new RestoreSnapshotException(msg, e, ProtobufUtil.createSnapshotDesc(snapshot));
// these handlers aren't futures so we need to register the error here.
monitorException.receive(new ForeignException("Master CloneSnapshotProcedure", rse));
throw rse;
}
}
});
}
use of org.apache.hadoop.hbase.snapshot.RestoreSnapshotException in project hbase by apache.
the class RawAsyncHBaseAdmin method restoreSnapshot.
@Override
public CompletableFuture<Void> restoreSnapshot(String snapshotName, boolean takeFailSafeSnapshot, boolean restoreAcl) {
CompletableFuture<Void> future = new CompletableFuture<>();
addListener(listSnapshots(Pattern.compile(snapshotName)), (snapshotDescriptions, err) -> {
if (err != null) {
future.completeExceptionally(err);
return;
}
TableName tableName = null;
if (snapshotDescriptions != null && !snapshotDescriptions.isEmpty()) {
for (SnapshotDescription snap : snapshotDescriptions) {
if (snap.getName().equals(snapshotName)) {
tableName = snap.getTableName();
break;
}
}
}
if (tableName == null) {
future.completeExceptionally(new RestoreSnapshotException("Unable to find the table name for snapshot=" + snapshotName));
return;
}
final TableName finalTableName = tableName;
addListener(tableExists(finalTableName), (exists, err2) -> {
if (err2 != null) {
future.completeExceptionally(err2);
} else if (!exists) {
// if table does not exist, then just clone snapshot into new table.
completeConditionalOnFuture(future, internalRestoreSnapshot(snapshotName, finalTableName, restoreAcl, null));
} else {
addListener(isTableDisabled(finalTableName), (disabled, err4) -> {
if (err4 != null) {
future.completeExceptionally(err4);
} else if (!disabled) {
future.completeExceptionally(new TableNotDisabledException(finalTableName));
} else {
completeConditionalOnFuture(future, restoreSnapshot(snapshotName, finalTableName, takeFailSafeSnapshot, restoreAcl));
}
});
}
});
});
return future;
}
Aggregations