This is an automated email from the ASF dual-hosted git repository.

alexpl 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 907dfd8e2e0 IGNITE-28133 Fix failure on concurrent cache.get() and the 
page eviction - Fixes #12884.
907dfd8e2e0 is described below

commit 907dfd8e2e0c9a3361d1f0294fe93a66554bb740
Author: Vladimir Steshin <[email protected]>
AuthorDate: Mon Mar 16 17:58:44 2026 +0300

    IGNITE-28133 Fix failure on concurrent cache.get() and the page eviction - 
Fixes #12884.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../cache/IgniteCacheOffheapManagerImpl.java       | 13 ++------
 .../evict/FairFifoPageEvictionTracker.java         |  9 ++++--
 .../persistence/evict/NoOpPageEvictionTracker.java |  9 +++---
 .../evict/PageAbstractEvictionTracker.java         |  8 ++++-
 .../persistence/evict/PageEvictionTracker.java     |  9 ++----
 .../evict/Random2LruPageEvictionTracker.java       | 37 ++++++++++++++--------
 .../evict/RandomLruPageEvictionTracker.java        | 26 ++++++++++++---
 7 files changed, 68 insertions(+), 43 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index 3d41f3ad095..48a3328d046 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -1792,22 +1792,13 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
 
             CacheDataRow row = dataTree.findOne(new SearchRow(cacheId, key), 
CacheDataRowAdapter.RowData.NO_KEY);
 
-            afterRowFound(row, key);
-
-            return row;
-        }
-
-        /**
-         * @param row Row.
-         * @param key Key.
-         * @throws IgniteCheckedException If failed.
-         */
-        private void afterRowFound(@Nullable CacheDataRow row, KeyCacheObject 
key) throws IgniteCheckedException {
             if (row != null) {
                 row.key(key);
 
                 grp.dataRegion().evictionTracker().touchPage(row.link());
             }
+
+            return row;
         }
 
         /** {@inheritDoc} */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java
index 84fd0188de3..04454d05acb 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java
@@ -55,7 +55,12 @@ public class FairFifoPageEvictionTracker extends 
PageAbstractEvictionTracker {
     }
 
     /** {@inheritDoc} */
-    @Override public synchronized void touchPage(long pageId) throws 
IgniteCheckedException {
+    @Override protected void initPage(long pageId) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void touchPage(long pageId) {
         pageUsageList.addLast(PageIdUtils.pageIndex(pageId));
     }
 
@@ -65,7 +70,7 @@ public class FairFifoPageEvictionTracker extends 
PageAbstractEvictionTracker {
     }
 
     /** {@inheritDoc} */
-    @Override public synchronized void forgetPage(long pageId) throws 
IgniteCheckedException {
+    @Override public synchronized void forgetPage(long pageId) {
         // No-op.
     }
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java
index d212fcec88b..4409e35e744 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java
@@ -16,7 +16,6 @@
 */
 package org.apache.ignite.internal.processors.cache.persistence.evict;
 
-import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 
 /**
@@ -34,17 +33,17 @@ public class NoOpPageEvictionTracker implements 
PageEvictionTracker {
     }
 
     /** {@inheritDoc} */
-    @Override public void touchPage(long pageId) throws IgniteCheckedException 
{
+    @Override public void touchPage(long pageId) {
         // No-op.
     }
 
     /** {@inheritDoc} */
-    @Override public void evictDataPage() throws IgniteCheckedException {
+    @Override public void evictDataPage() {
         // No-op.
     }
 
     /** {@inheritDoc} */
-    @Override public void forgetPage(long pageId) throws 
IgniteCheckedException {
+    @Override public void forgetPage(long pageId) {
         // No-op.
     }
 
@@ -54,7 +53,7 @@ public class NoOpPageEvictionTracker implements 
PageEvictionTracker {
     }
 
     /** {@inheritDoc} */
-    @Override public void trackFragmentPage(long pageId, long prevPageId, 
boolean isHeadPage) throws IgniteCheckedException {
+    @Override public void trackFragmentPage(long pageId, long prevPageId, 
boolean isHeadPage) {
         // No-op.
     }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java
index 07a97e8e4fb..2330c094266 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java
@@ -185,7 +185,10 @@ public abstract class PageAbstractEvictionTracker 
implements PageEvictionTracker
     }
 
     /** {@inheritDoc} */
-    @Override public void trackFragmentPage(long pageId, long prevPageId, 
boolean isHeadPage) throws IgniteCheckedException {
+    @Override public void trackFragmentPage(long pageId, long prevPageId, 
boolean isHeadPage) {
+        if (isHeadPage)
+            initPage(pageId);
+
         // Do nothing if called for tail page.
         if (prevPageId == 0)
             return;
@@ -200,6 +203,9 @@ public abstract class PageAbstractEvictionTracker 
implements PageEvictionTracker
         }
     }
 
+    /** */
+    protected abstract void initPage(long pageId);
+
     /**
      * Determine tail page tracking index given page id of previously written 
fragment.
      *
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java
index 5954137fc40..82970fb5252 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java
@@ -28,9 +28,8 @@ public interface PageEvictionTracker extends LifecycleAware {
      * Call this method when data page is accessed.
      *
      * @param pageId Page id.
-     * @throws IgniteCheckedException In case of page memory error.
      */
-    public void touchPage(long pageId) throws IgniteCheckedException;
+    public void touchPage(long pageId);
 
     /**
      * Check if page eviction is required according to the configured policy.
@@ -53,9 +52,8 @@ public interface PageEvictionTracker extends LifecycleAware {
      * Call this method when last entry is removed from data page.
      *
      * @param pageId Page id.
-     * @throws IgniteCheckedException In case of page memory error.
      */
-    public void forgetPage(long pageId) throws IgniteCheckedException;
+    public void forgetPage(long pageId);
 
     /**
      * Call this method when data page containing fragment of row is written.
@@ -63,7 +61,6 @@ public interface PageEvictionTracker extends LifecycleAware {
      * @param pageId     Page id.
      * @param prevPageId Page id of previous fragment.  0 if called for the 
tail fragment (written first).
      * @param isHeadPage True if head fragment (written last) of row is 
written, False otherwise.
-     * @throws IgniteCheckedException In case of page memory error.
      */
-    public void trackFragmentPage(long pageId, long prevPageId, boolean 
isHeadPage) throws IgniteCheckedException;
+    public void trackFragmentPage(long pageId, long prevPageId, boolean 
isHeadPage);
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java
index 80634ed878f..01300ffb73f 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java
@@ -80,35 +80,46 @@ public class Random2LruPageEvictionTracker extends 
PageAbstractEvictionTracker {
     }
 
     /** {@inheritDoc} */
-    @Override public void touchPage(long pageId) throws IgniteCheckedException 
{
+    @Override public void touchPage(long pageId) {
         int pageIdx = PageIdUtils.pageIndex(pageId);
-
-        long latestTs = compactTimestamp(U.currentTimeMillis());
-
-        assert latestTs >= 0 && latestTs < Integer.MAX_VALUE;
+        int trackingIdx = trackingIdx(pageIdx);
+        long trackingPtr = trackingArrPtr + trackingIdx * 8L;
 
         boolean success;
 
         do {
-            int trackingIdx = trackingIdx(pageIdx);
-
-            long trackingData = GridUnsafe.getLongVolatile(null, 
trackingArrPtr + trackingIdx * 8L);
+            long trackingData = GridUnsafe.getLongVolatile(null, trackingPtr);
 
             int firstTs = first(trackingData);
 
-            assert firstTs >= 0 : "[firstTs=" + firstTs + ", trackingData=" + 
trackingData + "]";
+            if (firstTs <= 0) // Concurrently evicted.
+                return;
+
+            long ts = compactTimestamp(U.currentTimeMillis());
+
+            assert ts >= 0 && ts < Integer.MAX_VALUE;
 
             int secondTs = second(trackingData);
 
             long newTrackingData;
 
             if (firstTs <= secondTs)
-                newTrackingData = U.toLong((int)latestTs, secondTs);
+                newTrackingData = U.toLong((int)ts, secondTs);
             else
-                newTrackingData = U.toLong(firstTs, (int)latestTs);
+                newTrackingData = U.toLong(firstTs, (int)ts);
+
+            success = GridUnsafe.compareAndSwapLong(null, trackingPtr, 
trackingData, newTrackingData);
+        }
+        while (!success);
+    }
+
+    /** */
+    @Override protected void initPage(long pageId) {
+        int ts = (int)compactTimestamp(U.currentTimeMillis());
+
+        long trackingPtr = trackingArrPtr + 
trackingIdx(PageIdUtils.pageIndex(pageId)) * 8L;
 
-            success = GridUnsafe.compareAndSwapLong(null, trackingArrPtr + 
trackingIdx * 8L, trackingData, newTrackingData);
-        } while (!success);
+        GridUnsafe.compareAndSwapLong(null, trackingPtr, 0, U.toLong(ts, 0));
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java
index cd690e0af73..b940681403c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java
@@ -82,14 +82,30 @@ public class RandomLruPageEvictionTracker extends 
PageAbstractEvictionTracker {
     }
 
     /** {@inheritDoc} */
-    @Override public void touchPage(long pageId) throws IgniteCheckedException 
{
-        int pageIdx = PageIdUtils.pageIndex(pageId);
+    @Override public void touchPage(long pageId) {
+        long trackingPtr = trackingArrPtr + 
trackingIdx(PageIdUtils.pageIndex(pageId)) * 4L;
+
+        boolean success;
+
+        do {
+            int trackingData = GridUnsafe.getIntVolatile(null, trackingPtr);
+
+            if (trackingData <= 0) // Concurrently evicted.
+                return;
+
+            long ts = compactTimestamp(U.currentTimeMillis());
 
-        long res = compactTimestamp(U.currentTimeMillis());
+            assert ts >= 0 && ts < Integer.MAX_VALUE;
+
+            success = GridUnsafe.compareAndSwapInt(null, trackingPtr, 
trackingData, (int)ts);
+        } while (!success);
+    }
 
-        assert res >= 0 && res < Integer.MAX_VALUE;
+    /** */
+    @Override protected void initPage(long pageId) {
+        int ts = (int)compactTimestamp(U.currentTimeMillis());
 
-        GridUnsafe.putIntVolatile(null, trackingArrPtr + trackingIdx(pageIdx) 
* 4L, (int)res);
+        GridUnsafe.compareAndSwapInt(null, trackingArrPtr + 
trackingIdx(PageIdUtils.pageIndex(pageId)) * 4L, 0, ts);
     }
 
     /** {@inheritDoc} */

Reply via email to