HBASE-21384 Procedure with holdlock=false should not be restored lock when restarts

This commit is contained in:
Allan Yang 2018-10-25 13:58:50 +08:00
parent 5309c3389d
commit e71c05707e
3 changed files with 23 additions and 3 deletions

View File

@ -73,7 +73,8 @@ public class LockAndQueue implements LockStatus {
@Override @Override
public boolean hasParentLock(Procedure<?> proc) { public boolean hasParentLock(Procedure<?> proc) {
// TODO: need to check all the ancestors // TODO: need to check all the ancestors. need to passed in the procedures
// to find the ancestors.
return proc.hasParent() && return proc.hasParent() &&
(isLockOwner(proc.getParentProcId()) || isLockOwner(proc.getRootProcId())); (isLockOwner(proc.getParentProcId()) || isLockOwner(proc.getRootProcId()));
} }

View File

@ -992,7 +992,13 @@ public abstract class Procedure<TEnvironment> implements Comparable<Procedure<TE
LOG.debug("{} is already bypassed, skip acquiring lock.", this); LOG.debug("{} is already bypassed, skip acquiring lock.", this);
return; return;
} }
// this can happen if the parent stores the sub procedures but before it can
// release its lock, the master restarts
if (getState() == ProcedureState.WAITING && !holdLock(env)) {
LOG.debug("{} is in WAITING STATE, and holdLock= false, skip acquiring lock.", this);
lockedWhenLoading = false;
return;
}
LOG.debug("{} held the lock before restarting, call acquireLock to restore it.", this); LOG.debug("{} held the lock before restarting, call acquireLock to restore it.", this);
LockState state = acquireLock(env); LockState state = acquireLock(env);
assert state == LockState.LOCK_ACQUIRED; assert state == LockState.LOCK_ACQUIRED;

View File

@ -653,7 +653,20 @@ public class ProcedureExecutor<TEnvironment> {
sendProcedureLoadedNotification(p.getProcId()); sendProcedureLoadedNotification(p.getProcId());
} }
// If the procedure holds the lock, put the procedure in front // If the procedure holds the lock, put the procedure in front
if (p.isLockedWhenLoading()) { // If its parent holds the lock, put the procedure in front
// TODO. Is that possible that its ancestor holds the lock?
// For now, the deepest procedure hierarchy is:
// ModifyTableProcedure -> ReopenTableProcedure ->
// MoveTableProcedure -> Unassign/AssignProcedure
// But ModifyTableProcedure and ReopenTableProcedure won't hold the lock
// So, check parent lock is enough(a tricky case is resovled by HBASE-21384).
// If some one change or add new procedures making 'grandpa' procedure
// holds the lock, but parent procedure don't hold the lock, there will
// be a problem here. We have to check one procedure's ancestors.
// And we need to change LockAndQueue.hasParentLock(Procedure<?> proc) method
// to check all ancestors too.
if (p.isLockedWhenLoading() || (p.hasParent() && procedures
.get(p.getParentProcId()).isLockedWhenLoading())) {
scheduler.addFront(p, false); scheduler.addFront(p, false);
} else { } else {
// if it was not, it can wait. // if it was not, it can wait.