This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new ad5f17c7db7 IGNITE-28653 Fix failure on remove from PDS expired
entries for onheap cache/near cache - Fixes #13117.
ad5f17c7db7 is described below
commit ad5f17c7db7daa3739a162522c312613974269d2
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Fri May 8 15:26:11 2026 +0300
IGNITE-28653 Fix failure on remove from PDS expired entries for onheap
cache/near cache - Fixes #13117.
Signed-off-by: Aleksey Plekhanov <[email protected]>
---
.../processors/cache/GridCacheMapEntry.java | 24 +++++++++--
.../cache/persistence/db/IgnitePdsWithTtlTest.java | 49 ++++++++++++++++++++++
2 files changed, 70 insertions(+), 3 deletions(-)
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 da6f47073df..b3af6e7b4d9 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
@@ -2308,9 +2308,10 @@ public abstract class GridCacheMapEntry extends
GridMetadataAwareAdapter impleme
boolean heap,
boolean offheap,
AffinityTopologyVersion topVer,
- @Nullable IgniteCacheExpiryPolicy expiryPlc)
- throws GridCacheEntryRemovedException, IgniteCheckedException {
+ @Nullable IgniteCacheExpiryPolicy expiryPlc
+ ) throws GridCacheEntryRemovedException, IgniteCheckedException {
assert heap || offheap;
+ assert cctx.shared().database().checkpointLockIsHeldByThread();
boolean rmv = false;
@@ -2377,7 +2378,17 @@ public abstract class GridCacheMapEntry extends
GridMetadataAwareAdapter impleme
AffinityTopologyVersion topVer = tx != null ? tx.topologyVersion() :
cctx.affinity().affinityTopologyVersion();
- return peek(true, false, topVer, null);
+ assert cctx.shared().database().checkpointLockIsHeldByThread() ||
!lockedByCurrentThread() :
+ "Lock order violation, checkpoint lock must be acquired before
entry lock";
+
+ cctx.shared().database().checkpointReadLock();
+
+ try {
+ return peek(true, false, topVer, null);
+ }
+ finally {
+ cctx.shared().database().checkpointReadUnlock();
+ }
}
/**
@@ -3790,6 +3801,11 @@ public abstract class GridCacheMapEntry extends
GridMetadataAwareAdapter impleme
public final boolean visitable(CacheEntryPredicate[] filter) {
boolean rmv = false;
+ assert cctx.shared().database().checkpointLockIsHeldByThread() ||
!lockedByCurrentThread() :
+ "Lock order violation, checkpoint lock must be acquired before
entry lock";
+
+ cctx.shared().database().checkpointReadLock();
+
try {
lockEntry();
@@ -3826,6 +3842,8 @@ public abstract class GridCacheMapEntry extends
GridMetadataAwareAdapter impleme
return false;
}
finally {
+ cctx.shared().database().checkpointReadUnlock();
+
if (rmv) {
onMarkedObsolete();
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
index 2b397a34d96..13e231d7ebc 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.WithSystemProperty;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
import org.junit.Test;
import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
@@ -484,6 +485,54 @@ public class IgnitePdsWithTtlTest extends
GridCommonAbstractTest {
assertFalse("Failure handler should not be triggered.",
failureHndTriggered);
}
+ /** */
+ @Test
+ public void testNearCacheExpiredEntriesIteration() throws Exception {
+ IgniteEx srv = startGrids(2);
+ srv.cluster().state(ACTIVE);
+
+ IgniteCache<Object, Object> cache = srv.getOrCreateCache(new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
+ .setNearConfiguration(new NearCacheConfiguration<>())
+ .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new
Duration(TimeUnit.MILLISECONDS, 1)))
+ .setEagerTtl(false)
+ );
+
+ for (int i = 0; i < 100; i++)
+ cache.put(i, "val");
+
+ doSleep(10); // Wait for expiration.
+
+ cache.clear();
+
+ assertEquals(0, cache.size());
+ }
+
+ /** */
+ @Test
+ public void testReplaceExpiredOnheapEntriesUnderTx() throws Exception {
+ IgniteEx srv = startGrid(0);
+ srv.cluster().state(ACTIVE);
+
+ IgniteCache<Object, Object> cache = srv.getOrCreateCache(new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
+ .setOnheapCacheEnabled(true)
+ .setAtomicityMode(TRANSACTIONAL)
+ .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new
Duration(TimeUnit.MILLISECONDS, 1)))
+ .setEagerTtl(false)
+ );
+
+ cache.put(0, "val");
+
+ doSleep(10); // Wait for expiration.
+
+ try (Transaction tx = srv.transactions().txStart()) {
+ cache.replace(0, "val", "val1");
+
+ tx.commit();
+ }
+
+ assertNull(cache.get(0)); // Expired.
+ }
+
/**
*
*/