Repository: hbase Updated Branches: refs/heads/master 64c701768 -> 837bb9ece
HBASE-18091 Added API for getting who currently holds a lock on namespace/ table/ region/ server and log messages when procedure needs to wait to acquire lock Signed-off-by: Michael Stack <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/837bb9ec Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/837bb9ec Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/837bb9ec Branch: refs/heads/master Commit: 837bb9ece796aee9bc1f82ec45414ea52ac33f80 Parents: 64c7017 Author: Umesh Agashe <[email protected]> Authored: Tue May 23 11:08:33 2017 -0700 Committer: Michael Stack <[email protected]> Committed: Wed May 24 14:56:22 2017 -0700 ---------------------------------------------------------------------- .../hbase/procedure2/ProcedureScheduler.java | 4 ++ .../procedure2/SimpleProcedureScheduler.java | 5 ++ .../procedure/MasterProcedureScheduler.java | 56 +++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/837bb9ec/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java ---------------------------------------------------------------------- diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java index b5295e7..93d0d5d 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java @@ -128,6 +128,10 @@ public interface ProcedureScheduler { List<LockInfo> listLocks(); /** + * @return {@link LockInfo} for resource of specified type & name. null if resource is not locked. + */ + LockInfo getLockInfoForResource(LockInfo.ResourceType resourceType, String resourceName); + /** * Returns the number of elements in this queue. * @return the number of elements in this queue. */ http://git-wip-us.apache.org/repos/asf/hbase/blob/837bb9ec/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java ---------------------------------------------------------------------- diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java index 176a900..f3523ec 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java @@ -81,4 +81,9 @@ public class SimpleProcedureScheduler extends AbstractProcedureScheduler { public List<LockInfo> listLocks() { return Collections.emptyList(); } + + @Override + public LockInfo getLockInfoForResource(LockInfo.ResourceType resourceType, String resourceName) { + return null; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hbase/blob/837bb9ec/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureScheduler.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureScheduler.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureScheduler.java index b0baf85..15b557a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureScheduler.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureScheduler.java @@ -339,6 +339,32 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler { } @Override + public LockInfo getLockInfoForResource(LockInfo.ResourceType resourceType, String resourceName) { + LockAndQueue queue = null; + schedLock(); + try { + switch (resourceType) { + case SERVER: + queue = locking.serverLocks.get(ServerName.valueOf(resourceName)); + break; + case NAMESPACE: + queue = locking.namespaceLocks.get(resourceName); + break; + case TABLE: + queue = locking.tableLocks.get(TableName.valueOf(resourceName)); + break; + case REGION: + queue = locking.regionLocks.get(resourceName); + break; + } + + return queue != null ? createLockInfo(resourceType, resourceName, queue) : null; + } finally { + schedUnlock(); + } + } + + @Override public void clear() { schedLock(); try { @@ -586,6 +612,27 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler { } /** + * Get lock info for a resource of specified type and name and log details + */ + protected void logLockInfoForResource(LockInfo.ResourceType resourceType, String resourceName) { + if (!LOG.isDebugEnabled()) { + return; + } + + LockInfo lockInfo = getLockInfoForResource(resourceType, resourceName); + if (lockInfo != null) { + String msg = resourceType.toString() + " '" + resourceName + "', shared lock count=" + + lockInfo.getSharedLockCount(); + + ProcedureInfo proc = lockInfo.getExclusiveLockOwnerProcedure(); + if (proc != null) { + msg += ", exclusively locked by procId=" + proc.getProcId(); + } + LOG.debug(msg); + } + } + + /** * Suspend the procedure if the specified table is already locked. * Other operations in the table-queue will be executed after the lock is released. * @param procedure the procedure trying to acquire the lock @@ -595,15 +642,18 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler { public boolean waitTableExclusiveLock(final Procedure procedure, final TableName table) { schedLock(); try { - final LockAndQueue namespaceLock = locking.getNamespaceLock(table.getNamespaceAsString()); + final String namespace = table.getNamespaceAsString(); + final LockAndQueue namespaceLock = locking.getNamespaceLock(namespace); final LockAndQueue tableLock = locking.getTableLock(table); if (!namespaceLock.trySharedLock()) { waitProcedure(namespaceLock, procedure); + logLockInfoForResource(LockInfo.ResourceType.NAMESPACE, namespace); return true; } if (!tableLock.tryExclusiveLock(procedure)) { namespaceLock.releaseSharedLock(); waitProcedure(tableLock, procedure); + logLockInfoForResource(LockInfo.ResourceType.TABLE, table.getNameAsString()); return true; } removeFromRunQueue(tableRunQueue, getTableQueue(table)); @@ -856,6 +906,8 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler { locking.getTableLock(TableName.NAMESPACE_TABLE_NAME); if (!systemNamespaceTableLock.trySharedLock()) { waitProcedure(systemNamespaceTableLock, procedure); + logLockInfoForResource(LockInfo.ResourceType.TABLE, + TableName.NAMESPACE_TABLE_NAME.getNameAsString()); return true; } @@ -863,6 +915,7 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler { if (!namespaceLock.tryExclusiveLock(procedure)) { systemNamespaceTableLock.releaseSharedLock(); waitProcedure(namespaceLock, procedure); + logLockInfoForResource(LockInfo.ResourceType.NAMESPACE, namespace); return true; } return false; @@ -915,6 +968,7 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler { return false; } waitProcedure(lock, procedure); + logLockInfoForResource(LockInfo.ResourceType.SERVER, serverName.getServerName()); return true; } finally { schedUnlock();
