You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2018/04/23 07:12:06 UTC
[10/50] [abbrv] ignite git commit: IGNITE-8021 Delete cache config
files when cache is destroyed - Fixes #3697.
IGNITE-8021 Delete cache config files when cache is destroyed - Fixes #3697.
Signed-off-by: Alexey Goncharuk <al...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2edcb22f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2edcb22f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2edcb22f
Branch: refs/heads/ignite-6083
Commit: 2edcb22fbb566981097733af6470ed6dde8e786b
Parents: 1b3a292
Author: Ivan Daschinskiy <iv...@gmail.com>
Authored: Tue Apr 17 18:05:42 2018 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Tue Apr 17 18:05:42 2018 +0300
----------------------------------------------------------------------
.../pagemem/store/IgnitePageStoreManager.java | 9 +
.../processors/cache/GridCacheProcessor.java | 11 +
.../persistence/file/FilePageStoreManager.java | 47 +++
...eConfigurationDataAfterDestroyCacheTest.java | 326 +++++++++++++++++++
.../pagemem/NoOpPageStoreManager.java | 5 +
.../ignite/testsuites/IgnitePdsTestSuite.java | 2 +
6 files changed, 400 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/2edcb22f/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java
index 1b46bf9..0fc9f94 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java
@@ -193,6 +193,15 @@ public interface IgnitePageStoreManager extends GridCacheSharedManager, IgniteCh
* @throws IgniteCheckedException If failed.
*/
public void storeCacheData(StoredCacheData cacheData, boolean overwrite) throws IgniteCheckedException;
+
+ /**
+ * Remove cache configuration data file.
+ *
+ * @param cacheData Cache configuration.
+ * @throws IgniteCheckedException If failed.
+ */
+ public void removeCacheData(StoredCacheData cacheData) throws IgniteCheckedException;
+
/**
* @param grpId Cache group ID.
* @return {@code True} if index store for given cache group existed before node started.
http://git-wip-us.apache.org/repos/asf/ignite/blob/2edcb22f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 36edd72..bceb8c7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -1284,6 +1284,17 @@ public class GridCacheProcessor extends GridProcessorAdapter {
U.stopLifecycleAware(log, lifecycleAwares(ctx.group(), cache.configuration(), ctx.store().configuredStore()));
+ IgnitePageStoreManager pageStore;
+
+ if (destroy && (pageStore = sharedCtx.pageStore()) != null) {
+ try {
+ pageStore.removeCacheData(new StoredCacheData(ctx.config()));
+ } catch (IgniteCheckedException e) {
+ U.error(log, "Failed to delete cache configuration data while destroying cache" +
+ "[cache=" + ctx.name() + "]", e);
+ }
+ }
+
if (log.isInfoEnabled()) {
if (ctx.group().sharedGroup())
log.info("Stopped cache [cacheName=" + cache.name() + ", group=" + ctx.group().name() + ']');
http://git-wip-us.apache.org/repos/asf/ignite/blob/2edcb22f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
index 6313eac..837f3d0 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
+import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
@@ -281,6 +282,9 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
IgniteCheckedException ex = shutdown(old, /*clean files if destroy*/destroy, null);
+ if (destroy)
+ removeCacheGroupConfigurationData(grp);
+
if (ex != null)
throw ex;
}
@@ -746,6 +750,49 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
}
/**
+ * Delete caches' configuration data files of cache group.
+ *
+ * @param ctx Cache group context.
+ * @throws IgniteCheckedException If fails.
+ */
+ private void removeCacheGroupConfigurationData(CacheGroupContext ctx) throws IgniteCheckedException {
+ File cacheGrpDir = cacheWorkDir(ctx.sharedGroup(), ctx.cacheOrGroupName());
+
+ if (cacheGrpDir != null && cacheGrpDir.exists()) {
+ DirectoryStream.Filter<Path> cacheCfgFileFilter = new DirectoryStream.Filter<Path>() {
+ @Override public boolean accept(Path path) {
+ return Files.isRegularFile(path) && path.getFileName().toString().endsWith(CACHE_DATA_FILENAME);
+ }
+ };
+
+ try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(cacheGrpDir.toPath(), cacheCfgFileFilter)) {
+ for(Path path: dirStream)
+ Files.deleteIfExists(path);
+ }
+ catch (IOException e) {
+ throw new IgniteCheckedException("Failed to delete cache configurations of group: " + ctx.toString(), e);
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void removeCacheData(StoredCacheData cacheData) throws IgniteCheckedException {
+ CacheConfiguration cacheCfg = cacheData.config();
+ File cacheWorkDir = cacheWorkDir(cacheCfg);
+ File file;
+
+ if (cacheData.config().getGroupName() != null)
+ file = new File(cacheWorkDir, cacheCfg.getName() + CACHE_DATA_FILENAME);
+ else
+ file = new File(cacheWorkDir, CACHE_DATA_FILENAME);
+
+ if (file.exists()) {
+ if (!file.delete())
+ throw new IgniteCheckedException("Failed to delete cache configuration:" + cacheCfg.getName());
+ }
+ }
+
+ /**
* @param store Store to shutdown.
* @param cleanFile {@code True} if files should be cleaned.
* @param aggr Aggregating exception.
http://git-wip-us.apache.org/repos/asf/ignite/blob/2edcb22f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDeleteCacheConfigurationDataAfterDestroyCacheTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDeleteCacheConfigurationDataAfterDestroyCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDeleteCacheConfigurationDataAfterDestroyCacheTest.java
new file mode 100644
index 0000000..d2767d4
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDeleteCacheConfigurationDataAfterDestroyCacheTest.java
@@ -0,0 +1,326 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+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.processors.cache.GatewayProtectedCacheProxy;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Test correct clean up cache configuration data after destroying cache.
+ */
+public class IgnitePdsDeleteCacheConfigurationDataAfterDestroyCacheTest extends GridCommonAbstractTest {
+ /** */
+ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ private static final int CACHES = 3;
+
+ /** */
+ private static final int NODES = 3;
+
+ /** */
+ private static final int NUM_OF_KEYS = 100;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ return cfg.setDiscoverySpi(new TcpDiscoverySpi()
+ .setIpFinder(IP_FINDER))
+ .setDataStorageConfiguration(new DataStorageConfiguration()
+ .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+ .setMaxSize(200 * 1024 * 1024)
+ .setPersistenceEnabled(true)));
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ cleanPersistenceDir();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ stopAllGrids();
+
+ cleanPersistenceDir();
+
+ super.afterTest();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @returns always {@code true} in order to be able to kill nodes when checkpointer thread hangs.
+ */
+ @Override protected boolean isMultiJvm() {
+ return true;
+ }
+
+ /**
+ * Test destroy non grouped caches.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDestroyCaches() throws Exception {
+ Ignite ignite = startGrids(NODES);
+
+ ignite.cluster().active(true);
+
+ startCachesDynamically(ignite);
+
+ checkDestroyCaches(ignite);
+ }
+
+ /**
+ * Test destroy grouped caches.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDestroyGroupCaches() throws Exception {
+ Ignite ignite = startGrids(NODES);
+
+ ignite.cluster().active(true);
+
+ startGroupCachesDynamically(ignite);
+
+ checkDestroyCaches(ignite);
+ }
+
+ /**
+ * Test destroy caches with disabled checkpoints.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDestroyCachesAbruptlyWithoutCheckpoints() throws Exception {
+ Ignite ignite = startGrids(NODES);
+
+ ignite.cluster().active(true);
+
+ startCachesDynamically(ignite);
+
+ enableCheckpoints(false);
+
+ checkDestroyCachesAbruptly(ignite);
+ }
+
+ /**
+ * Test destroy group caches with disabled checkpoints.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDestroyGroupCachesAbruptlyWithoutCheckpoints() throws Exception {
+ Ignite ignite = startGrids(NODES);
+
+ ignite.cluster().active(true);
+
+ startGroupCachesDynamically(ignite);
+
+ enableCheckpoints(false);
+
+ checkDestroyCachesAbruptly(ignite);
+ }
+
+ /**
+ * Test destroy caches abruptly with checkpoints.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDestroyCachesAbruptly() throws Exception {
+ Ignite ignite = startGrids(NODES);
+
+ ignite.cluster().active(true);
+
+ startCachesDynamically(ignite);
+
+ checkDestroyCachesAbruptly(ignite);
+ }
+
+
+ /**
+ * Test destroy group caches abruptly with checkpoints.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDestroyGroupCachesAbruptly() throws Exception {
+ Ignite ignite = startGrids(NODES);
+
+ ignite.cluster().active(true);
+
+ startGroupCachesDynamically(ignite);
+
+ checkDestroyCachesAbruptly(ignite);
+ }
+
+ /**
+ * @param ignite Ignite.
+ */
+ private void loadCaches(Ignite ignite) {
+ for (int i = 0; i < CACHES; i++) {
+ try (IgniteDataStreamer<Object, Object> s = ignite.dataStreamer(cacheName(i))) {
+ s.allowOverwrite(true);
+
+ for (int j = 0; j < NUM_OF_KEYS; j++)
+ s.addData(j, "cache: " + i + " data: " + j);
+
+ s.flush();
+ }
+ }
+ }
+
+ /**
+ * @param ignite Ignite.
+ */
+ private void checkDestroyCaches(Ignite ignite) throws Exception {
+ loadCaches(ignite);
+
+ log.warning("destroying caches....");
+
+ ignite.cache(cacheName(0)).destroy();
+ ignite.cache(cacheName(1)).destroy();
+
+ assertEquals(CACHES - 2, ignite.cacheNames().size());
+
+ log.warning("Stopping grid");
+
+ stopAllGrids();
+
+ log.warning("Grid stopped");
+
+ log.warning("Starting grid");
+
+ ignite = startGrids(NODES);
+
+ log.warning("Grid started");
+
+ assertEquals("Check that caches don't survived", CACHES - 2, ignite.cacheNames().size());
+
+ for(Ignite ig: G.allGrids()) {
+ IgniteCache cache = ig.cache(cacheName(2));
+
+ for (int j = 0; j < NUM_OF_KEYS; j++)
+ assertNotNull("Check that cache2 contains key: " + j + " node: " + ignite.name(), cache.get(j));
+ }
+ }
+
+
+ /**
+ * @param ignite Ignite instance.
+ */
+ private void checkDestroyCachesAbruptly(Ignite ignite) throws Exception {
+ loadCaches(ignite);
+
+ log.warning("Destroying caches");
+
+ ((GatewayProtectedCacheProxy)ignite.cache(cacheName(0))).destroyAsync();
+ ((GatewayProtectedCacheProxy)ignite.cache(cacheName(1))).destroyAsync();
+
+ log.warning("Stopping grid");
+
+ stopAllGrids();
+
+ log.warning("Grid stopped");
+
+ log.warning("Starting grid");
+
+ startGrids(NODES);
+
+ log.warning("Grid started");
+
+ for(Ignite ig: G.allGrids()) {
+ assertTrue(ig.cacheNames().contains(cacheName(2)));
+
+ IgniteCache cache = ig.cache(cacheName(2));
+
+ for (int j = 0; j < NUM_OF_KEYS; j++)
+ assertNotNull("Check that survived cache cache2 contains key: " + j + " node: " + ig.name(), cache.get(j));
+ }
+ }
+
+ /**
+ * @param ignite Ignite.
+ */
+ private void startCachesDynamically(Ignite ignite) {
+ List<CacheConfiguration> ccfg = new ArrayList<>(CACHES);
+
+ for (int i = 0; i < CACHES; i++)
+ ccfg.add(new CacheConfiguration<>(cacheName(i))
+ .setBackups(1)
+ .setAffinity(new RendezvousAffinityFunction(false, 32)));
+
+ ignite.createCaches(ccfg);
+ }
+
+ /**
+ * @param ignite Ignite instance.
+ */
+ private void startGroupCachesDynamically(Ignite ignite) {
+ List<CacheConfiguration> ccfg = new ArrayList<>(CACHES);
+
+ for (int i = 0; i < CACHES; i++)
+ ccfg.add(new CacheConfiguration<>(cacheName(i))
+ .setGroupName(i % 2 == 0 ? "grp-even" : "grp-odd")
+ .setBackups(1)
+ .setAffinity(new RendezvousAffinityFunction(false, 32)));
+
+ ignite.createCaches(ccfg);
+ }
+
+
+ /**
+ * Generate cache name from idx.
+ *
+ * @param idx Index.
+ */
+ private String cacheName(int idx) {
+ return "cache" + idx;
+ }
+
+ /**
+ * Enable/disable checkpoints on multi JVM nodes only.
+ *
+ * @param enabled Enabled flag.
+ * @throws IgniteCheckedException If failed.
+ */
+ private void enableCheckpoints(boolean enabled) throws IgniteCheckedException {
+ for (Ignite ignite : G.allGrids()) {
+ assert !ignite.cluster().localNode().isClient();
+
+ GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager)((IgniteEx)ignite).context()
+ .cache().context().database();
+
+ dbMgr.enableCheckpoints(enabled).get();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2edcb22f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/NoOpPageStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/NoOpPageStoreManager.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/NoOpPageStoreManager.java
index 64acf02..be40c90 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/NoOpPageStoreManager.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/NoOpPageStoreManager.java
@@ -187,6 +187,11 @@ public class NoOpPageStoreManager implements IgnitePageStoreManager {
}
/** {@inheritDoc} */
+ @Override public void removeCacheData(StoredCacheData cacheData) throws IgniteCheckedException {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
@Override public boolean hasIndexStore(int grpId) {
return false;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2edcb22f/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java
index a9668e7..af0b7ad 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite.java
@@ -19,6 +19,7 @@ package org.apache.ignite.testsuites;
import junit.framework.TestSuite;
import org.apache.ignite.internal.processors.cache.IgniteClusterActivateDeactivateTestWithPersistence;
+import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsDeleteCacheConfigurationDataAfterDestroyCacheTest;
import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsDynamicCacheTest;
import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsSingleNodePutGetPersistenceTest;
import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsCacheRestoreTest;
@@ -113,6 +114,7 @@ public class IgnitePdsTestSuite extends TestSuite {
suite.addTestSuite(IgnitePdsCacheRestoreTest.class);
suite.addTestSuite(IgnitePdsDataRegionMetricsTest.class);
+ suite.addTestSuite(IgnitePdsDeleteCacheConfigurationDataAfterDestroyCacheTest.class);
suite.addTestSuite(DefaultPageSizeBackwardsCompatibilityTest.class);