[ASTERIXDB-1869][MTD][TX] Control Lock size
- user model changes: no
- storage format changes: no
- interface changes: no
details:
- Previously, each lock call to the metadata lock manager increment
the lock counter and create a new Pair<Lock,Mode> object. After
this change, the lock manager checks if the lock was obtained
previously.
Change-Id: Icc884949a824d64fcf27e26c350a2bc0fa496141
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1854
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
BAD: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <hubailmor@gmail.com>
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/DatasetLock.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/DatasetLock.java
index ffcff78..542dd72 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/DatasetLock.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/DatasetLock.java
@@ -18,18 +18,20 @@
*/
package org.apache.asterix.metadata.lock;
+import java.util.Objects;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.apache.asterix.metadata.lock.IMetadataLock.Mode;
import org.apache.asterix.om.base.AMutableInt32;
public class DatasetLock implements IMetadataLock {
- private ReentrantReadWriteLock dsLock;
- private ReentrantReadWriteLock dsModifyLock;
- private AMutableInt32 indexBuildCounter;
+ private final String key;
+ private final ReentrantReadWriteLock dsLock;
+ private final ReentrantReadWriteLock dsModifyLock;
+ private final AMutableInt32 indexBuildCounter;
- public DatasetLock() {
+ public DatasetLock(String key) {
+ this.key = key;
dsLock = new ReentrantReadWriteLock(true);
dsModifyLock = new ReentrantReadWriteLock(true);
indexBuildCounter = new AMutableInt32(0);
@@ -154,4 +156,25 @@
break;
}
}
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof DatasetLock)) {
+ return false;
+ }
+ if (o == this) {
+ return true;
+ }
+ return Objects.equals(key, ((DatasetLock) o).key);
+ }
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/IMetadataLock.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/IMetadataLock.java
index 8af29ba..4d7fa93 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/IMetadataLock.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/IMetadataLock.java
@@ -47,4 +47,11 @@
* lock mode
*/
void release(IMetadataLock.Mode mode);
+
+ /**
+ * Get the lock's key
+ *
+ * @return the key identiying the lock
+ */
+ String getKey();
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/LockList.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/LockList.java
index bb708db..c5c9fe9 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/LockList.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/LockList.java
@@ -19,7 +19,9 @@
package org.apache.asterix.metadata.lock;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.common.exceptions.ErrorCode;
@@ -29,7 +31,8 @@
* The LockList is used for two phase locking.
*/
public class LockList {
- private List<Pair<IMetadataLock.Mode, IMetadataLock>> locks = new ArrayList<>();
+ private final List<Pair<IMetadataLock.Mode, IMetadataLock>> locks = new ArrayList<>();
+ private final Set<String> lockSet = new HashSet<>();
private boolean lockPhase = true;
/**
@@ -44,8 +47,12 @@
if (!lockPhase) {
throw new AsterixException(ErrorCode.COMPILATION_TWO_PHASE_LOCKING_VIOLATION);
}
+ if (lockSet.contains(lock.getKey())) {
+ return;
+ }
lock.acquire(mode);
locks.add(Pair.of(mode, lock));
+ lockSet.add(lock.getKey());
}
/**
@@ -58,6 +65,7 @@
pair.getRight().release(pair.getLeft());
}
locks.clear();
+ lockSet.clear();
lockPhase = false;
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLock.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLock.java
index c8fd64f..6c20e9f 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLock.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLock.java
@@ -18,13 +18,17 @@
*/
package org.apache.asterix.metadata.lock;
+import java.util.Objects;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.apache.asterix.metadata.lock.IMetadataLock.Mode;
-
public class MetadataLock implements IMetadataLock {
+ private final String key;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+ public MetadataLock(String key) {
+ this.key = key;
+ }
+
@Override
public void acquire(IMetadataLock.Mode mode) {
switch (mode) {
@@ -48,4 +52,25 @@
break;
}
}
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof MetadataLock)) {
+ return false;
+ }
+ if (o == this) {
+ return true;
+ }
+ return Objects.equals(key, ((MetadataLock) o).key);
+ }
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLockManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLockManager.java
index 9815f6f..43d72e3 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLockManager.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/lock/MetadataLockManager.java
@@ -29,131 +29,156 @@
public class MetadataLockManager {
public static final MetadataLockManager INSTANCE = new MetadataLockManager();
- private static final Function<String, MetadataLock> LOCK_FUNCTION = key -> new MetadataLock();
- private static final Function<String, DatasetLock> DATASET_LOCK_FUNCTION = key -> new DatasetLock();
+ private static final Function<String, MetadataLock> LOCK_FUNCTION = MetadataLock::new;
+ private static final Function<String, DatasetLock> DATASET_LOCK_FUNCTION = DatasetLock::new;
- private final ConcurrentHashMap<String, MetadataLock> dataversesLocks;
- private final ConcurrentHashMap<String, DatasetLock> datasetsLocks;
- private final ConcurrentHashMap<String, MetadataLock> functionsLocks;
- private final ConcurrentHashMap<String, MetadataLock> nodeGroupsLocks;
- private final ConcurrentHashMap<String, MetadataLock> feedsLocks;
- private final ConcurrentHashMap<String, MetadataLock> feedPolicyLocks;
- private final ConcurrentHashMap<String, MetadataLock> compactionPolicyLocks;
- private final ConcurrentHashMap<String, MetadataLock> dataTypeLocks;
- private final ConcurrentHashMap<String, MetadataLock> extensionLocks;
+ private final ConcurrentHashMap<String, IMetadataLock> mdlocks;
+
+ private static final String DATAVERSE_PREFIX = "Dataverse:";
+ private static final String DATASET_PREFIX = "Dataset:";
+ private static final String FUNCTION_PREFIX = "Function:";
+ private static final String NODE_GROUP_PREFIX = "NodeGroup:";
+ private static final String FEED_PREFIX = "Feed:";
+ private static final String FEED_POLICY_PREFIX = "FeedPolicy:";
+ private static final String MERGE_POLICY_PREFIX = "MergePolicy:";
+ private static final String DATATYPE_PREFIX = "DataType:";
+ private static final String EXTENSION_PREFIX = "Extension:";
private MetadataLockManager() {
- dataversesLocks = new ConcurrentHashMap<>();
- datasetsLocks = new ConcurrentHashMap<>();
- functionsLocks = new ConcurrentHashMap<>();
- nodeGroupsLocks = new ConcurrentHashMap<>();
- feedsLocks = new ConcurrentHashMap<>();
- feedPolicyLocks = new ConcurrentHashMap<>();
- compactionPolicyLocks = new ConcurrentHashMap<>();
- dataTypeLocks = new ConcurrentHashMap<>();
- extensionLocks = new ConcurrentHashMap<>();
+ mdlocks = new ConcurrentHashMap<>();
}
// Dataverse
public void acquireDataverseReadLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = dataversesLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ String key = DATAVERSE_PREFIX + dataverseName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
public void acquireDataverseWriteLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = dataversesLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ String key = DATAVERSE_PREFIX + dataverseName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
// Dataset
public void acquireDatasetReadLock(LockList locks, String datasetName) throws AsterixException {
- DatasetLock lock = datasetsLocks.computeIfAbsent(datasetName, DATASET_LOCK_FUNCTION);
+ String key = DATASET_PREFIX + datasetName;
+ DatasetLock lock = (DatasetLock) mdlocks.computeIfAbsent(key, DATASET_LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
public void acquireDatasetWriteLock(LockList locks, String datasetName) throws AsterixException {
- DatasetLock lock = datasetsLocks.computeIfAbsent(datasetName, DATASET_LOCK_FUNCTION);
+ String key = DATASET_PREFIX + datasetName;
+ DatasetLock lock = (DatasetLock) mdlocks.computeIfAbsent(key, DATASET_LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
public void acquireDatasetModifyLock(LockList locks, String datasetName) throws AsterixException {
- DatasetLock lock = datasetsLocks.computeIfAbsent(datasetName, DATASET_LOCK_FUNCTION);
+ String key = DATASET_PREFIX + datasetName;
+ DatasetLock lock = (DatasetLock) mdlocks.computeIfAbsent(key, DATASET_LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.MODIFY, lock);
}
public void acquireDatasetCreateIndexLock(LockList locks, String datasetName) throws AsterixException {
- DatasetLock lock = datasetsLocks.computeIfAbsent(datasetName, DATASET_LOCK_FUNCTION);
+ String key = DATASET_PREFIX + datasetName;
+ DatasetLock lock = (DatasetLock) mdlocks.computeIfAbsent(key, DATASET_LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.INDEX_BUILD, lock);
}
public void acquireExternalDatasetRefreshLock(LockList locks, String datasetName) throws AsterixException {
- DatasetLock lock = datasetsLocks.computeIfAbsent(datasetName, DATASET_LOCK_FUNCTION);
+ String key = DATASET_PREFIX + datasetName;
+ DatasetLock lock = (DatasetLock) mdlocks.computeIfAbsent(key, DATASET_LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.INDEX_BUILD, lock);
}
// Function
- public void acquireFunctionReadLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = functionsLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireFunctionReadLock(LockList locks, String functionName) throws AsterixException {
+ String key = FUNCTION_PREFIX + functionName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
- public void acquireFunctionWriteLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = functionsLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireFunctionWriteLock(LockList locks, String functionName) throws AsterixException {
+ String key = FUNCTION_PREFIX + functionName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
// Node Group
- public void acquireNodeGroupReadLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = nodeGroupsLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireNodeGroupReadLock(LockList locks, String nodeGroupName) throws AsterixException {
+ String key = NODE_GROUP_PREFIX + nodeGroupName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
public void acquireNodeGroupWriteLock(LockList locks, String nodeGroupName) throws AsterixException {
- MetadataLock lock = nodeGroupsLocks.computeIfAbsent(nodeGroupName, LOCK_FUNCTION);
+ String key = NODE_GROUP_PREFIX + nodeGroupName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
// Feeds
- public void acquireFeedReadLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = feedsLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireFeedReadLock(LockList locks, String feedName) throws AsterixException {
+ String key = FEED_PREFIX + feedName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
- public void acquireFeedWriteLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = feedsLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireFeedWriteLock(LockList locks, String feedName) throws AsterixException {
+ String key = FEED_PREFIX + feedName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
- public void acquireFeedPolicyWriteLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = feedPolicyLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireFeedPolicyWriteLock(LockList locks, String feedPolicyName) throws AsterixException {
+ String key = FEED_POLICY_PREFIX + feedPolicyName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
+ public void acquireFeedPolicyReadLock(LockList locks, String feedPolicyName) throws AsterixException {
+ String key = FEED_POLICY_PREFIX + feedPolicyName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
+ locks.add(IMetadataLock.Mode.READ, lock);
+ }
+
// CompactionPolicy
- public void acquireCompactionPolicyReadLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = compactionPolicyLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireMergePolicyReadLock(LockList locks, String mergePolicyName) throws AsterixException {
+ String key = MERGE_POLICY_PREFIX + mergePolicyName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
+ public void acquireMergePolicyWriteLock(LockList locks, String mergePolicyName) throws AsterixException {
+ String key = MERGE_POLICY_PREFIX + mergePolicyName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
+ locks.add(IMetadataLock.Mode.WRITE, lock);
+ }
+
// DataType
- public void acquireDataTypeReadLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = dataTypeLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireDataTypeReadLock(LockList locks, String datatypeName) throws AsterixException {
+ String key = DATATYPE_PREFIX + datatypeName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
- public void acquireDataTypeWriteLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = dataTypeLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireDataTypeWriteLock(LockList locks, String datatypeName) throws AsterixException {
+ String key = DATATYPE_PREFIX + datatypeName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
// Extensions
- public void acquireExtensionReadLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = extensionLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireExtensionReadLock(LockList locks, String extensionName) throws AsterixException {
+ String key = EXTENSION_PREFIX + extensionName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.READ, lock);
}
- public void acquireExtensionWriteLock(LockList locks, String dataverseName) throws AsterixException {
- MetadataLock lock = extensionLocks.computeIfAbsent(dataverseName, LOCK_FUNCTION);
+ public void acquireExtensionWriteLock(LockList locks, String extensionName) throws AsterixException {
+ String key = EXTENSION_PREFIX + extensionName;
+ IMetadataLock lock = mdlocks.computeIfAbsent(key, LOCK_FUNCTION);
locks.add(IMetadataLock.Mode.WRITE, lock);
}
@@ -178,7 +203,7 @@
acquireNodeGroupReadLock(locks, nodeGroupName);
}
if (!isDefaultCompactionPolicy) {
- acquireCompactionPolicyReadLock(locks, compactionPolicyName);
+ acquireMergePolicyReadLock(locks, compactionPolicyName);
}
acquireDatasetWriteLock(locks, datasetFullyQualifiedName);
}