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} */