You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by al...@apache.org on 2024/04/12 07:03:57 UTC

(ignite) branch master updated: IGNITE-21961 Fix entries cleaning on node shutdown/deactivation for in-memory mode - Fixes #11302.

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 327df73416b IGNITE-21961 Fix entries cleaning on node shutdown/deactivation for in-memory mode - Fixes #11302.
327df73416b is described below

commit 327df73416b310fc1704f24507df864c1632306f
Author: Aleksey Plekhanov <pl...@gmail.com>
AuthorDate: Fri Apr 12 09:57:13 2024 +0300

    IGNITE-21961 Fix entries cleaning on node shutdown/deactivation for in-memory mode - Fixes #11302.
    
    Signed-off-by: Aleksey Plekhanov <pl...@gmail.com>
---
 .../cache/IgniteCacheOffheapManagerImpl.java       |  19 +++
 .../cache/EntriesRemoveOnShutdownTest.java         | 137 +++++++++++++++++++++
 .../ignite/testsuites/IgniteCacheTestSuite13.java  |   2 +
 3 files changed, 158 insertions(+)

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 754aeeee880..9ba25c751b9 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
@@ -37,8 +37,11 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.cluster.ClusterState;
 import org.apache.ignite.failure.FailureContext;
 import org.apache.ignite.failure.FailureType;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.GridKernalState;
 import org.apache.ignite.internal.NodeStoppingException;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -197,6 +200,22 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
 
     /** {@inheritDoc} */
     @Override public void stop() {
+        GridKernalContext kctx = ctx.kernalContext();
+
+        // For in-memory mode, if we stop caches on grid stopping or cluster deactivation, skip data deletion from
+        // the trees and just close trees to release resources.
+        if (kctx.gateway().getState() == GridKernalState.STOPPING
+            || kctx.state().clusterState().state() == ClusterState.INACTIVE) {
+            for (CacheDataStore store : cacheDataStores())
+                store.tree().close();
+
+            if (pendingEntries != null)
+                pendingEntries.close();
+
+            return;
+        }
+
+        // In other cases (cache stop, for example) perform destroy with data deletion (through tree iteration).
         try {
             for (CacheDataStore store : cacheDataStores())
                 destroyCacheDataStore(store);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/EntriesRemoveOnShutdownTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/EntriesRemoveOnShutdownTest.java
new file mode 100644
index 00000000000..25e1211e2ed
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/EntriesRemoveOnShutdownTest.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * Tests entries removal after shutdown/deactivation on in-memory/persistence grid.
+ */
+@RunWith(Parameterized.class)
+public class EntriesRemoveOnShutdownTest extends GridCommonAbstractTest {
+    /** Persistence. */
+    @Parameterized.Parameter
+    public boolean pds;
+
+    /** Is any entry removed from the cache. */
+    AtomicBoolean removed = new AtomicBoolean();
+
+    /** Ignite instance. */
+    IgniteEx ignite;
+
+    /** @return Test parameters. */
+    @Parameterized.Parameters(name = "pds={0}")
+    public static Collection<?> parameters() {
+        return F.asList(true, false);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        return super.getConfiguration(igniteInstanceName).setDataStorageConfiguration(
+            new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration().setPersistenceEnabled(pds)));
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        removed.set(false);
+
+        ignite = startGrid();
+
+        ignite.cluster().state(ClusterState.ACTIVE);
+
+        ignite.getOrCreateCache(new CacheConfiguration<Integer, String>("cache0"));
+
+        // Create two caches in the same group.
+        ignite.getOrCreateCache(new CacheConfiguration<Integer, String>("cache1").setGroupName("grp"));
+        ignite.getOrCreateCache(new CacheConfiguration<Integer, String>("cache2").setGroupName("grp"));
+
+        for (String cacheName : ignite.cacheNames()) {
+            for (int i = 0; i < 1000; i++)
+                ignite.cache(cacheName).put(i, "Test" + i);
+        }
+
+        for (String cacheName : ignite.cacheNames()) {
+            // Inject row cleaner to know about physical rows removal.
+            IgniteCacheOffheapManager offheap = ignite.context().cache().cache(cacheName).context().offheap();
+            for (IgniteCacheOffheapManager.CacheDataStore ds : offheap.cacheDataStores())
+                ds.setRowCacheCleaner(r -> removed.set(true));
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+        stopAllGrids();
+    }
+
+    /** */
+    @Test
+    public void testShutdown() {
+        ignite.close();
+
+        assertFalse(removed.get());
+    }
+
+    /** */
+    @Test
+    public void testDeactivate() {
+        ignite.cluster().state(ClusterState.INACTIVE);
+
+        assertFalse(removed.get());
+    }
+
+    /** */
+    @Test
+    public void testCacheGroupDestroy() throws Exception {
+        ignite.destroyCache("cache0");
+
+        // For pds entire cache group can be dropped on checkpoint, we don't need to remove entries one by one
+        if (pds) {
+            forceCheckpoint();
+            assertFalse(removed.get());
+        }
+        else
+            assertTrue(removed.get());
+    }
+
+    /** */
+    @Test
+    public void testCacheDestroy() throws Exception {
+        ignite.destroyCache("cache1");
+
+        if (pds)
+            forceCheckpoint();
+
+        assertTrue(removed.get());
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
index 5d0b8fbdba2..7cbde83ce01 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
@@ -36,6 +36,7 @@ import org.apache.ignite.internal.metric.SystemViewComputeJobTest;
 import org.apache.ignite.internal.metric.SystemViewSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheClearAsyncDeadlockTest;
 import org.apache.ignite.internal.processors.cache.CacheDistributedGetLongRunningFutureDumpTest;
+import org.apache.ignite.internal.processors.cache.EntriesRemoveOnShutdownTest;
 import org.apache.ignite.internal.processors.cache.GridCacheDataTypesCoverageTest;
 import org.apache.ignite.internal.processors.cache.GridCacheLongRunningTransactionDiagnosticsTest;
 import org.apache.ignite.internal.processors.cache.GridCacheVersionGenerationWithCacheStorageTest;
@@ -113,6 +114,7 @@ public class IgniteCacheTestSuite13 {
         GridTestUtils.addTestIfNeeded(suite, ContinuousQueryBuffersCleanupTest.class, ignoredTests);
 
         GridTestUtils.addTestIfNeeded(suite, CacheDistributedGetLongRunningFutureDumpTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, EntriesRemoveOnShutdownTest.class, ignoredTests);
 
         return suite;
     }