You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2020/01/30 12:16:01 UTC
[ignite] 01/02: IGNITE-12594 Fix deadlock between
GridCacheDataStore#purgeExpiredInternal and
GridNearTxLocal#enlistWriteEntry - Fixes #7325.
This is an automated email from the ASF dual-hosted git repository.
agoncharuk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
commit 281b41ed6d25d0ea95585ca44ff62095a5135534
Author: Sergey Chugunov <sc...@gridgain.com>
AuthorDate: Thu Jan 30 14:02:22 2020 +0300
IGNITE-12594 Fix deadlock between GridCacheDataStore#purgeExpiredInternal and GridNearTxLocal#enlistWriteEntry - Fixes #7325.
---
.../cache/CacheOffheapEvictionManager.java | 5 ++++
.../processors/cache/GridCacheMapEntry.java | 27 ++++++++++------------
.../distributed/dht/GridPartitionedGetFuture.java | 5 ++++
.../dht/GridPartitionedSingleGetFuture.java | 5 ++++
.../cache/distributed/near/GridNearGetFuture.java | 4 ++++
.../persistence/DistributedMetaStorageImpl.java | 17 ++++++++++----
6 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOffheapEvictionManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOffheapEvictionManager.java
index 6813fec..9da4753 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOffheapEvictionManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOffheapEvictionManager.java
@@ -39,6 +39,8 @@ public class CacheOffheapEvictionManager extends GridCacheManagerAdapter impleme
if (e.detached())
return;
+ cctx.shared().database().checkpointReadLock();
+
try {
boolean evicted = e.evictInternal(GridCacheVersionManager.EVICT_VER, null, false)
|| e.markObsoleteIfEmpty(null);
@@ -49,6 +51,9 @@ public class CacheOffheapEvictionManager extends GridCacheManagerAdapter impleme
catch (IgniteCheckedException ex) {
U.error(log, "Failed to evict entry from cache: " + e, ex);
}
+ finally {
+ cctx.shared().database().checkpointReadUnlock();
+ }
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 5969666..1ad7eec 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -17,6 +17,10 @@
package org.apache.ignite.internal.processors.cache;
+import javax.cache.Cache;
+import javax.cache.expiry.ExpiryPolicy;
+import javax.cache.processor.EntryProcessor;
+import javax.cache.processor.EntryProcessorResult;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -27,10 +31,6 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
-import javax.cache.Cache;
-import javax.cache.expiry.ExpiryPolicy;
-import javax.cache.processor.EntryProcessor;
-import javax.cache.processor.EntryProcessorResult;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
@@ -538,6 +538,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
boolean deferred = false;
GridCacheVersion ver0 = null;
+ cctx.shared().database().checkpointReadLock();
+
lockEntry();
try {
@@ -572,6 +574,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
finally {
unlockEntry();
+
+ cctx.shared().database().checkpointReadUnlock();
}
if (obsolete) {
@@ -4085,17 +4089,10 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (log.isTraceEnabled())
log.trace("onExpired clear [key=" + key + ", entry=" + System.identityHashCode(this) + ']');
- cctx.shared().database().checkpointReadLock();
-
- try {
- if (cctx.mvccEnabled())
- cctx.offheap().mvccRemoveAll(this);
- else
- removeValue();
- }
- finally {
- cctx.shared().database().checkpointReadUnlock();
- }
+ if (cctx.mvccEnabled())
+ cctx.offheap().mvccRemoveAll(this);
+ else
+ removeValue();
if (cctx.events().isRecordable(EVT_CACHE_OBJECT_EXPIRED)) {
cctx.events().addEvent(partition(),
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
index 6ce1863..d1706e1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
@@ -445,6 +445,8 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
boolean evt = !skipVals;
while (true) {
+ cctx.shared().database().checkpointReadLock();
+
try {
boolean skipEntry = readNoEntry;
@@ -572,6 +574,9 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
return true;
}
+ finally {
+ cctx.shared().database().checkpointReadUnlock();
+ }
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
index a82f5b5..08abf5e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
@@ -434,6 +434,8 @@ public class GridPartitionedSingleGetFuture extends GridCacheFutureAdapter<Objec
boolean evt = !skipVals;
while (true) {
+ cctx.shared().database().checkpointReadLock();
+
try {
CacheObject v = null;
GridCacheVersion ver = null;
@@ -560,6 +562,9 @@ public class GridPartitionedSingleGetFuture extends GridCacheFutureAdapter<Objec
return true;
}
+ finally {
+ cctx.shared().database().checkpointReadUnlock();
+ }
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index b082726..d4513b7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@ -483,6 +483,8 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
assert dht.context().affinityNode() : this;
while (true) {
+ cctx.shared().database().checkpointReadLock();
+
GridCacheEntryEx dhtEntry = null;
try {
@@ -558,6 +560,8 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
return false;
}
finally {
+ cctx.shared().database().checkpointReadUnlock();
+
if (dhtEntry != null)
// Near cache is enabled, so near entry will be enlisted in the transaction.
// Always touch DHT entry in this case.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java
index 242c65c..038d830 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java
@@ -273,6 +273,8 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
}
finally {
lock.writeLock().unlock();
+
+ cancelUpdateFutures();
}
}
@@ -874,16 +876,23 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
ver = INITIAL_VERSION;
- for (GridFutureAdapter<Boolean> fut : updateFuts.values())
- fut.onDone(new IgniteCheckedException("Client was disconnected during the operation."));
-
- updateFuts.clear();
+ cancelUpdateFutures();
}
finally {
lock.writeLock().unlock();
}
}
+ /**
+ * Cancel all waiting futures and clear the map.
+ */
+ private void cancelUpdateFutures() {
+ for (GridFutureAdapter<Boolean> fut : updateFuts.values())
+ fut.onDone(new IgniteCheckedException("Client was disconnected during the operation."));
+
+ updateFuts.clear();
+ }
+
/** {@inheritDoc} */
@Override public IgniteInternalFuture<?> onReconnected(boolean clusterRestarted) {
assert isClient;