You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2022/04/18 12:08:20 UTC
[shardingsphere] branch master updated: Fix cluster mode multi-node duplicate lock bug (#16904)
This is an automated email from the ASF dual-hosted git repository.
zhaojinchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 3e1dd2f9efc Fix cluster mode multi-node duplicate lock bug (#16904)
3e1dd2f9efc is described below
commit 3e1dd2f9efca57a5110301e777d6982a2b4b9565
Author: gin <ja...@163.com>
AuthorDate: Mon Apr 18 20:08:11 2022 +0800
Fix cluster mode multi-node duplicate lock bug (#16904)
---
.../infra/lock/ShardingSphereGlobalLock.java | 21 ++++++++++++++-------
.../coordinator/lock/DistributeLockContext.java | 14 +++++---------
.../lock/ShardingSphereDistributeGlobalLock.java | 14 +++++++++++---
.../lock/service/LockRegistryService.java | 11 ++++++++---
.../lock/service/LockRegistryServiceTest.java | 2 +-
5 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/lock/ShardingSphereGlobalLock.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/lock/ShardingSphereGlobalLock.java
index a83473003e7..b2d94acc28a 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/lock/ShardingSphereGlobalLock.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/lock/ShardingSphereGlobalLock.java
@@ -38,13 +38,6 @@ public interface ShardingSphereGlobalLock extends ShardingSphereLock {
*/
void releaseAckLock(String lockName, String instanceId);
- /**
- * Release locked state.
- *
- * @param lockName lock name
- */
- void releaseLockedState(String lockName);
-
/**
* Add locked instance id.
*
@@ -58,4 +51,18 @@ public interface ShardingSphereGlobalLock extends ShardingSphereLock {
* @param instanceId instance id
*/
void removeLockedInstance(String instanceId);
+
+ /**
+ * Release locked state.
+ *
+ * @param lockName lock name
+ */
+ void releaseLockedState(String lockName);
+
+ /**
+ * Refresh owner instance id.
+ *
+ * @param ownerInstanceId owner instance id
+ */
+ void refreshOwner(String ownerInstanceId);
}
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/DistributeLockContext.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/DistributeLockContext.java
index 2f6fdec44a5..342f04c2041 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/DistributeLockContext.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/DistributeLockContext.java
@@ -123,8 +123,8 @@ public final class DistributeLockContext implements LockContext {
return Optional.ofNullable(globalLocks.get(schemaName));
}
- private boolean isSameInstanceId(final String instanceId) {
- return getCurrentInstanceId().equals(instanceId);
+ private boolean isOwnerInstance(final String ownerInstanceId) {
+ return getCurrentInstanceId().equals(ownerInstanceId);
}
/**
@@ -136,7 +136,7 @@ public final class DistributeLockContext implements LockContext {
public synchronized void renew(final LockedEvent event) {
String schema = event.getSchema();
String ownerInstanceId = event.getOwnerInstanceId();
- if (isSameInstanceId(ownerInstanceId)) {
+ if (isOwnerInstance(ownerInstanceId)) {
return;
}
ShardingSphereGlobalLock globalLock = globalLocks.get(schema);
@@ -145,6 +145,7 @@ public final class DistributeLockContext implements LockContext {
globalLocks.put(schema, globalLock);
}
globalLock.ackLock(schema, getCurrentInstanceId());
+ globalLock.refreshOwner(ownerInstanceId);
}
/**
@@ -156,12 +157,7 @@ public final class DistributeLockContext implements LockContext {
public synchronized void renew(final LockReleasedEvent event) {
String schema = event.getSchema();
String ownerInstanceId = event.getOwnerInstanceId();
- if (isSameInstanceId(ownerInstanceId)) {
- ShardingSphereGlobalLock shardingSphereGlobalLock = globalLocks.get(schema);
- if (null == shardingSphereGlobalLock) {
- return;
- }
- shardingSphereGlobalLock.releaseLockedState(schema);
+ if (isOwnerInstance(ownerInstanceId)) {
return;
}
getGlobalLock(schema).ifPresent(shardingSphereGlobalLock -> {
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/ShardingSphereDistributeGlobalLock.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/ShardingSphereDistributeGlobalLock.java
index 0fbfacf40d0..26c673bef60 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/ShardingSphereDistributeGlobalLock.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/ShardingSphereDistributeGlobalLock.java
@@ -140,14 +140,16 @@ public final class ShardingSphereDistributeGlobalLock implements ShardingSphereG
log.debug("releaseLock, state is not locked, ignore, lockName={}", lockName);
return;
}
- lockService.releaseGlobalLock(LockNode.generateGlobalSchemaLocksName(lockName, ownerInstanceId.get()));
String currentInstanceId = getCurrentInstanceId();
if (isOwnerInstanceId(currentInstanceId)) {
- lockedInstances.remove(ownerInstanceId.get());
- ownerInstanceId.set("");
+ lockService.releaseGlobalLock(LockNode.generateGlobalSchemaLocksName(lockName, this.ownerInstanceId.get()), true);
+ lockedInstances.remove(this.ownerInstanceId.get());
+ this.ownerInstanceId.set("");
synchronizedLockState.compareAndSet(LockState.LOCKED, LockState.UNLOCKED);
return;
}
+ lockService.releaseGlobalLock(LockNode.generateGlobalSchemaLockReleasedNodePath(lockName, this.ownerInstanceId.get()), false);
+ ownerInstanceId.set("");
releaseAckLock(lockName, currentInstanceId);
}
@@ -177,6 +179,7 @@ public final class ShardingSphereDistributeGlobalLock implements ShardingSphereG
public void ackLock(final String lockName, final String lockedInstanceId) {
lockService.ackLock(LockNode.generateGlobalSchemaAckLockName(lockName, lockedInstanceId), lockedInstanceId);
lockedInstances.add(lockedInstanceId);
+ synchronizedLockState.compareAndSet(LockState.UNLOCKED, LockState.LOCKED);
}
@Override
@@ -202,4 +205,9 @@ public final class ShardingSphereDistributeGlobalLock implements ShardingSphereG
synchronizedLockState.compareAndSet(LockState.LOCKED, LockState.UNLOCKED);
}
}
+
+ @Override
+ public void refreshOwner(final String ownerInstanceId) {
+ this.ownerInstanceId.set(ownerInstanceId);
+ }
}
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryService.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryService.java
index cc40d2a0186..1696f791179 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryService.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryService.java
@@ -63,12 +63,17 @@ public final class LockRegistryService {
}
/**
- * Release lock.
+ * Release global lock.
*
* @param lockName lock name
+ * @param isOwner is released by lock owner or not
*/
- public void releaseGlobalLock(final String lockName) {
- repository.releaseLock(lockName);
+ public void releaseGlobalLock(final String lockName, final boolean isOwner) {
+ if (isOwner) {
+ repository.releaseLock(lockName);
+ return;
+ }
+ repository.delete(lockName);
}
/**
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryServiceTest.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryServiceTest.java
index 74a17f5962a..d2e292ba92d 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryServiceTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/lock/service/LockRegistryServiceTest.java
@@ -73,7 +73,7 @@ public final class LockRegistryServiceTest {
@Test
public void assertReleaseGlobalLock() {
String schemaLockName = LockNode.generateGlobalSchemaLocksName("schema", "127.0.0.1@3307");
- lockRegistryService.releaseGlobalLock(schemaLockName);
+ lockRegistryService.releaseGlobalLock(schemaLockName, true);
verify(clusterPersistRepository).releaseLock(schemaLockName);
}