Aleksey Plekhanov created IGNITE-25172:
------------------------------------------
Summary: Expired locked tx cache entries are not deleted
Key: IGNITE-25172
URL: https://issues.apache.org/jira/browse/IGNITE-25172
Project: Ignite
Issue Type: Bug
Reporter: Aleksey Plekhanov
For transactional caches expired entries are not deleted if they are locked and
there was attempt to expire.
Reproducer:
{code:java}
@Test
public void testEntriesLeakTx() throws Exception {
IgniteEx srv = startGrid();
IgniteCache<Object, Object> cache = srv.getOrCreateCache(new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL))
.withExpiryPolicy(new CreatedExpiryPolicy(new
Duration(TimeUnit.MILLISECONDS, 100)));
Map<Integer, Integer> map = new TreeMap<>();
for (int i = 0; i < 1_000; i++)
map.put(i, i);
cache.putAll(map);
try (Transaction tx =
srv.transactions().txStart(TransactionConcurrency.PESSIMISTIC,
TransactionIsolation.REPEATABLE_READ)) {
cache.getAll(map.keySet());
doSleep(1_000);
tx.commit();
}
assertEquals(0, cache.size());
} {code}
The same problem also occurs when CDC is trying to insert almost expired
entries to a transactional cache (CDC uses putAllConflict method):
{code:java}
@Test
public void testEntriesLeakCdc() throws Exception {
IgniteEx srv = startGrid();
IgniteCache<Object, Object> cache = srv.getOrCreateCache(new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
IgniteInternalCache<Object, Object> cachex = srv.cachex(DEFAULT_CACHE_NAME);
GridCacheVersion ver = new GridCacheVersion(1, 1, 1, 2);
CacheObjectImpl val = new CacheObjectImpl(1, null);
Map<KeyCacheObject, GridCacheDrInfo> map = new HashMap<>();
for (int i = 0; i < 100_000; i++)
map.put(
new KeyCacheObjectImpl(i, null, -1),
new GridCacheDrExpirationInfo(val, ver, 1, CU.toExpireTime(1)));
cachex.putAllConflict(map);
assertTrue(GridTestUtils.waitForCondition(() -> cache.size() == 0,
10_000L));
} {code}
There is locks check in \{{GridCacheMapEntry#onExpired}} method:
{code:java}
if (mvccExtras() != null)
return false; {code}
Before actual entry remove. Due to this check entry stays in cache, while
{{PendingTree}} entry already removed.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)