You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sk...@apache.org on 2021/07/01 14:28:39 UTC

[ignite] branch master updated: IGNITE-15033 AssertionError: Unexpected rebalance on rebalanced cluster. Fixes #9211

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

sk0x50 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 5de1bae  IGNITE-15033 AssertionError: Unexpected rebalance on rebalanced cluster. Fixes #9211
5de1bae is described below

commit 5de1baec25cbc830679042f91ce873f033e01acf
Author: Vladislav Pyatkov <vl...@gmail.com>
AuthorDate: Thu Jul 1 17:27:58 2021 +0300

    IGNITE-15033 AssertionError: Unexpected rebalance on rebalanced cluster. Fixes #9211
    
    Signed-off-by: Slava Koptilin <sl...@gmail.com>
---
 .../cache/persistence/GridCacheOffheapManager.java |   2 +-
 .../RestorePartitionStateDuringCheckpointTest.java | 139 +++++++++++++++++++++
 .../IgnitePdsWithIndexingCoreTestSuite.java        |   4 +-
 3 files changed, 143 insertions(+), 2 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
index 8f2b12a..bf88af8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
@@ -397,7 +397,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
     ) throws IgniteCheckedException {
         RowStore rowStore0 = store.rowStore();
 
-        if (rowStore0 != null) {
+        if (rowStore0 != null && (partitionStatesRestored || grp.isLocal())) {
             ((CacheFreeList)rowStore0.freeList()).saveMetadata(grp.statisticsHolderData());
 
             PartitionMetaStorage<SimpleDataRow> partStore = store.partStorage();
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/RestorePartitionStateDuringCheckpointTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/RestorePartitionStateDuringCheckpointTest.java
new file mode 100644
index 0000000..f7a7376
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/RestorePartitionStateDuringCheckpointTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.persistence;
+
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cluster.ClusterState;
+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.IgniteInternalFuture;
+import org.apache.ignite.internal.pagemem.PageIdAllocator;
+import org.apache.ignite.internal.pagemem.PageIdUtils;
+import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
+import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager;
+import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl;
+import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState;
+import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+
+/**
+ * This test restarts a cache during checkpoint.
+ */
+public class RestorePartitionStateDuringCheckpointTest extends GridCommonAbstractTest {
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        return super.getConfiguration(igniteInstanceName)
+            .setDataStorageConfiguration(new DataStorageConfiguration()
+                .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+                    .setMaxSize(200L * 1024 * 1024)
+                    .setPersistenceEnabled(true)));
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void test() throws Exception {
+        IgniteEx ignite0 = startGrids(1);
+
+        ignite0.cluster().state(ClusterState.ACTIVE);
+
+        IgniteCache cache = ignite0.createCache(DEFAULT_CACHE_NAME);
+
+        int partId = ignite0.affinity(DEFAULT_CACHE_NAME).allPartitions(ignite0.localNode())[0];
+
+        log.info("Local partition was determined [node= " + ignite0.name()
+            + ", partId=" + partId + ']');
+
+        int key = F.first(partitionKeys(cache, partId, 1, 0));
+
+        cache.put(key, key);
+
+        GridCacheProcessor cacheProcessor = ignite0.context().cache();
+
+        cacheProcessor.dynamicDestroyCaches(Collections.singleton(DEFAULT_CACHE_NAME), false, false).get();
+
+        assertNull(ignite0.cache(DEFAULT_CACHE_NAME));
+
+        DataRegion region = cacheProcessor.context().database().dataRegion(DataStorageConfiguration.DFLT_DATA_REG_DEFAULT_NAME);
+
+        PageMemoryEx pageMemorySpy = spy((PageMemoryEx)region.pageMemory());
+
+        long partMetaId = PageIdUtils.pageId(partId, PageIdAllocator.FLAG_DATA, 0);
+        int grpId = CU.cacheId(DEFAULT_CACHE_NAME);
+
+        AtomicBoolean checkpointTriggered = new AtomicBoolean(false);
+
+        doAnswer(invocation -> {
+            IgniteCacheOffheapManager.CacheDataStore partDataStore = ((IgniteCacheOffheapManagerImpl)cacheProcessor
+                .cacheGroup(grpId).offheap()).dataStore(partId);
+
+            if (partDataStore.rowStore() != null && checkpointTriggered.compareAndSet(false, true)) {
+                info("Before write lock will be gotten on the partition meta page [pageId=" + invocation.getArgument(2) + ']');
+
+                GridTestUtils.runAsync(() -> {
+                    try {
+                        forceCheckpoint();
+                    }
+                    catch (IgniteCheckedException e) {
+                        log.error("Checkpoint failed", e);
+                    }
+                });
+
+                doSleep(200);
+            }
+
+            return invocation.callRealMethod();
+        }).when(pageMemorySpy).writeLock(eq(grpId), eq(partMetaId), anyLong());
+
+        GridTestUtils.setFieldValue(region, "pageMem", pageMemorySpy);
+
+        IgniteInternalFuture startCacheFut = GridTestUtils.runAsync(() -> {
+            ignite0.createCache(DEFAULT_CACHE_NAME);
+        });
+
+        startCacheFut.get();
+
+        assertTrue(checkpointTriggered.get());
+
+        assertSame(GridDhtPartitionState.OWNING, cacheProcessor.cacheGroup(grpId).topology().localPartition(partId).state());
+    }
+}
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java
index 26e1df4..e974caa 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java
@@ -28,6 +28,7 @@ import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsTxHistor
 import org.apache.ignite.internal.processors.cache.persistence.IgnitePersistenceSequentialCheckpointTest;
 import org.apache.ignite.internal.processors.cache.persistence.IgnitePersistentStoreCacheGroupsTest;
 import org.apache.ignite.internal.processors.cache.persistence.PersistenceDirectoryWarningLoggingTest;
+import org.apache.ignite.internal.processors.cache.persistence.RestorePartitionStateDuringCheckpointTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.IgniteCacheGroupsWithRestartsTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.IgniteLogicalRecoveryTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.IgniteLogicalRecoveryWithParamsTest;
@@ -98,7 +99,8 @@ import org.junit.runners.Suite;
 
     IgniteSequentialNodeCrashRecoveryTest.class,
 
-    IgniteCacheGroupsWithRestartsTest.class
+    IgniteCacheGroupsWithRestartsTest.class,
+    RestorePartitionStateDuringCheckpointTest.class
 })
 public class IgnitePdsWithIndexingCoreTestSuite {
 }