You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by sy...@apache.org on 2017/01/04 07:39:35 UTC
[33/50] [abbrv] hbase git commit: HBASE-17068 Procedure v2 - inherit
region locks (Matteo Bertozzi)
HBASE-17068 Procedure v2 - inherit region locks (Matteo Bertozzi)
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/306ef83c
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/306ef83c
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/306ef83c
Branch: refs/heads/hbase-12439
Commit: 306ef83c9cde9730ae2268db3814d59b936de4c1
Parents: 319ecd8
Author: Michael Stack <st...@apache.org>
Authored: Tue Dec 27 16:17:45 2016 -0800
Committer: Michael Stack <st...@apache.org>
Committed: Tue Dec 27 16:17:45 2016 -0800
----------------------------------------------------------------------
.../procedure/MasterProcedureScheduler.java | 67 ++++++++++++--------
.../procedure/TestMasterProcedureScheduler.java | 43 +++++++++++++
2 files changed, 85 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/306ef83c/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 691442c..3f588ff 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
@@ -412,15 +412,27 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
return exclusiveLockProcIdOwner == procId;
}
- public boolean tryExclusiveLock(final long procIdOwner) {
- assert procIdOwner != Long.MIN_VALUE;
- if (hasExclusiveLock() && !isLockOwner(procIdOwner)) return false;
- exclusiveLockProcIdOwner = procIdOwner;
+ public boolean hasParentLock(final Procedure proc) {
+ return proc.hasParent() &&
+ (isLockOwner(proc.getParentProcId()) || isLockOwner(proc.getRootProcId()));
+ }
+
+ public boolean hasLockAccess(final Procedure proc) {
+ return isLockOwner(proc.getProcId()) || hasParentLock(proc);
+ }
+
+ public boolean tryExclusiveLock(final Procedure proc) {
+ if (hasExclusiveLock()) return hasLockAccess(proc);
+ exclusiveLockProcIdOwner = proc.getProcId();
return true;
}
- private void releaseExclusiveLock() {
- exclusiveLockProcIdOwner = Long.MIN_VALUE;
+ public boolean releaseExclusiveLock(final Procedure proc) {
+ if (isLockOwner(proc.getProcId())) {
+ exclusiveLockProcIdOwner = Long.MIN_VALUE;
+ return true;
+ }
+ return false;
}
public HRegionInfo getRegionInfo() {
@@ -443,7 +455,7 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
public static class TableQueue extends QueueImpl<TableName> {
private final NamespaceQueue namespaceQueue;
- private HashMap<HRegionInfo, RegionEvent> regionEventMap;
+ private HashMap<String, RegionEvent> regionEventMap;
private TableLock tableLock = null;
public TableQueue(TableName tableName, NamespaceQueue namespaceQueue, int priority) {
@@ -476,18 +488,18 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
public synchronized RegionEvent getRegionEvent(final HRegionInfo regionInfo) {
if (regionEventMap == null) {
- regionEventMap = new HashMap<HRegionInfo, RegionEvent>();
+ regionEventMap = new HashMap<String, RegionEvent>();
}
- RegionEvent event = regionEventMap.get(regionInfo);
+ RegionEvent event = regionEventMap.get(regionInfo.getEncodedName());
if (event == null) {
event = new RegionEvent(regionInfo);
- regionEventMap.put(regionInfo, event);
+ regionEventMap.put(regionInfo.getEncodedName(), event);
}
return event;
}
public synchronized void removeRegionEvent(final RegionEvent event) {
- regionEventMap.remove(event.getRegionInfo());
+ regionEventMap.remove(event.getRegionInfo().getEncodedName());
if (regionEventMap.isEmpty()) {
regionEventMap = null;
}
@@ -675,7 +687,7 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
hasXLock = queue.tryZkExclusiveLock(lockManager, procedure.toString());
if (!hasXLock) {
schedLock();
- if (!hasParentLock) queue.releaseExclusiveLock();
+ if (!hasParentLock) queue.releaseExclusiveLock(procedure);
queue.getNamespaceQueue().releaseSharedLock();
addToRunQueue(tableRunQueue, queue);
schedUnlock();
@@ -699,7 +711,7 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
}
schedLock();
- if (!hasParentLock) queue.releaseExclusiveLock();
+ if (!hasParentLock) queue.releaseExclusiveLock(procedure);
queue.getNamespaceQueue().releaseSharedLock();
addToRunQueue(tableRunQueue, queue);
schedUnlock();
@@ -846,11 +858,11 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
assert i == 0 || regionInfo[i] != regionInfo[i-1] : "duplicate region: " + regionInfo[i];
event[i] = queue.getRegionEvent(regionInfo[i]);
- if (!event[i].tryExclusiveLock(procedure.getProcId())) {
+ if (!event[i].tryExclusiveLock(procedure)) {
suspendProcedure(event[i], procedure);
hasLock = false;
while (i-- > 0) {
- event[i].releaseExclusiveLock();
+ event[i].releaseExclusiveLock(procedure);
}
break;
}
@@ -892,12 +904,13 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
assert i == 0 || regionInfo[i] != regionInfo[i-1] : "duplicate region: " + regionInfo[i];
RegionEvent event = queue.getRegionEvent(regionInfo[i]);
- event.releaseExclusiveLock();
- if (event.hasWaitingProcedures()) {
- // release one procedure at the time since regions has an xlock
- nextProcs[numProcs++] = event.popWaitingProcedure(true);
- } else {
- queue.removeRegionEvent(event);
+ if (event.releaseExclusiveLock(procedure)) {
+ if (event.hasWaitingProcedures()) {
+ // release one procedure at the time since regions has an xlock
+ nextProcs[numProcs++] = event.popWaitingProcedure(true);
+ } else {
+ queue.removeRegionEvent(event);
+ }
}
}
}
@@ -960,7 +973,7 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
final TableQueue tableQueue = getTableQueue(TableName.NAMESPACE_TABLE_NAME);
final NamespaceQueue queue = getNamespaceQueue(nsName);
- queue.releaseExclusiveLock();
+ queue.releaseExclusiveLock(procedure);
if (tableQueue.releaseSharedLock()) {
addToRunQueue(tableRunQueue, tableQueue);
}
@@ -1005,7 +1018,7 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
schedLock();
try {
ServerQueue queue = getServerQueue(serverName);
- queue.releaseExclusiveLock();
+ queue.releaseExclusiveLock(procedure);
addToRunQueue(serverRunQueue, queue);
} finally {
schedUnlock();
@@ -1135,8 +1148,12 @@ public class MasterProcedureScheduler extends AbstractProcedureScheduler {
return true;
}
- public synchronized void releaseExclusiveLock() {
- exclusiveLockProcIdOwner = Long.MIN_VALUE;
+ public synchronized boolean releaseExclusiveLock(final Procedure proc) {
+ if (isLockOwner(proc.getProcId())) {
+ exclusiveLockProcIdOwner = Long.MIN_VALUE;
+ return true;
+ }
+ return false;
}
// This should go away when we have the new AM and its events
http://git-wip-us.apache.org/repos/asf/hbase/blob/306ef83c/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestMasterProcedureScheduler.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestMasterProcedureScheduler.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestMasterProcedureScheduler.java
index 776416f..7397168 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestMasterProcedureScheduler.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestMasterProcedureScheduler.java
@@ -543,6 +543,49 @@ public class TestMasterProcedureScheduler {
}
@Test
+ public void testInheritedRegionXLock() {
+ final TableName tableName = TableName.valueOf("testInheritedRegionXLock");
+ final HRegionInfo region = new HRegionInfo(tableName, Bytes.toBytes("a"), Bytes.toBytes("b"));
+
+ queue.addBack(new TestRegionProcedure(1, tableName,
+ TableProcedureInterface.TableOperationType.SPLIT, region));
+ queue.addBack(new TestRegionProcedure(1, 2, tableName,
+ TableProcedureInterface.TableOperationType.UNASSIGN, region));
+ queue.addBack(new TestRegionProcedure(3, tableName,
+ TableProcedureInterface.TableOperationType.REGION_EDIT, region));
+
+ // fetch the root proc and take the lock on the region
+ Procedure rootProc = queue.poll();
+ assertEquals(1, rootProc.getProcId());
+ assertEquals(false, queue.waitRegion(rootProc, region));
+
+ // fetch the sub-proc and take the lock on the region (inherited lock)
+ Procedure childProc = queue.poll();
+ assertEquals(2, childProc.getProcId());
+ assertEquals(false, queue.waitRegion(childProc, region));
+
+ // proc-3 will be fetched but it can't take the lock
+ Procedure proc = queue.poll();
+ assertEquals(3, proc.getProcId());
+ assertEquals(true, queue.waitRegion(proc, region));
+
+ // release the child lock
+ queue.wakeRegion(childProc, region);
+
+ // nothing in the queue (proc-3 is suspended)
+ assertEquals(null, queue.poll(0));
+
+ // release the root lock
+ queue.wakeRegion(rootProc, region);
+
+ // proc-3 should be now available
+ proc = queue.poll();
+ assertEquals(3, proc.getProcId());
+ assertEquals(false, queue.waitRegion(proc, region));
+ queue.wakeRegion(proc, region);
+ }
+
+ @Test
public void testSuspendedProcedure() throws Exception {
final TableName tableName = TableName.valueOf("testSuspendedProcedure");