@InterfaceAudience.Private public abstract class RegionTransitionProcedure extends Procedure<MasterProcedureEnv> implements TableProcedureInterface, RemoteProcedureDispatcher.RemoteProcedure<MasterProcedureEnv,ServerName>
This procedure is asynchronous and responds to external events. The AssignmentManager will notify this procedure when the RS completes the operation and reports the transitioned state (see the Assign and Unassign class for more detail).
Procedures move from the REGION_TRANSITION_QUEUE state when they are first submitted, to the REGION_TRANSITION_DISPATCH state when the request to remote server is sent and the Procedure is suspended waiting on external event to be woken again. Once the external event is triggered, Procedure moves to the REGION_TRANSITION_FINISH state.
NOTE: AssignProcedure
and UnassignProcedure
should not be thought of
as being asymmetric, at least currently.
AssignProcedure
moves through all the above described states and implements methods
associated with each while UnassignProcedure
starts at state
REGION_TRANSITION_DISPATCH and state REGION_TRANSITION_QUEUE is not supported.AssignProcedure
fails, failure handler
AssignProcedure#handleFailure(MasterProcedureEnv, RegionStateNode) re-attempts the
assignment by setting the procedure state to REGION_TRANSITION_QUEUE and forces
assignment to a different target server by setting AssignProcedure.forceNewPlan
. When
the number of attempts reaches threshold configuration 'hbase.assignment.maximum.attempts',
the procedure is aborted. For UnassignProcedure
, similar re-attempts are
intentionally not implemented. It is a 'one shot' procedure. See its class doc for how it
handles failure.
regionInfo
.
TODO: Considering it is a priority doing all we can to get make a region available as soon as
possible, re-attempting with any target makes sense if specified target fails in case of
AssignProcedure
. For UnassignProcedure
, our concern is preventing data loss
on failed unassign. See class doc for explanation.
Procedure.LockState
TableProcedureInterface.TableOperationType
Modifier and Type | Field and Description |
---|---|
protected AtomicBoolean |
aborted |
private int |
attempt
Like
regionInfo , the expectation is that subclasses persist the value of this
data member. |
private static org.slf4j.Logger |
LOG |
private boolean |
override
this data member must also be persisted.
|
private RegionInfo |
regionInfo
This data member must be persisted.
|
private org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState |
transitionState |
NO_PROC_ID, NO_TIMEOUT
Constructor and Description |
---|
RegionTransitionProcedure() |
RegionTransitionProcedure(RegionInfo regionInfo,
boolean override) |
Modifier and Type | Method and Description |
---|---|
protected boolean |
abort(MasterProcedureEnv env)
The abort() call is asynchronous and each procedure must decide how to deal
with it, if they want to be abortable.
|
protected Procedure.LockState |
acquireLock(MasterProcedureEnv env)
The user should override this method if they need a lock on an Entity.
|
protected boolean |
addToRemoteDispatcher(MasterProcedureEnv env,
ServerName targetServer)
Be careful! At the end of this method, the procedure has either succeeded
and this procedure has been set into a suspended state OR, we failed and
this procedure has been put back on the scheduler ready for another worker
to pick it up.
|
protected void |
bypass(MasterProcedureEnv env)
Set the bypass to true.
|
protected Procedure[] |
execute(MasterProcedureEnv env)
The main code of the procedure.
|
protected abstract void |
finishTransition(MasterProcedureEnv env,
RegionStates.RegionStateNode regionNode) |
protected int |
getAttempt() |
RegionInfo |
getRegionInfo() |
RegionStates.RegionStateNode |
getRegionState(MasterProcedureEnv env) |
abstract ServerName |
getServer(MasterProcedureEnv env)
Used by ServerCrashProcedure to see if this Assign/Unassign needs processing.
|
TableName |
getTableName() |
protected org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState |
getTransitionState() |
protected boolean |
holdLock(MasterProcedureEnv env)
Used to keep the procedure lock even when the procedure is yielding or suspended.
|
boolean |
isMeta() |
(package private) boolean |
isOverride() |
protected abstract boolean |
isRollbackSupported(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState state) |
protected boolean |
isServerOnline(MasterProcedureEnv env,
RegionStates.RegionStateNode regionNode) |
protected boolean |
isServerOnline(MasterProcedureEnv env,
ServerName serverName) |
protected void |
releaseLock(MasterProcedureEnv env)
The user should override this method, and release lock if necessary.
|
abstract RemoteProcedureDispatcher.RemoteOperation |
remoteCallBuild(MasterProcedureEnv env,
ServerName serverName) |
void |
remoteCallCompleted(MasterProcedureEnv env,
ServerName serverName,
RemoteProcedureDispatcher.RemoteOperation response) |
protected abstract boolean |
remoteCallFailed(MasterProcedureEnv env,
RegionStates.RegionStateNode regionNode,
IOException exception) |
boolean |
remoteCallFailed(MasterProcedureEnv env,
ServerName serverName,
IOException exception) |
protected abstract void |
reportTransition(MasterProcedureEnv env,
RegionStates.RegionStateNode regionNode,
org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode code,
long seqId) |
protected void |
reportTransition(MasterProcedureEnv env,
ServerName serverName,
org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode code,
long seqId) |
protected void |
rollback(MasterProcedureEnv env)
The code to undo what was done by the execute() code.
|
protected void |
setAttempt(int attempt)
This setter is for subclasses to call in their
Procedure.deserializeStateData(ProcedureStateSerializer) method. |
protected void |
setOverride(boolean override)
This setter is for subclasses to call in their
Procedure.deserializeStateData(ProcedureStateSerializer) method. |
protected void |
setRegionInfo(RegionInfo regionInfo)
This setter is for subclasses to call in their
Procedure.deserializeStateData(ProcedureStateSerializer) method. |
protected boolean |
setTimeoutFailure(MasterProcedureEnv env)
At end of timeout, wake ourselves up so we run again.
|
(package private) void |
setTransitionState(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState state) |
protected boolean |
shouldWaitClientAck(MasterProcedureEnv env)
By default, the executor will keep the procedure result around util
the eviction TTL is expired.
|
protected abstract boolean |
startTransition(MasterProcedureEnv env,
RegionStates.RegionStateNode regionNode) |
void |
toStringClassDetails(StringBuilder sb)
Extend the toString() information with the procedure details
e.g.
|
protected void |
toStringState(StringBuilder builder)
Called from
Procedure.toString() when interpolating Procedure State. |
protected abstract boolean |
updateTransition(MasterProcedureEnv env,
RegionStates.RegionStateNode regionNode)
Called when the Procedure is in the REGION_TRANSITION_DISPATCH state.
|
protected boolean |
waitInitialized(MasterProcedureEnv env)
The
Procedure.doAcquireLock(Object, ProcedureStore) will be split into two steps, first, it will
call us to determine whether we need to wait for initialization, second, it will call
Procedure.acquireLock(Object) to actually handle the lock for this procedure. |
addStackIndex, afterReplay, beforeReplay, compareTo, completionCleanup, deserializeStateData, doExecute, doRollback, elapsedTime, getChildrenLatch, getException, getLastUpdate, getNonceKey, getOwner, getParentProcId, getProcedureMetrics, getProcId, getProcIdHashCode, getProcName, getResult, getRootProcedureId, getRootProcId, getStackIndexes, getState, getSubmittedTime, getTimeout, getTimeoutTimestamp, hasChildren, hasException, hasLock, hasOwner, hasParent, hasTimeout, haveSameParent, incChildrenLatch, isBypass, isFailed, isFinished, isInitializing, isLockedWhenLoading, isRunnable, isSuccess, isWaiting, isYieldAfterExecutionStep, removeStackIndex, serializeStateData, setAbortFailure, setChildrenLatch, setFailure, setFailure, setLastUpdate, setNonceKey, setOwner, setOwner, setParentProcId, setProcId, setResult, setRootProcId, setStackIndexes, setState, setSubmittedTime, setTimeout, skipPersistence, toString, toStringClass, toStringDetails, toStringSimpleSB, updateMetricsOnFinish, updateMetricsOnSubmit, updateTimestamp, wasExecuted
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getTableOperationType
private static final org.slf4j.Logger LOG
protected final AtomicBoolean aborted
private org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState transitionState
private RegionInfo regionInfo
Procedure.serializeStateData(ProcedureStateSerializer)
call, restoring regionInfo
in their Procedure.deserializeStateData(ProcedureStateSerializer)
method.private boolean override
regionInfo
private int attempt
regionInfo
, the expectation is that subclasses persist the value of this
data member. It is used doing backoff when Procedure gets stuck.public RegionTransitionProcedure()
public RegionTransitionProcedure(RegionInfo regionInfo, boolean override)
public RegionInfo getRegionInfo()
protected void setRegionInfo(RegionInfo regionInfo)
Procedure.deserializeStateData(ProcedureStateSerializer)
method. Expectation is that
subclasses will persist `regioninfo` in their
Procedure.serializeStateData(ProcedureStateSerializer)
method and then restore `regionInfo` on
deserialization by calling this.protected void setOverride(boolean override)
Procedure.deserializeStateData(ProcedureStateSerializer)
method. Expectation is that
subclasses will persist `override` in their
Procedure.serializeStateData(ProcedureStateSerializer)
method and then restore `override` on
deserialization by calling this.protected void setAttempt(int attempt)
Procedure.deserializeStateData(ProcedureStateSerializer)
method.setRegionInfo(RegionInfo)
protected int getAttempt()
public TableName getTableName()
getTableName
in interface TableProcedureInterface
public boolean isMeta()
public void toStringClassDetails(StringBuilder sb)
Procedure
toStringClassDetails
in class Procedure<MasterProcedureEnv>
sb
- the string builder to use to append the proc specific informationpublic RegionStates.RegionStateNode getRegionState(MasterProcedureEnv env)
void setTransitionState(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState state)
protected org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState getTransitionState()
protected abstract boolean startTransition(MasterProcedureEnv env, RegionStates.RegionStateNode regionNode) throws IOException, ProcedureSuspendedException
protected abstract boolean updateTransition(MasterProcedureEnv env, RegionStates.RegionStateNode regionNode) throws IOException, ProcedureSuspendedException
protected abstract void finishTransition(MasterProcedureEnv env, RegionStates.RegionStateNode regionNode) throws IOException, ProcedureSuspendedException
protected abstract void reportTransition(MasterProcedureEnv env, RegionStates.RegionStateNode regionNode, org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode code, long seqId) throws UnexpectedStateException
UnexpectedStateException
public abstract RemoteProcedureDispatcher.RemoteOperation remoteCallBuild(MasterProcedureEnv env, ServerName serverName)
remoteCallBuild
in interface RemoteProcedureDispatcher.RemoteProcedure<MasterProcedureEnv,ServerName>
protected abstract boolean remoteCallFailed(MasterProcedureEnv env, RegionStates.RegionStateNode regionNode, IOException exception)
public void remoteCallCompleted(MasterProcedureEnv env, ServerName serverName, RemoteProcedureDispatcher.RemoteOperation response)
remoteCallCompleted
in interface RemoteProcedureDispatcher.RemoteProcedure<MasterProcedureEnv,ServerName>
public boolean remoteCallFailed(MasterProcedureEnv env, ServerName serverName, IOException exception)
remoteCallFailed
in interface RemoteProcedureDispatcher.RemoteProcedure<MasterProcedureEnv,ServerName>
protected boolean addToRemoteDispatcher(MasterProcedureEnv env, ServerName targetServer)
protected void reportTransition(MasterProcedureEnv env, ServerName serverName, org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode code, long seqId) throws UnexpectedStateException
UnexpectedStateException
protected boolean isServerOnline(MasterProcedureEnv env, RegionStates.RegionStateNode regionNode)
protected boolean isServerOnline(MasterProcedureEnv env, ServerName serverName)
protected void toStringState(StringBuilder builder)
Procedure
Procedure.toString()
when interpolating Procedure
State. Allows decorating
generic Procedure State with Procedure particulars.toStringState
in class Procedure<MasterProcedureEnv>
builder
- Append current ProcedureProtos.ProcedureState
protected Procedure[] execute(MasterProcedureEnv env) throws ProcedureSuspendedException
Procedure
execute
in class Procedure<MasterProcedureEnv>
env
- the environment passed to the ProcedureExecutorProcedureSuspendedException
- Signal to the executor that Procedure has suspended itself and
has set itself up waiting for an external event to wake it back up again.protected boolean setTimeoutFailure(MasterProcedureEnv env)
setTimeoutFailure
in class Procedure<MasterProcedureEnv>
protected void rollback(MasterProcedureEnv env)
Procedure
rollback
in class Procedure<MasterProcedureEnv>
env
- the environment passed to the ProcedureExecutorprotected abstract boolean isRollbackSupported(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionState state)
protected boolean abort(MasterProcedureEnv env)
Procedure
NOTE: abort() is not like Thread.interrupt(). It is just a notification that allows the procedure implementor abort.
abort
in class Procedure<MasterProcedureEnv>
protected boolean waitInitialized(MasterProcedureEnv env)
Procedure
Procedure.doAcquireLock(Object, ProcedureStore)
will be split into two steps, first, it will
call us to determine whether we need to wait for initialization, second, it will call
Procedure.acquireLock(Object)
to actually handle the lock for this procedure.
This is because that when master restarts, we need to restore the lock state for all the
procedures to not break the semantic if Procedure.holdLock(Object)
is true. But the
ProcedureExecutor
will be started before the master finish initialization(as it is part
of the initialization!), so we need to split the code into two steps, and when restore, we just
restore the lock part and ignore the waitInitialized part. Otherwise there will be dead lock.waitInitialized
in class Procedure<MasterProcedureEnv>
protected Procedure.LockState acquireLock(MasterProcedureEnv env)
Procedure
Procedure.execute(Object)
. It calls Procedure.releaseLock(Object)
after the call to
execute.
If you need to hold the lock for the life of the Procedure -- i.e. you do not want any other
Procedure interfering while this Procedure is running, see Procedure.holdLock(Object)
.
Example: in our Master we can execute request in parallel for different tables. We can create
t1 and create t2 and these creates can be executed at the same time. Anything else on t1/t2 is
queued waiting that specific table create to happen.
There are 3 LockState:
acquireLock
in class Procedure<MasterProcedureEnv>
protected void releaseLock(MasterProcedureEnv env)
Procedure
releaseLock
in class Procedure<MasterProcedureEnv>
protected boolean holdLock(MasterProcedureEnv env)
Procedure
holdLock
in class Procedure<MasterProcedureEnv>
protected boolean shouldWaitClientAck(MasterProcedureEnv env)
Procedure
shouldWaitClientAck
in class Procedure<MasterProcedureEnv>
env
- the environment passed to the ProcedureExecutorpublic abstract ServerName getServer(MasterProcedureEnv env)
protected void bypass(MasterProcedureEnv env)
Procedure
ProcedureExecutor.bypassProcedure(long, long, boolean, boolean)
for
now.
DO NOT use this method alone, since we can't just bypass one single procedure. We need to
bypass its ancestor too. If your Procedure has set state, it needs to undo it in here.bypass
in class Procedure<MasterProcedureEnv>
env
- Current environment. May be null because of context; e.g. pretty-printing
procedure WALs where there is no 'environment' (and where Procedures that require
an 'environment' won't be run.boolean isOverride()
Copyright © 2007–2019 The Apache Software Foundation. All rights reserved.