001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master.procedure; 019 020import com.google.errorprone.annotations.RestrictedApi; 021import java.io.IOException; 022import java.util.ArrayList; 023import java.util.HashMap; 024import java.util.Iterator; 025import java.util.List; 026import java.util.Map; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.fs.FileSystem; 029import org.apache.hadoop.fs.Path; 030import org.apache.hadoop.hbase.DoNotRetryIOException; 031import org.apache.hadoop.hbase.HBaseIOException; 032import org.apache.hadoop.hbase.MetaTableAccessor; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.hadoop.hbase.TableNotFoundException; 035import org.apache.hadoop.hbase.client.Connection; 036import org.apache.hadoop.hbase.client.RegionInfo; 037import org.apache.hadoop.hbase.client.RegionReplicaUtil; 038import org.apache.hadoop.hbase.client.TableDescriptor; 039import org.apache.hadoop.hbase.errorhandling.ForeignException; 040import org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher; 041import org.apache.hadoop.hbase.favored.FavoredNodesManager; 042import org.apache.hadoop.hbase.fs.ErasureCodingUtils; 043import org.apache.hadoop.hbase.master.MasterFileSystem; 044import org.apache.hadoop.hbase.master.MetricsSnapshot; 045import org.apache.hadoop.hbase.master.RegionState; 046import org.apache.hadoop.hbase.master.assignment.AssignmentManager; 047import org.apache.hadoop.hbase.master.assignment.RegionStateStore; 048import org.apache.hadoop.hbase.monitoring.MonitoredTask; 049import org.apache.hadoop.hbase.monitoring.TaskMonitor; 050import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; 051import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils; 052import org.apache.hadoop.hbase.snapshot.RestoreSnapshotHelper; 053import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils; 054import org.apache.hadoop.hbase.snapshot.SnapshotManifest; 055import org.apache.hadoop.hbase.snapshot.SnapshotTTLExpiredException; 056import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 057import org.apache.hadoop.hbase.util.Pair; 058import org.apache.yetus.audience.InterfaceAudience; 059import org.slf4j.Logger; 060import org.slf4j.LoggerFactory; 061 062import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 063import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 064import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RestoreParentToChildRegionsPair; 065import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RestoreSnapshotState; 066import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RestoreSnapshotStateData; 067import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription; 068 069@InterfaceAudience.Private 070public class RestoreSnapshotProcedure 071 extends AbstractStateMachineTableProcedure<RestoreSnapshotState> { 072 private static final Logger LOG = LoggerFactory.getLogger(RestoreSnapshotProcedure.class); 073 074 private TableDescriptor oldTableDescriptor; 075 private TableDescriptor modifiedTableDescriptor; 076 private List<RegionInfo> regionsToRestore = null; 077 private List<RegionInfo> regionsToRemove = null; 078 private List<RegionInfo> regionsToAdd = null; 079 private Map<String, Pair<String, String>> parentsToChildrenPairMap = new HashMap<>(); 080 081 private SnapshotDescription snapshot; 082 private boolean restoreAcl; 083 084 // Monitor 085 private MonitoredTask monitorStatus = null; 086 087 /** 088 * Constructor (for failover) 089 */ 090 public RestoreSnapshotProcedure() { 091 } 092 093 public RestoreSnapshotProcedure(final MasterProcedureEnv env, 094 final TableDescriptor tableDescriptor, final SnapshotDescription snapshot) 095 throws HBaseIOException { 096 this(env, tableDescriptor, snapshot, false); 097 } 098 099 public RestoreSnapshotProcedure(final MasterProcedureEnv env, 100 final TableDescriptor tableDescriptor, final SnapshotDescription snapshot, 101 final boolean restoreAcl) throws HBaseIOException { 102 this(env, tableDescriptor, tableDescriptor, snapshot, restoreAcl); 103 } 104 105 /** 106 * Constructor 107 * @param env MasterProcedureEnv 108 * @param modifiedTableDescriptor the table to operate on 109 * @param snapshot snapshot to restore from 110 */ 111 public RestoreSnapshotProcedure(final MasterProcedureEnv env, 112 final TableDescriptor oldTableDescriptor, final TableDescriptor modifiedTableDescriptor, 113 final SnapshotDescription snapshot, final boolean restoreAcl) throws HBaseIOException { 114 super(env); 115 this.oldTableDescriptor = oldTableDescriptor; 116 // This is the new schema we are going to write out as this modification. 117 this.modifiedTableDescriptor = modifiedTableDescriptor; 118 preflightChecks(env, null/* Table can be online when restore is called? */); 119 // Snapshot information 120 this.snapshot = snapshot; 121 this.restoreAcl = restoreAcl; 122 123 // Monitor 124 getMonitorStatus(); 125 } 126 127 /** 128 * Set up monitor status if it is not created. 129 */ 130 private MonitoredTask getMonitorStatus() { 131 if (monitorStatus == null) { 132 monitorStatus = TaskMonitor.get().createStatus( 133 "Restoring snapshot '" + snapshot.getName() + "' to table " + getTableName()); 134 } 135 return monitorStatus; 136 } 137 138 @Override 139 protected Flow executeFromState(final MasterProcedureEnv env, final RestoreSnapshotState state) 140 throws InterruptedException { 141 LOG.trace("{} execute state={}", this, state); 142 143 // Make sure that the monitor status is set up 144 getMonitorStatus(); 145 146 try { 147 switch (state) { 148 case RESTORE_SNAPSHOT_PRE_OPERATION: 149 // Verify if we can restore the table 150 prepareRestore(env); 151 setNextState(RestoreSnapshotState.RESTORE_SNAPSHOT_UPDATE_TABLE_DESCRIPTOR); 152 break; 153 case RESTORE_SNAPSHOT_UPDATE_TABLE_DESCRIPTOR: 154 updateTableDescriptor(env); 155 // for restore, table dir already exists. sync EC if necessary before doing the real 156 // restore. this may be useful in certain restore scenarios where a user is explicitly 157 // trying to disable EC for some reason as part of the restore. 158 if (ErasureCodingUtils.needsSync(oldTableDescriptor, modifiedTableDescriptor)) { 159 setNextState(RestoreSnapshotState.RESTORE_SNAPSHOT_SYNC_ERASURE_CODING_POLICY); 160 } else { 161 setNextState(RestoreSnapshotState.RESTORE_SNAPSHOT_WRITE_FS_LAYOUT); 162 } 163 break; 164 case RESTORE_SNAPSHOT_SYNC_ERASURE_CODING_POLICY: 165 ErasureCodingUtils.sync(env.getMasterFileSystem().getFileSystem(), 166 env.getMasterFileSystem().getRootDir(), modifiedTableDescriptor); 167 setNextState(RestoreSnapshotState.RESTORE_SNAPSHOT_WRITE_FS_LAYOUT); 168 break; 169 case RESTORE_SNAPSHOT_WRITE_FS_LAYOUT: 170 restoreSnapshot(env); 171 setNextState(RestoreSnapshotState.RESTORE_SNAPSHOT_UPDATE_META); 172 break; 173 case RESTORE_SNAPSHOT_UPDATE_META: 174 updateMETA(env); 175 setNextState(RestoreSnapshotState.RESTORE_SNAPSHOT_RESTORE_ACL); 176 break; 177 case RESTORE_SNAPSHOT_RESTORE_ACL: 178 restoreSnapshotAcl(env); 179 return Flow.NO_MORE_STATE; 180 default: 181 throw new UnsupportedOperationException("unhandled state=" + state); 182 } 183 } catch (IOException e) { 184 if (isRollbackSupported(state)) { 185 setFailure("master-restore-snapshot", e); 186 } else { 187 LOG.warn("Retriable error trying to restore snapshot=" + snapshot.getName() + " to table=" 188 + getTableName() + " (in state=" + state + ")", e); 189 } 190 } 191 return Flow.HAS_MORE_STATE; 192 } 193 194 @Override 195 protected void rollbackState(final MasterProcedureEnv env, final RestoreSnapshotState state) 196 throws IOException { 197 if (state == RestoreSnapshotState.RESTORE_SNAPSHOT_PRE_OPERATION) { 198 // nothing to rollback 199 return; 200 } 201 202 // The restore snapshot doesn't have a rollback. The execution will succeed, at some point. 203 throw new UnsupportedOperationException("unhandled state=" + state); 204 } 205 206 @Override 207 protected boolean isRollbackSupported(final RestoreSnapshotState state) { 208 switch (state) { 209 case RESTORE_SNAPSHOT_PRE_OPERATION: 210 return true; 211 default: 212 return false; 213 } 214 } 215 216 @Override 217 protected RestoreSnapshotState getState(final int stateId) { 218 return RestoreSnapshotState.valueOf(stateId); 219 } 220 221 @Override 222 protected int getStateId(final RestoreSnapshotState state) { 223 return state.getNumber(); 224 } 225 226 @Override 227 protected RestoreSnapshotState getInitialState() { 228 return RestoreSnapshotState.RESTORE_SNAPSHOT_PRE_OPERATION; 229 } 230 231 @Override 232 public TableName getTableName() { 233 return modifiedTableDescriptor.getTableName(); 234 } 235 236 @Override 237 public TableOperationType getTableOperationType() { 238 return TableOperationType.EDIT; // Restore is modifying a table 239 } 240 241 @Override 242 public boolean abort(final MasterProcedureEnv env) { 243 // TODO: We may be able to abort if the procedure is not started yet. 244 return false; 245 } 246 247 @Override 248 public void toStringClassDetails(StringBuilder sb) { 249 sb.append(getClass().getSimpleName()); 250 sb.append(" (table="); 251 sb.append(getTableName()); 252 sb.append(" snapshot="); 253 sb.append(snapshot); 254 sb.append(")"); 255 } 256 257 @Override 258 protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException { 259 super.serializeStateData(serializer); 260 261 RestoreSnapshotStateData.Builder restoreSnapshotMsg = RestoreSnapshotStateData.newBuilder() 262 .setUserInfo(MasterProcedureUtil.toProtoUserInfo(getUser())).setSnapshot(this.snapshot) 263 .setModifiedTableSchema(ProtobufUtil.toTableSchema(modifiedTableDescriptor)) 264 .setOldTableSchema(ProtobufUtil.toTableSchema(oldTableDescriptor)); 265 266 if (regionsToRestore != null) { 267 for (RegionInfo hri : regionsToRestore) { 268 restoreSnapshotMsg.addRegionInfoForRestore(ProtobufUtil.toRegionInfo(hri)); 269 } 270 } 271 if (regionsToRemove != null) { 272 for (RegionInfo hri : regionsToRemove) { 273 restoreSnapshotMsg.addRegionInfoForRemove(ProtobufUtil.toRegionInfo(hri)); 274 } 275 } 276 if (regionsToAdd != null) { 277 for (RegionInfo hri : regionsToAdd) { 278 restoreSnapshotMsg.addRegionInfoForAdd(ProtobufUtil.toRegionInfo(hri)); 279 } 280 } 281 if (!parentsToChildrenPairMap.isEmpty()) { 282 final Iterator<Map.Entry<String, Pair<String, String>>> it = 283 parentsToChildrenPairMap.entrySet().iterator(); 284 while (it.hasNext()) { 285 final Map.Entry<String, Pair<String, String>> entry = it.next(); 286 287 RestoreParentToChildRegionsPair.Builder parentToChildrenPair = 288 RestoreParentToChildRegionsPair.newBuilder().setParentRegionName(entry.getKey()) 289 .setChild1RegionName(entry.getValue().getFirst()) 290 .setChild2RegionName(entry.getValue().getSecond()); 291 restoreSnapshotMsg.addParentToChildRegionsPairList(parentToChildrenPair); 292 } 293 } 294 restoreSnapshotMsg.setRestoreAcl(restoreAcl); 295 serializer.serialize(restoreSnapshotMsg.build()); 296 } 297 298 @Override 299 protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException { 300 super.deserializeStateData(serializer); 301 302 RestoreSnapshotStateData restoreSnapshotMsg = 303 serializer.deserialize(RestoreSnapshotStateData.class); 304 setUser(MasterProcedureUtil.toUserInfo(restoreSnapshotMsg.getUserInfo())); 305 snapshot = restoreSnapshotMsg.getSnapshot(); 306 oldTableDescriptor = ProtobufUtil.toTableDescriptor(restoreSnapshotMsg.getOldTableSchema()); 307 modifiedTableDescriptor = 308 ProtobufUtil.toTableDescriptor(restoreSnapshotMsg.getModifiedTableSchema()); 309 310 if (restoreSnapshotMsg.getRegionInfoForRestoreCount() == 0) { 311 regionsToRestore = null; 312 } else { 313 regionsToRestore = new ArrayList<>(restoreSnapshotMsg.getRegionInfoForRestoreCount()); 314 for (HBaseProtos.RegionInfo hri : restoreSnapshotMsg.getRegionInfoForRestoreList()) { 315 regionsToRestore.add(ProtobufUtil.toRegionInfo(hri)); 316 } 317 } 318 if (restoreSnapshotMsg.getRegionInfoForRemoveCount() == 0) { 319 regionsToRemove = null; 320 } else { 321 regionsToRemove = new ArrayList<>(restoreSnapshotMsg.getRegionInfoForRemoveCount()); 322 for (HBaseProtos.RegionInfo hri : restoreSnapshotMsg.getRegionInfoForRemoveList()) { 323 regionsToRemove.add(ProtobufUtil.toRegionInfo(hri)); 324 } 325 } 326 if (restoreSnapshotMsg.getRegionInfoForAddCount() == 0) { 327 regionsToAdd = null; 328 } else { 329 regionsToAdd = new ArrayList<>(restoreSnapshotMsg.getRegionInfoForAddCount()); 330 for (HBaseProtos.RegionInfo hri : restoreSnapshotMsg.getRegionInfoForAddList()) { 331 regionsToAdd.add(ProtobufUtil.toRegionInfo(hri)); 332 } 333 } 334 if (restoreSnapshotMsg.getParentToChildRegionsPairListCount() > 0) { 335 for (RestoreParentToChildRegionsPair parentToChildrenPair : restoreSnapshotMsg 336 .getParentToChildRegionsPairListList()) { 337 parentsToChildrenPairMap.put(parentToChildrenPair.getParentRegionName(), new Pair<>( 338 parentToChildrenPair.getChild1RegionName(), parentToChildrenPair.getChild2RegionName())); 339 } 340 } 341 if (restoreSnapshotMsg.hasRestoreAcl()) { 342 restoreAcl = restoreSnapshotMsg.getRestoreAcl(); 343 } 344 } 345 346 /** 347 * Action before any real action of restoring from snapshot. 348 * @param env MasterProcedureEnv 349 */ 350 private void prepareRestore(final MasterProcedureEnv env) throws IOException { 351 final TableName tableName = getTableName(); 352 // Checks whether the table exists 353 if (!env.getMasterServices().getTableDescriptors().exists(tableName)) { 354 throw new TableNotFoundException(tableName); 355 } 356 357 // check whether ttl has expired for this snapshot 358 if ( 359 SnapshotDescriptionUtils.isExpiredSnapshot(snapshot.getTtl(), snapshot.getCreationTime(), 360 EnvironmentEdgeManager.currentTime()) 361 ) { 362 throw new SnapshotTTLExpiredException(ProtobufUtil.createSnapshotDesc(snapshot)); 363 } 364 365 // Check whether table is disabled. 366 env.getMasterServices().checkTableModifiable(tableName); 367 368 // Check that we have at least 1 CF 369 if (modifiedTableDescriptor.getColumnFamilyCount() == 0) { 370 throw new DoNotRetryIOException( 371 "Table " + getTableName().toString() + " should have at least one column family."); 372 } 373 374 if (!getTableName().isSystemTable()) { 375 // Table already exist. Check and update the region quota for this table namespace. 376 final MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem(); 377 SnapshotManifest manifest = 378 SnapshotManifest.open(env.getMasterConfiguration(), mfs.getFileSystem(), 379 SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshot, mfs.getRootDir()), snapshot); 380 int snapshotRegionCount = manifest.getRegionManifestsMap().size(); 381 int tableRegionCount = 382 ProcedureSyncWait.getMasterQuotaManager(env).getRegionCountOfTable(tableName); 383 384 if (snapshotRegionCount > 0 && tableRegionCount != snapshotRegionCount) { 385 ProcedureSyncWait.getMasterQuotaManager(env).checkAndUpdateNamespaceRegionQuota(tableName, 386 snapshotRegionCount); 387 } 388 } 389 } 390 391 /** 392 * Update descriptor 393 * @param env MasterProcedureEnv 394 **/ 395 private void updateTableDescriptor(final MasterProcedureEnv env) throws IOException { 396 env.getMasterServices().getTableDescriptors().update(modifiedTableDescriptor); 397 } 398 399 /** 400 * Execute the on-disk Restore 401 * @param env MasterProcedureEnv 402 **/ 403 private void restoreSnapshot(final MasterProcedureEnv env) throws IOException { 404 MasterFileSystem fileSystemManager = env.getMasterServices().getMasterFileSystem(); 405 FileSystem fs = fileSystemManager.getFileSystem(); 406 Path rootDir = fileSystemManager.getRootDir(); 407 final ForeignExceptionDispatcher monitorException = new ForeignExceptionDispatcher(); 408 final Configuration conf = new Configuration(env.getMasterConfiguration()); 409 410 LOG.info("Starting restore snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot)); 411 try { 412 Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshot, rootDir); 413 SnapshotManifest manifest = SnapshotManifest.open(conf, fs, snapshotDir, snapshot); 414 RestoreSnapshotHelper restoreHelper = new RestoreSnapshotHelper(conf, fs, manifest, 415 modifiedTableDescriptor, rootDir, monitorException, getMonitorStatus()); 416 417 RestoreSnapshotHelper.RestoreMetaChanges metaChanges = restoreHelper.restoreHdfsRegions(); 418 regionsToRestore = metaChanges.getRegionsToRestore(); 419 regionsToRemove = metaChanges.getRegionsToRemove(); 420 regionsToAdd = metaChanges.getRegionsToAdd(); 421 parentsToChildrenPairMap = metaChanges.getParentToChildrenPairMap(); 422 } catch (IOException e) { 423 String msg = "restore snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) 424 + " failed in on-disk restore. Try re-running the restore command."; 425 LOG.error(msg, e); 426 monitorException 427 .receive(new ForeignException(env.getMasterServices().getServerName().toString(), e)); 428 throw new IOException(msg, e); 429 } 430 } 431 432 /** 433 * Apply changes to hbase:meta 434 **/ 435 private void updateMETA(final MasterProcedureEnv env) throws IOException { 436 try { 437 Connection conn = env.getMasterServices().getConnection(); 438 RegionStateStore regionStateStore = env.getAssignmentManager().getRegionStateStore(); 439 int regionReplication = modifiedTableDescriptor.getRegionReplication(); 440 441 // 1. Prepare to restore 442 getMonitorStatus().setStatus("Preparing to restore each region"); 443 444 // 2. Applies changes to hbase:meta and in-memory states 445 // (2.1). Removes the current set of regions from META and in-memory states 446 // 447 // By removing also the regions to restore (the ones present both in the snapshot 448 // and in the current state) we ensure that no extra fields are present in META 449 // e.g. with a simple add addRegionToMeta() the splitA and splitB attributes 450 // not overwritten/removed, so you end up with old informations 451 // that are not correct after the restore. 452 if (regionsToRemove != null) { 453 regionStateStore.deleteRegions(regionsToRemove); 454 deleteRegionsFromInMemoryStates(regionsToRemove, env, regionReplication); 455 } 456 457 // (2.2). Add the new set of regions to META and in-memory states 458 // 459 // At this point the old regions are no longer present in META. 460 // and the set of regions present in the snapshot will be written to META. 461 // All the information in hbase:meta are coming from the .regioninfo of each region present 462 // in the snapshot folder. 463 if (regionsToAdd != null) { 464 MetaTableAccessor.addRegionsToMeta(conn, regionsToAdd, regionReplication); 465 addRegionsToInMemoryStates(regionsToAdd, env, regionReplication); 466 } 467 468 if (regionsToRestore != null) { 469 regionStateStore.overwriteRegions(regionsToRestore, regionReplication); 470 471 deleteRegionsFromInMemoryStates(regionsToRestore, env, regionReplication); 472 addRegionsToInMemoryStates(regionsToRestore, env, regionReplication); 473 } 474 475 RestoreSnapshotHelper.RestoreMetaChanges metaChanges = 476 new RestoreSnapshotHelper.RestoreMetaChanges(modifiedTableDescriptor, 477 parentsToChildrenPairMap); 478 metaChanges.updateMetaParentRegions(conn, regionsToAdd); 479 480 // At this point the restore is complete. 481 LOG.info("Restore snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) 482 + " on table=" + getTableName() + " completed!"); 483 } catch (IOException e) { 484 final ForeignExceptionDispatcher monitorException = new ForeignExceptionDispatcher(); 485 String msg = "restore snapshot=" + ClientSnapshotDescriptionUtils.toString(snapshot) 486 + " failed in meta update. Try re-running the restore command."; 487 LOG.error(msg, e); 488 monitorException 489 .receive(new ForeignException(env.getMasterServices().getServerName().toString(), e)); 490 throw new IOException(msg, e); 491 } 492 493 monitorStatus.markComplete("Restore snapshot '" + snapshot.getName() + "'!"); 494 MetricsSnapshot metricsSnapshot = new MetricsSnapshot(); 495 metricsSnapshot 496 .addSnapshotRestore(monitorStatus.getCompletionTimestamp() - monitorStatus.getStartTime()); 497 } 498 499 /** 500 * Delete regions from in-memory states 501 * @param regionInfos regions to delete 502 * @param env MasterProcedureEnv 503 * @param regionReplication the number of region replications 504 */ 505 private void deleteRegionsFromInMemoryStates(List<RegionInfo> regionInfos, MasterProcedureEnv env, 506 int regionReplication) { 507 FavoredNodesManager fnm = env.getMasterServices().getFavoredNodesManager(); 508 509 env.getAssignmentManager().getRegionStates().deleteRegions(regionInfos); 510 env.getMasterServices().getServerManager().removeRegions(regionInfos); 511 if (fnm != null) { 512 fnm.deleteFavoredNodesForRegions(regionInfos); 513 } 514 515 // For region replicas 516 if (regionReplication > 1) { 517 for (RegionInfo regionInfo : regionInfos) { 518 for (int i = 1; i < regionReplication; i++) { 519 RegionInfo regionInfoForReplica = 520 RegionReplicaUtil.getRegionInfoForReplica(regionInfo, i); 521 env.getAssignmentManager().getRegionStates().deleteRegion(regionInfoForReplica); 522 env.getMasterServices().getServerManager().removeRegion(regionInfoForReplica); 523 if (fnm != null) { 524 fnm.deleteFavoredNodesForRegion(regionInfoForReplica); 525 } 526 } 527 } 528 } 529 } 530 531 /** 532 * Add regions to in-memory states 533 * @param regionInfos regions to add 534 * @param env MasterProcedureEnv 535 * @param regionReplication the number of region replications 536 */ 537 private void addRegionsToInMemoryStates(List<RegionInfo> regionInfos, MasterProcedureEnv env, 538 int regionReplication) { 539 AssignmentManager am = env.getAssignmentManager(); 540 for (RegionInfo regionInfo : regionInfos) { 541 if (regionInfo.isSplit()) { 542 am.getRegionStates().updateRegionState(regionInfo, RegionState.State.SPLIT); 543 } else { 544 am.getRegionStates().updateRegionState(regionInfo, RegionState.State.CLOSED); 545 546 // For region replicas 547 for (int i = 1; i < regionReplication; i++) { 548 RegionInfo regionInfoForReplica = 549 RegionReplicaUtil.getRegionInfoForReplica(regionInfo, i); 550 am.getRegionStates().updateRegionState(regionInfoForReplica, RegionState.State.CLOSED); 551 } 552 } 553 } 554 } 555 556 private void restoreSnapshotAcl(final MasterProcedureEnv env) throws IOException { 557 if ( 558 restoreAcl && snapshot.hasUsersAndPermissions() && snapshot.getUsersAndPermissions() != null 559 && SnapshotDescriptionUtils.isSecurityAvailable(env.getMasterServices().getConfiguration()) 560 ) { 561 // restore acl of snapshot to table. 562 RestoreSnapshotHelper.restoreSnapshotAcl(snapshot, TableName.valueOf(snapshot.getTable()), 563 env.getMasterServices().getConfiguration()); 564 } 565 } 566 567 /** 568 * Exposed for Testing: HBASE-26462 569 */ 570 @RestrictedApi(explanation = "Should only be called in tests", link = "", 571 allowedOnPath = ".*/src/test/.*") 572 public boolean getRestoreAcl() { 573 return restoreAcl; 574 } 575}