Return-Path: X-Original-To: apmail-hbase-commits-archive@www.apache.org Delivered-To: apmail-hbase-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 39421180D1 for ; Fri, 15 Jan 2016 17:04:08 +0000 (UTC) Received: (qmail 71989 invoked by uid 500); 15 Jan 2016 17:04:07 -0000 Delivered-To: apmail-hbase-commits-archive@hbase.apache.org Received: (qmail 71701 invoked by uid 500); 15 Jan 2016 17:04:07 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 71688 invoked by uid 99); 15 Jan 2016 17:04:07 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 15 Jan 2016 17:04:07 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 34394E07F6; Fri, 15 Jan 2016 17:04:07 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: misty@apache.org To: commits@hbase.apache.org Date: Fri, 15 Jan 2016 17:04:15 -0000 Message-Id: <4bd2c1f9b3994d43b6597c4263d82055@git.apache.org> In-Reply-To: <4be18a42f8bc4fac8008fffd526b82d6@git.apache.org> References: <4be18a42f8bc4fac8008fffd526b82d6@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [10/51] [partial] hbase-site git commit: Published site at cb17c7a97a1e2eb0ebd532f614191e4edbb9e49b. http://git-wip-us.apache.org/repos/asf/hbase-site/blob/50917b1d/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/DisableTableProcedure.BulkDisabler.html ---------------------------------------------------------------------- diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/DisableTableProcedure.BulkDisabler.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/DisableTableProcedure.BulkDisabler.html index 5439921..945a72c 100644 --- a/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/DisableTableProcedure.BulkDisabler.html +++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/DisableTableProcedure.BulkDisabler.html @@ -44,511 +44,508 @@ 036import org.apache.hadoop.hbase.classification.InterfaceAudience; 037import org.apache.hadoop.hbase.client.TableState; 038import org.apache.hadoop.hbase.constraint.ConstraintException; -039import org.apache.hadoop.hbase.executor.EventType; -040import org.apache.hadoop.hbase.master.AssignmentManager; -041import org.apache.hadoop.hbase.master.BulkAssigner; -042import org.apache.hadoop.hbase.master.MasterCoprocessorHost; -043import org.apache.hadoop.hbase.master.RegionState; -044import org.apache.hadoop.hbase.master.RegionStates; -045import org.apache.hadoop.hbase.master.TableStateManager; -046import org.apache.hadoop.hbase.procedure2.StateMachineProcedure; -047import org.apache.hadoop.hbase.protobuf.ProtobufUtil; -048import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos; -049import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DisableTableState; -050import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; -051import org.apache.hadoop.security.UserGroupInformation; -052import org.apache.htrace.Trace; -053 -054@InterfaceAudience.Private -055public class DisableTableProcedure -056 extends StateMachineProcedure<MasterProcedureEnv, DisableTableState> -057 implements TableProcedureInterface { -058 private static final Log LOG = LogFactory.getLog(DisableTableProcedure.class); -059 -060 private final AtomicBoolean aborted = new AtomicBoolean(false); -061 -062 // This is for back compatible with 1.0 asynchronized operations. -063 private final ProcedurePrepareLatch syncLatch; -064 -065 private TableName tableName; -066 private boolean skipTableStateCheck; -067 private UserGroupInformation user; -068 -069 private Boolean traceEnabled = null; -070 -071 enum MarkRegionOfflineOpResult { -072 MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL, -073 BULK_ASSIGN_REGIONS_FAILED, -074 MARK_ALL_REGIONS_OFFLINE_INTERRUPTED, -075 } -076 -077 public DisableTableProcedure() { -078 syncLatch = null; -079 } -080 -081 /** -082 * Constructor -083 * @param env MasterProcedureEnv -084 * @param tableName the table to operate on -085 * @param skipTableStateCheck whether to check table state -086 * @throws IOException -087 */ -088 public DisableTableProcedure( -089 final MasterProcedureEnv env, -090 final TableName tableName, -091 final boolean skipTableStateCheck) throws IOException { -092 this(env, tableName, skipTableStateCheck, null); -093 } -094 -095 /** -096 * Constructor -097 * @param env MasterProcedureEnv -098 * @param tableName the table to operate on -099 * @param skipTableStateCheck whether to check table state -100 * @throws IOException -101 */ -102 public DisableTableProcedure( -103 final MasterProcedureEnv env, -104 final TableName tableName, -105 final boolean skipTableStateCheck, -106 final ProcedurePrepareLatch syncLatch) throws IOException { -107 this.tableName = tableName; -108 this.skipTableStateCheck = skipTableStateCheck; -109 this.user = env.getRequestUser().getUGI(); -110 this.setOwner(this.user.getShortUserName()); -111 -112 // Compatible with 1.0: We use latch to make sure that this procedure implementation is -113 // compatible with 1.0 asynchronized operations. We need to lock the table and check -114 // whether the Disable operation could be performed (table exists and online; table state -115 // is ENABLED). Once it is done, we are good to release the latch and the client can -116 // start asynchronously wait for the operation. -117 // -118 // Note: the member syncLatch could be null if we are in failover or recovery scenario. -119 // This is ok for backward compatible, as 1.0 client would not able to peek at procedure. -120 this.syncLatch = syncLatch; -121 } -122 -123 @Override -124 protected Flow executeFromState(final MasterProcedureEnv env, final DisableTableState state) -125 throws InterruptedException { -126 if (isTraceEnabled()) { -127 LOG.trace(this + " execute state=" + state); -128 } -129 -130 try { -131 switch (state) { -132 case DISABLE_TABLE_PREPARE: -133 if (prepareDisable(env)) { -134 setNextState(DisableTableState.DISABLE_TABLE_PRE_OPERATION); -135 } else { -136 assert isFailed() : "disable should have an exception here"; -137 return Flow.NO_MORE_STATE; -138 } -139 break; -140 case DISABLE_TABLE_PRE_OPERATION: -141 preDisable(env, state); -142 setNextState(DisableTableState.DISABLE_TABLE_SET_DISABLING_TABLE_STATE); -143 break; -144 case DISABLE_TABLE_SET_DISABLING_TABLE_STATE: -145 setTableStateToDisabling(env, tableName); -146 setNextState(DisableTableState.DISABLE_TABLE_MARK_REGIONS_OFFLINE); -147 break; -148 case DISABLE_TABLE_MARK_REGIONS_OFFLINE: -149 if (markRegionsOffline(env, tableName, true) == -150 MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL) { -151 setNextState(DisableTableState.DISABLE_TABLE_SET_DISABLED_TABLE_STATE); -152 } else { -153 LOG.trace("Retrying later to disable the missing regions"); -154 } -155 break; -156 case DISABLE_TABLE_SET_DISABLED_TABLE_STATE: -157 setTableStateToDisabled(env, tableName); -158 setNextState(DisableTableState.DISABLE_TABLE_POST_OPERATION); -159 break; -160 case DISABLE_TABLE_POST_OPERATION: -161 postDisable(env, state); -162 return Flow.NO_MORE_STATE; -163 default: -164 throw new UnsupportedOperationException("unhandled state=" + state); -165 } -166 } catch (IOException e) { -167 LOG.warn("Retriable error trying to disable table=" + tableName + " state=" + state, e); -168 } -169 return Flow.HAS_MORE_STATE; -170 } -171 -172 @Override -173 protected void rollbackState(final MasterProcedureEnv env, final DisableTableState state) -174 throws IOException { -175 if (state == DisableTableState.DISABLE_TABLE_PREPARE) { -176 // nothing to rollback, prepare-disable is just table-state checks. -177 // We can fail if the table does not exist or is not disabled. -178 ProcedurePrepareLatch.releaseLatch(syncLatch, this); -179 return; -180 } -181 -182 // The delete doesn't have a rollback. The execution will succeed, at some point. -183 throw new UnsupportedOperationException("unhandled state=" + state); -184 } -185 -186 @Override -187 protected DisableTableState getState(final int stateId) { -188 return DisableTableState.valueOf(stateId); -189 } -190 -191 @Override -192 protected int getStateId(final DisableTableState state) { -193 return state.getNumber(); -194 } -195 -196 @Override -197 protected DisableTableState getInitialState() { -198 return DisableTableState.DISABLE_TABLE_PREPARE; -199 } -200 -201 @Override -202 protected void setNextState(final DisableTableState state) { -203 if (aborted.get()) { -204 setAbortFailure("disable-table", "abort requested"); -205 } else { -206 super.setNextState(state); -207 } -208 } -209 -210 @Override -211 public boolean abort(final MasterProcedureEnv env) { -212 aborted.set(true); -213 return true; -214 } -215 -216 @Override -217 protected boolean acquireLock(final MasterProcedureEnv env) { -218 if (!env.isInitialized()) return false; -219 return env.getProcedureQueue().tryAcquireTableExclusiveLock( -220 tableName, -221 EventType.C_M_DISABLE_TABLE.toString()); -222 } -223 -224 @Override -225 protected void releaseLock(final MasterProcedureEnv env) { -226 env.getProcedureQueue().releaseTableExclusiveLock(tableName); -227 } -228 -229 @Override -230 public void serializeStateData(final OutputStream stream) throws IOException { -231 super.serializeStateData(stream); -232 -233 MasterProcedureProtos.DisableTableStateData.Builder disableTableMsg = -234 MasterProcedureProtos.DisableTableStateData.newBuilder() -235 .setUserInfo(MasterProcedureUtil.toProtoUserInfo(user)) -236 .setTableName(ProtobufUtil.toProtoTableName(tableName)) -237 .setSkipTableStateCheck(skipTableStateCheck); +039import org.apache.hadoop.hbase.master.AssignmentManager; +040import org.apache.hadoop.hbase.master.BulkAssigner; +041import org.apache.hadoop.hbase.master.MasterCoprocessorHost; +042import org.apache.hadoop.hbase.master.RegionState; +043import org.apache.hadoop.hbase.master.RegionStates; +044import org.apache.hadoop.hbase.master.TableStateManager; +045import org.apache.hadoop.hbase.procedure2.StateMachineProcedure; +046import org.apache.hadoop.hbase.protobuf.ProtobufUtil; +047import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos; +048import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DisableTableState; +049import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; +050import org.apache.hadoop.security.UserGroupInformation; +051import org.apache.htrace.Trace; +052 +053@InterfaceAudience.Private +054public class DisableTableProcedure +055 extends StateMachineProcedure<MasterProcedureEnv, DisableTableState> +056 implements TableProcedureInterface { +057 private static final Log LOG = LogFactory.getLog(DisableTableProcedure.class); +058 +059 private final AtomicBoolean aborted = new AtomicBoolean(false); +060 +061 // This is for back compatible with 1.0 asynchronized operations. +062 private final ProcedurePrepareLatch syncLatch; +063 +064 private TableName tableName; +065 private boolean skipTableStateCheck; +066 private UserGroupInformation user; +067 +068 private Boolean traceEnabled = null; +069 +070 enum MarkRegionOfflineOpResult { +071 MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL, +072 BULK_ASSIGN_REGIONS_FAILED, +073 MARK_ALL_REGIONS_OFFLINE_INTERRUPTED, +074 } +075 +076 public DisableTableProcedure() { +077 syncLatch = null; +078 } +079 +080 /** +081 * Constructor +082 * @param env MasterProcedureEnv +083 * @param tableName the table to operate on +084 * @param skipTableStateCheck whether to check table state +085 * @throws IOException +086 */ +087 public DisableTableProcedure( +088 final MasterProcedureEnv env, +089 final TableName tableName, +090 final boolean skipTableStateCheck) throws IOException { +091 this(env, tableName, skipTableStateCheck, null); +092 } +093 +094 /** +095 * Constructor +096 * @param env MasterProcedureEnv +097 * @param tableName the table to operate on +098 * @param skipTableStateCheck whether to check table state +099 * @throws IOException +100 */ +101 public DisableTableProcedure( +102 final MasterProcedureEnv env, +103 final TableName tableName, +104 final boolean skipTableStateCheck, +105 final ProcedurePrepareLatch syncLatch) throws IOException { +106 this.tableName = tableName; +107 this.skipTableStateCheck = skipTableStateCheck; +108 this.user = env.getRequestUser().getUGI(); +109 this.setOwner(this.user.getShortUserName()); +110 +111 // Compatible with 1.0: We use latch to make sure that this procedure implementation is +112 // compatible with 1.0 asynchronized operations. We need to lock the table and check +113 // whether the Disable operation could be performed (table exists and online; table state +114 // is ENABLED). Once it is done, we are good to release the latch and the client can +115 // start asynchronously wait for the operation. +116 // +117 // Note: the member syncLatch could be null if we are in failover or recovery scenario. +118 // This is ok for backward compatible, as 1.0 client would not able to peek at procedure. +119 this.syncLatch = syncLatch; +120 } +121 +122 @Override +123 protected Flow executeFromState(final MasterProcedureEnv env, final DisableTableState state) +124 throws InterruptedException { +125 if (isTraceEnabled()) { +126 LOG.trace(this + " execute state=" + state); +127 } +128 +129 try { +130 switch (state) { +131 case DISABLE_TABLE_PREPARE: +132 if (prepareDisable(env)) { +133 setNextState(DisableTableState.DISABLE_TABLE_PRE_OPERATION); +134 } else { +135 assert isFailed() : "disable should have an exception here"; +136 return Flow.NO_MORE_STATE; +137 } +138 break; +139 case DISABLE_TABLE_PRE_OPERATION: +140 preDisable(env, state); +141 setNextState(DisableTableState.DISABLE_TABLE_SET_DISABLING_TABLE_STATE); +142 break; +143 case DISABLE_TABLE_SET_DISABLING_TABLE_STATE: +144 setTableStateToDisabling(env, tableName); +145 setNextState(DisableTableState.DISABLE_TABLE_MARK_REGIONS_OFFLINE); +146 break; +147 case DISABLE_TABLE_MARK_REGIONS_OFFLINE: +148 if (markRegionsOffline(env, tableName, true) == +149 MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL) { +150 setNextState(DisableTableState.DISABLE_TABLE_SET_DISABLED_TABLE_STATE); +151 } else { +152 LOG.trace("Retrying later to disable the missing regions"); +153 } +154 break; +155 case DISABLE_TABLE_SET_DISABLED_TABLE_STATE: +156 setTableStateToDisabled(env, tableName); +157 setNextState(DisableTableState.DISABLE_TABLE_POST_OPERATION); +158 break; +159 case DISABLE_TABLE_POST_OPERATION: +160 postDisable(env, state); +161 return Flow.NO_MORE_STATE; +162 default: +163 throw new UnsupportedOperationException("unhandled state=" + state); +164 } +165 } catch (IOException e) { +166 LOG.warn("Retriable error trying to disable table=" + tableName + " state=" + state, e); +167 } +168 return Flow.HAS_MORE_STATE; +169 } +170 +171 @Override +172 protected void rollbackState(final MasterProcedureEnv env, final DisableTableState state) +173 throws IOException { +174 if (state == DisableTableState.DISABLE_TABLE_PREPARE) { +175 // nothing to rollback, prepare-disable is just table-state checks. +176 // We can fail if the table does not exist or is not disabled. +177 ProcedurePrepareLatch.releaseLatch(syncLatch, this); +178 return; +179 } +180 +181 // The delete doesn't have a rollback. The execution will succeed, at some point. +182 throw new UnsupportedOperationException("unhandled state=" + state); +183 } +184 +185 @Override +186 protected DisableTableState getState(final int stateId) { +187 return DisableTableState.valueOf(stateId); +188 } +189 +190 @Override +191 protected int getStateId(final DisableTableState state) { +192 return state.getNumber(); +193 } +194 +195 @Override +196 protected DisableTableState getInitialState() { +197 return DisableTableState.DISABLE_TABLE_PREPARE; +198 } +199 +200 @Override +201 protected void setNextState(final DisableTableState state) { +202 if (aborted.get()) { +203 setAbortFailure("disable-table", "abort requested"); +204 } else { +205 super.setNextState(state); +206 } +207 } +208 +209 @Override +210 public boolean abort(final MasterProcedureEnv env) { +211 aborted.set(true); +212 return true; +213 } +214 +215 @Override +216 protected boolean acquireLock(final MasterProcedureEnv env) { +217 if (env.waitInitialized(this)) return false; +218 return env.getProcedureQueue().tryAcquireTableExclusiveLock(tableName, "disable table"); +219 } +220 +221 @Override +222 protected void releaseLock(final MasterProcedureEnv env) { +223 env.getProcedureQueue().releaseTableExclusiveLock(tableName); +224 } +225 +226 @Override +227 public void serializeStateData(final OutputStream stream) throws IOException { +228 super.serializeStateData(stream); +229 +230 MasterProcedureProtos.DisableTableStateData.Builder disableTableMsg = +231 MasterProcedureProtos.DisableTableStateData.newBuilder() +232 .setUserInfo(MasterProcedureUtil.toProtoUserInfo(user)) +233 .setTableName(ProtobufUtil.toProtoTableName(tableName)) +234 .setSkipTableStateCheck(skipTableStateCheck); +235 +236 disableTableMsg.build().writeDelimitedTo(stream); +237 } 238 -239 disableTableMsg.build().writeDelimitedTo(stream); -240 } -241 -242 @Override -243 public void deserializeStateData(final InputStream stream) throws IOException { -244 super.deserializeStateData(stream); -245 -246 MasterProcedureProtos.DisableTableStateData disableTableMsg = -247 MasterProcedureProtos.DisableTableStateData.parseDelimitedFrom(stream); -248 user = MasterProcedureUtil.toUserInfo(disableTableMsg.getUserInfo()); -249 tableName = ProtobufUtil.toTableName(disableTableMsg.getTableName()); -250 skipTableStateCheck = disableTableMsg.getSkipTableStateCheck(); -251 } -252 -253 @Override -254 public void toStringClassDetails(StringBuilder sb) { -255 sb.append(getClass().getSimpleName()); -256 sb.append(" (table="); -257 sb.append(tableName); -258 sb.append(")"); -259 } -260 -261 @Override -262 public TableName getTableName() { -263 return tableName; -264 } -265 -266 @Override -267 public TableOperationType getTableOperationType() { -268 return TableOperationType.DISABLE; -269 } -270 -271 /** -272 * Action before any real action of disabling table. Set the exception in the procedure instead -273 * of throwing it. This approach is to deal with backward compatible with 1.0. -274 * @param env MasterProcedureEnv -275 * @throws IOException -276 */ -277 private boolean prepareDisable(final MasterProcedureEnv env) throws IOException { -278 boolean canTableBeDisabled = true; -279 if (tableName.equals(TableName.META_TABLE_NAME)) { -280 setFailure("master-disable-table", new ConstraintException("Cannot disable catalog table")); +239 @Override +240 public void deserializeStateData(final InputStream stream) throws IOException { +241 super.deserializeStateData(stream); +242 +243 MasterProcedureProtos.DisableTableStateData disableTableMsg = +244 MasterProcedureProtos.DisableTableStateData.parseDelimitedFrom(stream); +245 user = MasterProcedureUtil.toUserInfo(disableTableMsg.getUserInfo()); +246 tableName = ProtobufUtil.toTableName(disableTableMsg.getTableName()); +247 skipTableStateCheck = disableTableMsg.getSkipTableStateCheck(); +248 } +249 +250 @Override +251 public void toStringClassDetails(StringBuilder sb) { +252 sb.append(getClass().getSimpleName()); +253 sb.append(" (table="); +254 sb.append(tableName); +255 sb.append(")"); +256 } +257 +258 @Override +259 public TableName getTableName() { +260 return tableName; +261 } +262 +263 @Override +264 public TableOperationType getTableOperationType() { +265 return TableOperationType.DISABLE; +266 } +267 +268 /** +269 * Action before any real action of disabling table. Set the exception in the procedure instead +270 * of throwing it. This approach is to deal with backward compatible with 1.0. +271 * @param env MasterProcedureEnv +272 * @throws IOException +273 */ +274 private boolean prepareDisable(final MasterProcedureEnv env) throws IOException { +275 boolean canTableBeDisabled = true; +276 if (tableName.equals(TableName.META_TABLE_NAME)) { +277 setFailure("master-disable-table", new ConstraintException("Cannot disable catalog table")); +278 canTableBeDisabled = false; +279 } else if (!MetaTableAccessor.tableExists(env.getMasterServices().getConnection(), tableName)) { +280 setFailure("master-disable-table", new TableNotFoundException(tableName)); 281 canTableBeDisabled = false; -282 } else if (!MetaTableAccessor.tableExists(env.getMasterServices().getConnection(), tableName)) { -283 setFailure("master-disable-table", new TableNotFoundException(tableName)); -284 canTableBeDisabled = false; -285 } else if (!skipTableStateCheck) { -286 // There could be multiple client requests trying to disable or enable -287 // the table at the same time. Ensure only the first request is honored -288 // After that, no other requests can be accepted until the table reaches -289 // DISABLED or ENABLED. -290 // -291 // Note: in 1.0 release, we called TableStateManager.setTableStateIfInStates() to set -292 // the state to DISABLING from ENABLED. The implementation was done before table lock -293 // was implemented. With table lock, there is no need to set the state here (it will -294 // set the state later on). A quick state check should be enough for us to move forward. -295 TableStateManager tsm = -296 env.getMasterServices().getAssignmentManager().getTableStateManager(); -297 TableState.State state = tsm.getTableState(tableName); -298 if(!state.equals(TableState.State.ENABLED)){ -299 LOG.info("Table " + tableName + " isn't enabled;is "+state.name()+"; skipping disable"); -300 setFailure("master-disable-table", new TableNotEnabledException( -301 tableName+" state is "+state.name())); -302 canTableBeDisabled = false; -303 } -304 } +282 } else if (!skipTableStateCheck) { +283 // There could be multiple client requests trying to disable or enable +284 // the table at the same time. Ensure only the first request is honored +285 // After that, no other requests can be accepted until the table reaches +286 // DISABLED or ENABLED. +287 // +288 // Note: in 1.0 release, we called TableStateManager.setTableStateIfInStates() to set +289 // the state to DISABLING from ENABLED. The implementation was done before table lock +290 // was implemented. With table lock, there is no need to set the state here (it will +291 // set the state later on). A quick state check should be enough for us to move forward. +292 TableStateManager tsm = +293 env.getMasterServices().getAssignmentManager().getTableStateManager(); +294 TableState.State state = tsm.getTableState(tableName); +295 if(!state.equals(TableState.State.ENABLED)){ +296 LOG.info("Table " + tableName + " isn't enabled;is "+state.name()+"; skipping disable"); +297 setFailure("master-disable-table", new TableNotEnabledException( +298 tableName+" state is "+state.name())); +299 canTableBeDisabled = false; +300 } +301 } +302 +303 // We are done the check. Future actions in this procedure could be done asynchronously. +304 ProcedurePrepareLatch.releaseLatch(syncLatch, this); 305 -306 // We are done the check. Future actions in this procedure could be done asynchronously. -307 ProcedurePrepareLatch.releaseLatch(syncLatch, this); +306 return canTableBeDisabled; +307 } 308 -309 return canTableBeDisabled; -310 } -311 -312 /** -313 * Action before disabling table. -314 * @param env MasterProcedureEnv -315 * @param state the procedure state -316 * @throws IOException -317 * @throws InterruptedException -318 */ -319 protected void preDisable(final MasterProcedureEnv env, final DisableTableState state) -320 throws IOException, InterruptedException { -321 runCoprocessorAction(env, state); -322 } -323 -324 /** -325 * Mark table state to Disabling -326 * @param env MasterProcedureEnv -327 * @throws IOException -328 */ -329 protected static void setTableStateToDisabling( -330 final MasterProcedureEnv env, -331 final TableName tableName) throws IOException { -332 // Set table disabling flag up in zk. -333 env.getMasterServices().getAssignmentManager().getTableStateManager().setTableState( -334 tableName, -335 TableState.State.DISABLING); -336 } -337 -338 /** -339 * Mark regions of the table offline with retries -340 * @param env MasterProcedureEnv -341 * @param tableName the target table -342 * @param retryRequired whether to retry if the first run failed -343 * @return whether the operation is fully completed or being interrupted. -344 * @throws IOException -345 */ -346 protected static MarkRegionOfflineOpResult markRegionsOffline( -347 final MasterProcedureEnv env, -348 final TableName tableName, -349 final Boolean retryRequired) throws IOException { -350 // Dev consideration: add a config to control max number of retry. For now, it is hard coded. -351 int maxTry = (retryRequired ? 10 : 1); -352 MarkRegionOfflineOpResult operationResult = -353 MarkRegionOfflineOpResult.BULK_ASSIGN_REGIONS_FAILED; -354 do { -355 try { -356 operationResult = markRegionsOffline(env, tableName); -357 if (operationResult == MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL) { -358 break; -359 } +309 /** +310 * Action before disabling table. +311 * @param env MasterProcedureEnv +312 * @param state the procedure state +313 * @throws IOException +314 * @throws InterruptedException +315 */ +316 protected void preDisable(final MasterProcedureEnv env, final DisableTableState state) +317 throws IOException, InterruptedException { +318 runCoprocessorAction(env, state); +319 } +320 +321 /** +322 * Mark table state to Disabling +323 * @param env MasterProcedureEnv +324 * @throws IOException +325 */ +326 protected static void setTableStateToDisabling( +327 final MasterProcedureEnv env, +328 final TableName tableName) throws IOException { +329 // Set table disabling flag up in zk. +330 env.getMasterServices().getAssignmentManager().getTableStateManager().setTableState( +331 tableName, +332 TableState.State.DISABLING); +333 } +334 +335 /** +336 * Mark regions of the table offline with retries +337 * @param env MasterProcedureEnv +338 * @param tableName the target table +339 * @param retryRequired whether to retry if the first run failed +340 * @return whether the operation is fully completed or being interrupted. +341 * @throws IOException +342 */ +343 protected static MarkRegionOfflineOpResult markRegionsOffline( +344 final MasterProcedureEnv env, +345 final TableName tableName, +346 final Boolean retryRequired) throws IOException { +347 // Dev consideration: add a config to control max number of retry. For now, it is hard coded. +348 int maxTry = (retryRequired ? 10 : 1); +349 MarkRegionOfflineOpResult operationResult = +350 MarkRegionOfflineOpResult.BULK_ASSIGN_REGIONS_FAILED; +351 do { +352 try { +353 operationResult = markRegionsOffline(env, tableName); +354 if (operationResult == MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL) { +355 break; +356 } +357 maxTry--; +358 } catch (Exception e) { +359 LOG.warn("Received exception while marking regions online. tries left: " + maxTry, e); 360 maxTry--; -361 } catch (Exception e) { -362 LOG.warn("Received exception while marking regions online. tries left: " + maxTry, e); -363 maxTry--; -364 if (maxTry > 0) { -365 continue; // we still have some retry left, try again. -366 } -367 throw e; -368 } -369 } while (maxTry > 0); -370 -371 if (operationResult != MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL) { -372 LOG.warn("Some or all regions of the Table '" + tableName + "' were still online"); -373 } +361 if (maxTry > 0) { +362 continue; // we still have some retry left, try again. +363 } +364 throw e; +365 } +366 } while (maxTry > 0); +367 +368 if (operationResult != MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL) { +369 LOG.warn("Some or all regions of the Table '" + tableName + "' were still online"); +370 } +371 +372 return operationResult; +373 } 374 -375 return operationResult; -376 } -377 -378 /** -379 * Mark regions of the table offline -380 * @param env MasterProcedureEnv -381 * @param tableName the target table -382 * @return whether the operation is fully completed or being interrupted. -383 * @throws IOException -384 */ -385 private static MarkRegionOfflineOpResult markRegionsOffline( -386 final MasterProcedureEnv env, -387 final TableName tableName) throws IOException { -388 // Get list of online regions that are of this table. Regions that are -389 // already closed will not be included in this list; i.e. the returned -390 // list is not ALL regions in a table, its all online regions according -391 // to the in-memory state on this master. -392 MarkRegionOfflineOpResult operationResult = -393 MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL; -394 final List<HRegionInfo> regions = -395 env.getMasterServices().getAssignmentManager().getRegionStates() -396 .getRegionsOfTable(tableName); -397 if (regions.size() > 0) { -398 LOG.info("Offlining " + regions.size() + " regions."); -399 -400 BulkDisabler bd = new BulkDisabler(env, tableName, regions); -401 try { -402 if (!bd.bulkAssign()) { -403 operationResult = MarkRegionOfflineOpResult.BULK_ASSIGN_REGIONS_FAILED; -404 } -405 } catch (InterruptedException e) { -406 LOG.warn("Disable was interrupted"); -407 // Preserve the interrupt. -408 Thread.currentThread().interrupt(); -409 operationResult = MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_INTERRUPTED; -410 } -411 } -412 return operationResult; -413 } -414 -415 /** -416 * Mark table state to Disabled -417 * @param env MasterProcedureEnv -418 * @throws IOException -419 */ -420 protected static void setTableStateToDisabled( -421 final MasterProcedureEnv env, -422 final TableName tableName) throws IOException { -423 // Flip the table to disabled -424 env.getMasterServices().getAssignmentManager().getTableStateManager().setTableState( -425 tableName, -426 TableState.State.DISABLED); -427 LOG.info("Disabled table, " + tableName + ", is completed."); -428 } -429 -430 /** -431 * Action after disabling table. -432 * @param env MasterProcedureEnv -433 * @param state the procedure state -434 * @throws IOException -435 * @throws InterruptedException -436 */ -437 protected void postDisable(final MasterProcedureEnv env, final DisableTableState state) -438 throws IOException, InterruptedException { -439 runCoprocessorAction(env, state); -440 } -441 -442 /** -443 * The procedure could be restarted from a different machine. If the variable is null, we need to -444 * retrieve it. -445 * @return traceEnabled -446 */ -447 private Boolean isTraceEnabled() { -448 if (traceEnabled == null) { -449 traceEnabled = LOG.isTraceEnabled(); -450 } -451 return traceEnabled; -452 } -453 -454 /** -455 * Coprocessor Action. -456 * @param env MasterProcedureEnv -457 * @param state the procedure state -458 * @throws IOException -459 * @throws InterruptedException -460 */ -461 private void runCoprocessorAction(final MasterProcedureEnv env, final DisableTableState state) -462 throws IOException, InterruptedException { -463 final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost(); -464 if (cpHost != null) { -465 user.doAs(new PrivilegedExceptionAction<Void>() { -466 @Override -467 public Void run() throws Exception { -468 switch (state) { -469 case DISABLE_TABLE_PRE_OPERATION: -470 cpHost.preDisableTableHandler(tableName); +375 /** +376 * Mark regions of the table offline +377 * @param env MasterProcedureEnv +378 * @param tableName the target table +379 * @return whether the operation is fully completed or being interrupted. +380 * @throws IOException +381 */ +382 private static MarkRegionOfflineOpResult markRegionsOffline( +383 final MasterProcedureEnv env, +384 final TableName tableName) throws IOException { +385 // Get list of online regions that are of this table. Regions that are +386 // already closed will not be included in this list; i.e. the returned +387 // list is not ALL regions in a table, its all online regions according +388 // to the in-memory state on this master. +389 MarkRegionOfflineOpResult operationResult = +390 MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_SUCCESSFUL; +391 final List<HRegionInfo> regions = +392 env.getMasterServices().getAssignmentManager().getRegionStates() +393 .getRegionsOfTable(tableName); +394 if (regions.size() > 0) { +395 LOG.info("Offlining " + regions.size() + " regions."); +396 +397 BulkDisabler bd = new BulkDisabler(env, tableName, regions); +398 try { +399 if (!bd.bulkAssign()) { +400 operationResult = MarkRegionOfflineOpResult.BULK_ASSIGN_REGIONS_FAILED; +401 } +402 } catch (InterruptedException e) { +403 LOG.warn("Disable was interrupted"); +404 // Preserve the interrupt. +405 Thread.currentThread().interrupt(); +406 operationResult = MarkRegionOfflineOpResult.MARK_ALL_REGIONS_OFFLINE_INTERRUPTED; +407 } +408 } +409 return operationResult; +410 } +411 +412 /** +413 * Mark table state to Disabled +414 * @param env MasterProcedureEnv +415 * @throws IOException +416 */ +417 protected static void setTableStateToDisabled( +418 final MasterProcedureEnv env, +419 final TableName tableName) throws IOException { +420 // Flip the table to disabled +421 env.getMasterServices().getAssignmentManager().getTableStateManager().setTableState( +422 tableName, +423 TableState.State.DISABLED); +424 LOG.info("Disabled table, " + tableName + ", is completed."); +425 } +426 +427 /** +428 * Action after disabling table. +429 * @param env MasterProcedureEnv +430 * @param state the procedure state +431 * @throws IOException +432 * @throws InterruptedException +433 */ +434 protected void postDisable(final MasterProcedureEnv env, final DisableTableState state) +435 throws IOException, InterruptedException { +436 runCoprocessorAction(env, state); +437 } +438 +439 /** +440 * The procedure could be restarted from a different machine. If the variable is null, we need to +441 * retrieve it. +442 * @return traceEnabled +443 */ +444 private Boolean isTraceEnabled() { +445 if (traceEnabled == null) { +446 traceEnabled = LOG.isTraceEnabled(); +447 } +448 return traceEnabled; +449 } +450 +451 /** +452 * Coprocessor Action. +453 * @param env MasterProcedureEnv +454 * @param state the procedure state +455 * @throws IOException +456 * @throws InterruptedException +457 */ +458 private void runCoprocessorAction(final MasterProcedureEnv env, final DisableTableState state) +459 throws IOException, InterruptedException { +460 final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost(); +461 if (cpHost != null) { +462 user.doAs(new PrivilegedExceptionAction<Void>() { +463 @Override +464 public Void run() throws Exception { +465 switch (state) { +466 case DISABLE_TABLE_PRE_OPERATION: +467 cpHost.preDisableTableHandler(tableName); +468 break; +469 case DISABLE_TABLE_POST_OPERATION: +470 cpHost.postDisableTableHandler(tableName); 471 break; -472 case DISABLE_TABLE_POST_OPERATION: -473 cpHost.postDisableTableHandler(tableName); -474 break; -475 default: -476 throw new UnsupportedOperationException(this + " unhandled state=" + state); -477 } -478 return null; -479 } -480 }); -481 } -482 } -483 -484 /** -485 * Run bulk disable. -486 */ -487 private static class BulkDisabler extends BulkAssigner { -488 private final AssignmentManager assignmentManager; -489 private final List<HRegionInfo> regions; -490 private final TableName tableName; -491 private final int waitingTimeForEvents; -492 -493 public BulkDisabler(final MasterProcedureEnv env, final TableName tableName, -494 final List<HRegionInfo> regions) { -495 super(env.getMasterServices()); -496 this.assignmentManager = env.getMasterServices().getAssignmentManager(); -497 this.tableName = tableName; -498 this.regions = regions; -499 this.waitingTimeForEvents = -500 env.getMasterServices().getConfiguration() -501 .getInt("hbase.master.event.waiting.time", 1000); -502 } -503 -504 @Override -505 protected void populatePool(ExecutorService pool) { -506 RegionStates regionStates = assignmentManager.getRegionStates(); -507 for (final HRegionInfo region : regions) { -508 if (regionStates.isRegionInTransition(region) -509 && !regionStates.isRegionInState(region, RegionState.State.FAILED_CLOSE)) { -510 continue; -511 } -512 pool.execute(Trace.wrap("DisableTableHandler.BulkDisabler", new Runnable() { -513 @Override -514 public void run() { -515<