[ https://issues.apache.org/jira/browse/IGNITE-16922?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Denis Chudov updated IGNITE-16922: ---------------------------------- Description: {{IgniteCache#get(key)}} operation causes {{IgniteOutOfMemoryException}} if {{AccessedExpiryPolicy}} or {{TouchedExpiryPolicy}} is enabled for the {{key}} and Ignite has not enough storage for another entry of the same or bigger size. This happens because: # Ignite needs to update TTL # TTL is part of the entry and Ignite overwrites full entry to update the TTL # The problem is Ignite runs common code that checks if Ignite has enough storage to write the entry with updated TTL back. The check fails causing the {{IgniteCache#get(key)}} operation to throw {{IgniteOutOfMemoryException}}. # This behavior is very confusing for Ignite users: why would a "read" operation throw Ignite OOM? Can we update the TTL atomically and skip the storage size check? Please enhance Ignite not to throw Ignite OOM on {{get}}. Stack trace: {code:java} [2022-05-20 15:08:20,025][ERROR][sys-stripe-6-#8%ignite.IgniteOOMOnGet0%][IgniteTestResources] Critical system error detected. Will be handled accordingly to configured handler [hnd=NoOpFailureHandler [super=AbstractFailureHandler [ignoredFailureTypes=UnmodifiableSet [SYSTEM_WORKER_BLOCKED, SYSTEM_CRITICAL_OPERATION_TIMEOUT]]], failureCtx=FailureContext [type=CRITICAL_ERROR, err=class o.a.i.i.mem.IgniteOutOfMemoryException: Out of memory in data region [name=default, initSize=18.1 MiB, maxSize=18.1 MiB, persistenceEnabled=false] Try the following: ^-- Increase maximum off-heap memory size (DataRegionConfiguration.maxSize) ^-- Enable Ignite persistence (DataRegionConfiguration.persistenceEnabled) ^-- Enable eviction or expiration policies]] class org.apache.ignite.internal.mem.IgniteOutOfMemoryException: Out of memory in data region [name=default, initSize=18.1 MiB, maxSize=18.1 MiB, persistenceEnabled=false] Try the following: ^-- Increase maximum off-heap memory size (DataRegionConfiguration.maxSize) ^-- Enable Ignite persistence (DataRegionConfiguration.persistenceEnabled) ^-- Enable eviction or expiration policies at org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.ensureFreeSpaceForInsert(IgniteCacheDatabaseSharedManager.java:1234) at org.apache.ignite.internal.processors.cache.persistence.RowStore.addRow(RowStore.java:108) at org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.createRow(IgniteCacheOffheapManagerImpl.java:1962) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry$UpdateClosure.call(GridCacheMapEntry.java:5767) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry$UpdateClosure.call(GridCacheMapEntry.java:5695) at org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.invokeClosure(BPlusTree.java:4131) at org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invokeDown(BPlusTree.java:2121) at org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1997) at org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke0(IgniteCacheOffheapManagerImpl.java:1860) at org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke(IgniteCacheOffheapManagerImpl.java:1843) at org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl.invoke(IgniteCacheOffheapManagerImpl.java:471) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.storeValue(GridCacheMapEntry.java:4164) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.storeValue(GridCacheMapEntry.java:4140) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.updateTtl(GridCacheMapEntry.java:2961) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.updateTtl(GridCacheMapEntry.java:2934) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerGet0(GridCacheMapEntry.java:825) at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerGetVersioned(GridCacheMapEntry.java:704) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.getAllAsync0(GridDhtCacheAdapter.java:851) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.getDhtAllAsync(GridDhtCacheAdapter.java:691) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.getAsync(GridDhtGetSingleFuture.java:413) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.map0(GridDhtGetSingleFuture.java:289) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.map(GridDhtGetSingleFuture.java:270) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.init(GridDhtGetSingleFuture.java:186) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.getDhtSingleAsync(GridDhtCacheAdapter.java:1156) at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.processNearSingleGetRequest(GridDhtCacheAdapter.java:1174) at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.access$200(GridDhtAtomicCache.java:151) at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$4.apply(GridDhtAtomicCache.java:278) at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$4.apply(GridDhtAtomicCache.java:273) at org.apache.ignite.internal.processors.cache.GridCacheIoManager.processMessage(GridCacheIoManager.java:1150) at org.apache.ignite.internal.processors.cache.GridCacheIoManager.onMessage0(GridCacheIoManager.java:591) at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:392) at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:318) at org.apache.ignite.internal.processors.cache.GridCacheIoManager$1.onMessage(GridCacheIoManager.java:308) at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1727) at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:1334) at org.apache.ignite.internal.managers.communication.GridIoManager$8.execute(GridIoManager.java:1218) at org.apache.ignite.internal.managers.communication.TraceRunnable.run(TraceRunnable.java:54) at org.apache.ignite.internal.util.StripedExecutor$Stripe.body(StripedExecutor.java:567) at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:119) at java.base/java.lang.Thread.run(Thread.java:833) {code} was: {{IgniteCache#get(key)}} operation causes {{IgniteOutOfMemoryException}} if {{AccessedExpiryPolicy}} or {{TouchedExpiryPolicy}} is enabled for the {{key}} and Ignite has not enough storage for another entry of the same or bigger size. This happens because: # Ignite needs to update TTL # TTL is part of the entry and Ignite overwrites full entry to update the TTL # The problem is Ignite runs common code that checks if Ignite has enough storage to write the entry with updated TTL back. The check fails causing the {{IgniteCache#get(key)}} operation to throw {{IgniteOutOfMemoryException}}. # This behavior is very confusing for Ignite users: why would a "read" operation throw Ignite OOM? Can we update the TTL atomically and skip the storage size check? Please enhance Ignite not to throw Ignite OOM on {{get}}. > Getting an entry with expiry policy causes IgniteOutOfMemoryException > --------------------------------------------------------------------- > > Key: IGNITE-16922 > URL: https://issues.apache.org/jira/browse/IGNITE-16922 > Project: Ignite > Issue Type: Bug > Affects Versions: 2.13 > Reporter: Alexey Kukushkin > Priority: Major > Labels: cggg > Original Estimate: 64h > Remaining Estimate: 64h > > {{IgniteCache#get(key)}} operation causes {{IgniteOutOfMemoryException}} if > {{AccessedExpiryPolicy}} or {{TouchedExpiryPolicy}} is enabled for the > {{key}} and Ignite has not enough storage for another entry of the same or > bigger size. > This happens because: > # Ignite needs to update TTL > # TTL is part of the entry and Ignite overwrites full entry to update the TTL > # The problem is Ignite runs common code that checks if Ignite has enough > storage to write the entry with updated TTL back. The check fails causing the > {{IgniteCache#get(key)}} operation to throw {{IgniteOutOfMemoryException}}. > # This behavior is very confusing for Ignite users: why would a "read" > operation throw Ignite OOM? > Can we update the TTL atomically and skip the storage size check? > Please enhance Ignite not to throw Ignite OOM on {{get}}. > Stack trace: > {code:java} > [2022-05-20 > 15:08:20,025][ERROR][sys-stripe-6-#8%ignite.IgniteOOMOnGet0%][IgniteTestResources] > Critical system error detected. Will be handled accordingly to configured > handler [hnd=NoOpFailureHandler [super=AbstractFailureHandler > [ignoredFailureTypes=UnmodifiableSet [SYSTEM_WORKER_BLOCKED, > SYSTEM_CRITICAL_OPERATION_TIMEOUT]]], failureCtx=FailureContext > [type=CRITICAL_ERROR, err=class o.a.i.i.mem.IgniteOutOfMemoryException: Out > of memory in data region [name=default, initSize=18.1 MiB, maxSize=18.1 MiB, > persistenceEnabled=false] Try the following: > ^-- Increase maximum off-heap memory size (DataRegionConfiguration.maxSize) > ^-- Enable Ignite persistence (DataRegionConfiguration.persistenceEnabled) > ^-- Enable eviction or expiration policies]] > class org.apache.ignite.internal.mem.IgniteOutOfMemoryException: Out of > memory in data region [name=default, initSize=18.1 MiB, maxSize=18.1 MiB, > persistenceEnabled=false] Try the following: > ^-- Increase maximum off-heap memory size (DataRegionConfiguration.maxSize) > ^-- Enable Ignite persistence (DataRegionConfiguration.persistenceEnabled) > ^-- Enable eviction or expiration policies > at > org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.ensureFreeSpaceForInsert(IgniteCacheDatabaseSharedManager.java:1234) > at > org.apache.ignite.internal.processors.cache.persistence.RowStore.addRow(RowStore.java:108) > at > org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.createRow(IgniteCacheOffheapManagerImpl.java:1962) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry$UpdateClosure.call(GridCacheMapEntry.java:5767) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry$UpdateClosure.call(GridCacheMapEntry.java:5695) > at > org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.invokeClosure(BPlusTree.java:4131) > at > org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invokeDown(BPlusTree.java:2121) > at > org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1997) > at > org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke0(IgniteCacheOffheapManagerImpl.java:1860) > at > org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke(IgniteCacheOffheapManagerImpl.java:1843) > at > org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl.invoke(IgniteCacheOffheapManagerImpl.java:471) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry.storeValue(GridCacheMapEntry.java:4164) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry.storeValue(GridCacheMapEntry.java:4140) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry.updateTtl(GridCacheMapEntry.java:2961) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry.updateTtl(GridCacheMapEntry.java:2934) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerGet0(GridCacheMapEntry.java:825) > at > org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerGetVersioned(GridCacheMapEntry.java:704) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.getAllAsync0(GridDhtCacheAdapter.java:851) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.getDhtAllAsync(GridDhtCacheAdapter.java:691) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.getAsync(GridDhtGetSingleFuture.java:413) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.map0(GridDhtGetSingleFuture.java:289) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.map(GridDhtGetSingleFuture.java:270) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture.init(GridDhtGetSingleFuture.java:186) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.getDhtSingleAsync(GridDhtCacheAdapter.java:1156) > at > org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.processNearSingleGetRequest(GridDhtCacheAdapter.java:1174) > at > org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.access$200(GridDhtAtomicCache.java:151) > at > org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$4.apply(GridDhtAtomicCache.java:278) > at > org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$4.apply(GridDhtAtomicCache.java:273) > at > org.apache.ignite.internal.processors.cache.GridCacheIoManager.processMessage(GridCacheIoManager.java:1150) > at > org.apache.ignite.internal.processors.cache.GridCacheIoManager.onMessage0(GridCacheIoManager.java:591) > at > org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:392) > at > org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:318) > at > org.apache.ignite.internal.processors.cache.GridCacheIoManager$1.onMessage(GridCacheIoManager.java:308) > at > org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1727) > at > org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:1334) > at > org.apache.ignite.internal.managers.communication.GridIoManager$8.execute(GridIoManager.java:1218) > at > org.apache.ignite.internal.managers.communication.TraceRunnable.run(TraceRunnable.java:54) > at > org.apache.ignite.internal.util.StripedExecutor$Stripe.body(StripedExecutor.java:567) > at > org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:119) > at java.base/java.lang.Thread.run(Thread.java:833) > {code} -- This message was sent by Atlassian Jira (v8.20.7#820007)