You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2023/07/28 23:26:46 UTC
[ignite] 03/06: IGNITE-19950 Save metadata implemented
This is an automated email from the ASF dual-hosted git repository.
nizhikov pushed a commit to branch IGNITE-19950-snapshot-merge
in repository https://gitbox.apache.org/repos/asf/ignite.git
commit 7300b472a518a665ed1021a7d636d65b8feaea06
Author: nizhikov <ni...@apache.org>
AuthorDate: Thu Jul 27 18:35:28 2023 +0300
IGNITE-19950 Save metadata implemented
---
.../processors/cache/GridLocalConfigManager.java | 8 ++-
.../cache/binary/BinaryMetadataFileStore.java | 19 +++----
.../binary/CacheObjectBinaryProcessorImpl.java | 11 ++--
.../snapshot/IgniteSnapshotManager.java | 29 +++++------
.../snapshot/dump/DumpCacheFutureTask.java | 58 ++++++++++++++++++++--
.../snapshot/IgniteCacheDumpSelfTest.java | 34 ++++++++++++-
6 files changed, 122 insertions(+), 37 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridLocalConfigManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridLocalConfigManager.java
index 846d7128a99..4a6917e1a04 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridLocalConfigManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridLocalConfigManager.java
@@ -541,8 +541,12 @@ public class GridLocalConfigManager {
public File cacheConfigurationFile(CacheConfiguration<?, ?> ccfg) {
File cacheWorkDir = cacheWorkDir(ccfg);
- return ccfg.getGroupName() == null ? new File(cacheWorkDir, CACHE_DATA_FILENAME) :
- new File(cacheWorkDir, ccfg.getName() + CACHE_DATA_FILENAME);
+ return new File(cacheWorkDir, cachDataFilename(ccfg));
+ }
+
+ /** @return Name of cache data filename. */
+ public static String cachDataFilename(CacheConfiguration<?, ?> ccfg) {
+ return ccfg.getGroupName() == null ? CACHE_DATA_FILENAME : (ccfg.getName() + CACHE_DATA_FILENAME);
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
index b994c4b7d06..fa20227d21b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
@@ -87,32 +87,33 @@ class BinaryMetadataFileStore {
final ConcurrentMap<Integer, BinaryMetadataHolder> metadataLocCache,
final GridKernalContext ctx,
final IgniteLogger log,
- final File binaryMetadataFileStoreDir
+ final File binaryMetadataFileStoreDir,
+ final boolean forceEnabled
) throws IgniteCheckedException {
this.metadataLocCache = metadataLocCache;
this.ctx = ctx;
- enabled = CU.isPersistenceEnabled(ctx.config()) || CU.isCdcEnabled(ctx.config());
+ enabled = forceEnabled || CU.isPersistenceEnabled(ctx.config()) || CU.isCdcEnabled(ctx.config());
this.log = log;
- if (!enabled)
- return;
-
- fileIOFactory = ctx.config().getDataStorageConfiguration().getFileIOFactory();
+ DataStorageConfiguration dsCfg = ctx.config().getDataStorageConfiguration();
- final String nodeFolderName = ctx.pdsFolderResolver().resolveFolders().folderName();
+ fileIOFactory = dsCfg == null ? new DataStorageConfiguration().getFileIOFactory() : dsCfg.getFileIOFactory();
if (binaryMetadataFileStoreDir != null)
metadataDir = binaryMetadataFileStoreDir;
- else
+ else {
+ final String nodeFolderName = ctx.pdsFolderResolver().resolveFolders().folderName();
+
metadataDir = new File(U.resolveWorkDirectory(
ctx.config().getWorkDirectory(),
DataStorageConfiguration.DFLT_BINARY_METADATA_PATH,
false
), nodeFolderName);
- fixLegacyFolder(nodeFolderName);
+ fixLegacyFolder(nodeFolderName);
+ }
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index db8bb33c8b4..7ca52e66449 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -261,7 +261,8 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
CU.isPersistenceEnabled(ctx.config()) && binaryMetadataFileStoreDir == null ?
resolveBinaryWorkDir(ctx.config().getWorkDirectory(),
ctx.pdsFolderResolver().resolveFolders().folderName()) :
- binaryMetadataFileStoreDir);
+ binaryMetadataFileStoreDir,
+ false);
metadataFileStore.start();
}
@@ -1019,7 +1020,9 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
ctx,
log,
resolveBinaryWorkDir(dir.getAbsolutePath(),
- ctx.pdsFolderResolver().resolveFolders().folderName()));
+ ctx.pdsFolderResolver().resolveFolders().folderName()),
+ true
+ );
for (BinaryType type : types)
writer.mergeAndWriteMetadata(((BinaryTypeImpl)type).metadata());
@@ -1037,7 +1040,7 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
try {
ConcurrentMap<Integer, BinaryMetadataHolder> metaCache = new ConcurrentHashMap<>();
- new BinaryMetadataFileStore(metaCache, ctx, log, metadataDir)
+ new BinaryMetadataFileStore(metaCache, ctx, log, metadataDir, false)
.restoreMetadata();
Collection<BinaryMetadata> metadata = F.viewReadOnly(metaCache.values(), BinaryMetadataHolder::metadata);
@@ -1073,7 +1076,7 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
ConcurrentMap<Integer, BinaryMetadataHolder> metaCache = new ConcurrentHashMap<>();
- new BinaryMetadataFileStore(metaCache, ctx, log, metadataDir).restoreMetadata(typeId);
+ new BinaryMetadataFileStore(metaCache, ctx, log, metadataDir, false).restoreMetadata(typeId);
addMetaLocally(typeId, metaCache.get(typeId).metadata().wrap(binaryContext()), false);
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java
index f7dbf5a19a8..074833bdd63 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java
@@ -164,6 +164,7 @@ import org.apache.ignite.internal.processors.task.GridInternal;
import org.apache.ignite.internal.util.BasicRateLimiter;
import org.apache.ignite.internal.util.GridBusyLock;
import org.apache.ignite.internal.util.GridCloseableIteratorAdapter;
+import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.internal.util.distributed.DistributedProcess;
import org.apache.ignite.internal.util.distributed.InitMessage;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
@@ -1224,18 +1225,18 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter
}
/**
- * @param req Request
- * @param grpIds0 Groups.
+ * @param req Request.
+ * @param grps0 Cache groups to dump.
* @return Create dump future.
*/
- private IgniteInternalFuture<SnapshotOperationResponse> initLocalDump(SnapshotOperationRequest req, List<Integer> grpIds0) {
+ private IgniteInternalFuture<SnapshotOperationResponse> initLocalDump(SnapshotOperationRequest req, List<Integer> grps0) {
IgniteInternalFuture<?> task0;
- List<Integer> grpIds = grpIds0.stream().filter(grpId -> cctx.cache().cacheGroup(grpId) != null).collect(Collectors.toList());
+ List<Integer> grps = grps0.stream().filter(grpId -> cctx.cache().cacheGroup(grpId) != null).collect(Collectors.toList());
File dumpDir = snapshotLocalDir(req.snapshotName(), null, locDumpDir);
- if (grpIds.isEmpty())
+ if (grps.isEmpty())
task0 = new GridFinishedFuture<>(Collections.emptySet());
else {
dumpDir.mkdirs();
@@ -1248,7 +1249,8 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter
req.snapshotPath(),
dumpDir,
tmpWorkDir,
- ioFactory
+ ioFactory,
+ grps
));
}
@@ -1266,7 +1268,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter
req.requestId(),
cctx.localNode().consistentId().toString(),
req.snapshotName(),
- grpIds,
+ grps,
nodes
);
@@ -2903,7 +2905,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter
/** */
private void removeDumpLock(String dumpName) throws IgniteCheckedException {
- File lock = dumpLockFile(snapshotLocalDir(dumpName, null, locDumpDir), cctx);
+ File lock = new File(nodeDumpDirectory(snapshotLocalDir(dumpName, null, locDumpDir), cctx), DUMP_LOCK);
if (!lock.exists())
throw new IgniteCheckedException("Lock file not exists: " + lock);
@@ -2913,17 +2915,12 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter
}
/** */
- public static File dumpLockFile(File dumpDir, GridCacheSharedContext<?, ?> cctx) throws IgniteCheckedException {
+ public static File nodeDumpDirectory(File dumpDir, GridCacheSharedContext<?, ?> cctx) throws IgniteCheckedException {
File nodeDumpDir = new File(dumpDir, databaseRelativePath(cctx.kernalContext().pdsFolderResolver().resolveFolders().folderName()));
- if (nodeDumpDir.exists()) {
- if (!nodeDumpDir.isDirectory())
- throw new IgniteCheckedException(nodeDumpDir + " must be a directory");
- }
- else if (!nodeDumpDir.mkdirs())
- throw new IgniteCheckedException("Dump directory can't be created: " + nodeDumpDir);
+ IgniteUtils.ensureDirectory(nodeDumpDir, "dump directory", null);
- return new File(nodeDumpDir, DUMP_LOCK);
+ return nodeDumpDir;
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/DumpCacheFutureTask.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/DumpCacheFutureTask.java
index d2090a1ef17..30e56086f57 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/DumpCacheFutureTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/DumpCacheFutureTask.java
@@ -19,22 +19,37 @@ package org.apache.ignite.internal.processors.cache.persistence.snapshot.dump;
import java.io.File;
import java.io.IOException;
+import java.util.List;
import java.util.UUID;
import java.util.function.BiConsumer;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.MarshallerContextImpl;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.StoredCacheData;
import org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory;
import org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
import org.apache.ignite.internal.processors.cache.persistence.snapshot.AbstractSnapshotFutureTask;
import org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager;
import org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotSender;
+import org.apache.ignite.internal.util.IgniteUtils;
import org.jetbrains.annotations.Nullable;
+import static org.apache.ignite.internal.processors.cache.GridLocalConfigManager.cachDataFilename;
+import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_DIR_PREFIX;
+import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_GRP_DIR_PREFIX;
+import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DUMP_LOCK;
+
/** */
public class DumpCacheFutureTask extends AbstractSnapshotFutureTask<Void> implements BiConsumer<String, File> {
/** */
private final File dumpDir;
+ /** */
+ private final List<Integer> grps;
+
/**
* @param cctx Cache context.
* @param dumpName Dump name.
@@ -51,7 +66,8 @@ public class DumpCacheFutureTask extends AbstractSnapshotFutureTask<Void> implem
@Nullable String snpPath,
File dumpDir,
File tmpWorkDir,
- FileIOFactory ioFactory
+ FileIOFactory ioFactory,
+ List<Integer> grps
) {
super(
cctx,
@@ -80,6 +96,7 @@ public class DumpCacheFutureTask extends AbstractSnapshotFutureTask<Void> implem
);
this.dumpDir = dumpDir;
+ this.grps = grps;
cctx.cache().configManager().addConfigurationChangeListener(this);
}
@@ -87,9 +104,40 @@ public class DumpCacheFutureTask extends AbstractSnapshotFutureTask<Void> implem
/** {@inheritDoc} */
@Override public boolean start() {
try {
- log.info("start!");
+ log.info("Start cache dump [name=" + snpName + ", grps=" + grps + ']');
+
+ File dumpNodeDir = IgniteSnapshotManager.nodeDumpDirectory(dumpDir, cctx);
+
+ createDumpLock(dumpNodeDir);
+
+ for (Integer grp : grps) {
+ CacheGroupContext grpCtx = cctx.cache().cacheGroup(grp);
+
+ File grpDir = new File(
+ dumpNodeDir,
+ (grpCtx.caches().size() > 1 ? CACHE_GRP_DIR_PREFIX : CACHE_DIR_PREFIX) + grpCtx.cacheOrGroupName()
+ );
+
+ IgniteUtils.ensureDirectory(grpDir, "dump group directory", null);
+
+ for (GridCacheContext<?, ?> cacheCtx : grpCtx.caches()) {
+ CacheConfiguration<?, ?> ccfg = cacheCtx.config();
+
+ cctx.cache().configManager().writeCacheData(
+ new StoredCacheData(ccfg),
+ new File(grpDir, cachDataFilename(ccfg))
+ );
+ }
+ }
+
+ cctx.kernalContext().cacheObjects().saveMetadata(
+ cctx.kernalContext().cacheObjects().binary().types(),
+ dumpDir
+ );
- lockDumpDirectory();
+ MarshallerContextImpl.saveMappings(cctx.kernalContext(), cctx.kernalContext()
+ .marshallerContext()
+ .getCachedMappings(), dumpDir);
onDone();
}
@@ -101,8 +149,8 @@ public class DumpCacheFutureTask extends AbstractSnapshotFutureTask<Void> implem
}
/** */
- private void lockDumpDirectory() throws IgniteCheckedException, IOException {
- File lock = IgniteSnapshotManager.dumpLockFile(dumpDir, cctx);
+ private void createDumpLock(File dumpNodeDir) throws IgniteCheckedException, IOException {
+ File lock = new File(dumpNodeDir, DUMP_LOCK);
if (!lock.createNewFile())
throw new IgniteCheckedException("Lock file can't be created or already exists: " + lock.getAbsolutePath());
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteCacheDumpSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteCacheDumpSelfTest.java
index 93698443140..1f27df89772 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteCacheDumpSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteCacheDumpSelfTest.java
@@ -22,11 +22,22 @@ import java.util.Collections;
import java.util.stream.IntStream;
import javax.management.DynamicMBean;
import org.apache.ignite.IgniteCache;
+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.platform.model.ACL;
+import org.apache.ignite.platform.model.Key;
+import org.apache.ignite.platform.model.Role;
+import org.apache.ignite.platform.model.User;
+import org.apache.ignite.platform.model.Value;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
import static org.apache.ignite.internal.management.api.CommandMBean.INVOKE;
+import static org.apache.ignite.platform.model.AccessLevel.SUPER;
/** */
public class IgniteCacheDumpSelfTest extends GridCommonAbstractTest {
@@ -37,13 +48,34 @@ public class IgniteCacheDumpSelfTest extends GridCommonAbstractTest {
cleanPersistenceDir();
}
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ return super.getConfiguration(igniteInstanceName).setDataStorageConfiguration(
+ new DataStorageConfiguration()
+ .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+ .setPersistenceEnabled(true))
+ );
+ }
+
/** */
@Test
public void testCacheDump() throws Exception {
try (IgniteEx ign = startGrid(0)) {
+ ign.cluster().state(ClusterState.ACTIVE);
+
IgniteCache<Object, Object> cache = ign.createCache(DEFAULT_CACHE_NAME);
+ IgniteCache<Object, Object> grpCache0 = ign.createCache(
+ new CacheConfiguration<>().setGroupName("grp").setName("cache-0")
+ );
+ IgniteCache<Object, Object> grpCache1 = ign.createCache(
+ new CacheConfiguration<>().setGroupName("grp").setName("cache-1")
+ );
- IntStream.range(0, 10).forEach(i -> cache.put(i, i));
+ IntStream.range(0, 10).forEach(i -> {
+ cache.put(i, i);
+ grpCache0.put(i, new User(i, ACL.values()[i % ACL.values().length], new Role("Role" + i, SUPER)));
+ grpCache1.put(new Key(i), new Value(String.valueOf(i)));
+ });
Object[] args = {"dump", ""};