/** * Apply changes to hbase:meta * @param env MasterProcedureEnv * @throws IOException **/ private void updateMETA(final MasterProcedureEnv env) throws IOException { try { Connection conn = env.getMasterServices().getConnection(); // 1. Prepare to restore getMonitorStatus().setStatus("Preparing to restore each region"); // 2. Applies changes to hbase:meta // (2.1). Removes the current set of regions from META // // By removing also the regions to restore (the ones present both in the snapshot // and in the current state) we ensure that no extra fields are present in META // e.g. with a simple add addRegionToMeta() the splitA and splitB attributes // not overwritten/removed, so you end up with old informations // that are not correct after the restore. if (regionsToRemove != null) { MetaTableAccessor.deleteRegions(conn, regionsToRemove); } // (2.2). Add the new set of regions to META // // At this point the old regions are no longer present in META. // and the set of regions present in the snapshot will be written to META. // All the information in hbase:meta are coming from the .regioninfo of each region present // in the snapshot folder. if (regionsToAdd != null) { MetaTableAccessor.addRegionsToMeta( conn, regionsToAdd, modifiedTableDescriptor.getRegionReplication()); } if (regionsToRestore != null) { MetaTableAccessor.overwriteRegions( conn, regionsToRestore, modifiedTableDescriptor.getRegionReplication()); } RestoreSnapshotHelper.RestoreMetaChanges metaChanges = new RestoreSnapshotHelper.RestoreMetaChanges( modifiedTableDescriptor, parentsToChildrenPairMap); metaChanges.updateMetaParentRegions(conn, regionsToAdd); // At this point the restore is complete. LOG.info("Restore snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) + " on table=" + getTableName() + " completed!"); } catch (IOException e) { final ForeignExceptionDispatcher monitorException = new ForeignExceptionDispatcher(); String msg = "restore snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) + " failed in meta update. Try re-running the restore command."; LOG.error(msg, e); monitorException.receive( new ForeignException(env.getMasterServices().getServerName().toString(), e)); throw new IOException(msg, e); } monitorStatus.markComplete("Restore snapshot '"+ snapshot.getName() +"'!"); MetricsSnapshot metricsSnapshot = new MetricsSnapshot(); metricsSnapshot.addSnapshotRestore( monitorStatus.getCompletionTimestamp() - monitorStatus.getStartTime()); }
@Override protected Flow executeFromState(final MasterProcedureEnv env, final CloneSnapshotState state) throws InterruptedException { if (isTraceEnabled()) { LOG.trace(this + " execute state=" + state); } try { switch (state) { case CLONE_SNAPSHOT_PRE_OPERATION: // Verify if we can clone the table prepareClone(env); preCloneSnapshot(env); setNextState(CloneSnapshotState.CLONE_SNAPSHOT_WRITE_FS_LAYOUT); break; case CLONE_SNAPSHOT_WRITE_FS_LAYOUT: newRegions = createFilesystemLayout(env, tableDescriptor, newRegions); setNextState(CloneSnapshotState.CLONE_SNAPSHOT_ADD_TO_META); break; case CLONE_SNAPSHOT_ADD_TO_META: addRegionsToMeta(env); setNextState(CloneSnapshotState.CLONE_SNAPSHOT_ASSIGN_REGIONS); break; case CLONE_SNAPSHOT_ASSIGN_REGIONS: CreateTableProcedure.setEnablingState(env, getTableName()); addChildProcedure(env.getAssignmentManager().createRoundRobinAssignProcedures(newRegions)); setNextState(CloneSnapshotState.CLONE_SNAPSHOT_UPDATE_DESC_CACHE); break; case CLONE_SNAPSHOT_UPDATE_DESC_CACHE: CreateTableProcedure.setEnabledState(env, getTableName()); CreateTableProcedure.updateTableDescCache(env, getTableName()); setNextState(CloneSnapshotState.CLONE_SNAPHOST_RESTORE_ACL); break; case CLONE_SNAPHOST_RESTORE_ACL: restoreSnapshotAcl(env); setNextState(CloneSnapshotState.CLONE_SNAPSHOT_POST_OPERATION); break; case CLONE_SNAPSHOT_POST_OPERATION: postCloneSnapshot(env); MetricsSnapshot metricsSnapshot = new MetricsSnapshot(); metricsSnapshot.addSnapshotClone( getMonitorStatus().getCompletionTimestamp() - getMonitorStatus().getStartTime()); getMonitorStatus().markComplete("Clone snapshot '"+ snapshot.getName() +"' completed!"); return Flow.NO_MORE_STATE; default: throw new UnsupportedOperationException("unhandled state=" + state); } } catch (IOException e) { if (isRollbackSupported(state)) { setFailure("master-clone-snapshot", e); } else { LOG.warn("Retriable error trying to clone snapshot=" + snapshot.getName() + " to table=" + getTableName() + " state=" + state, e); } } return Flow.HAS_MORE_STATE; }