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 <schugu...@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;