diff --git a/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java b/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java index 1443da99d3fc2..868235683636c 100644 --- a/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java +++ b/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java @@ -129,11 +129,12 @@ public DumpReader(DumpReaderConfiguration cfg, IgniteLogger log) { for (Map.Entry> e : grpsCfgs.grpToNodes.entrySet()) { int grp = e.getKey(); + String grpName = grpsCfgs.grpIdToName.get(grp); for (String node : e.getValue()) { for (int part : dump.partitions(node, grp)) { if (grps != null && !grps.get(grp).add(part)) { - log.info("Skip copy partition [node=" + node + ", grp=" + grp + ", part=" + part + ']'); + log.info("Skip copy partition [node=" + node + ", grp=" + grpName + ", part=" + part + ']'); continue; } @@ -141,7 +142,7 @@ public DumpReader(DumpReaderConfiguration cfg, IgniteLogger log) { Runnable consumePart = () -> { if (skip.get()) { if (log.isDebugEnabled()) { - log.debug("Skip partition due to previous error [node=" + node + ", grp=" + grp + + log.debug("Skip partition due to previous error [node=" + node + ", grp=" + grpName + ", part=" + part + ']'); } @@ -150,7 +151,7 @@ public DumpReader(DumpReaderConfiguration cfg, IgniteLogger log) { try (DumpedPartitionIterator iter = dump.iterator(node, grp, part, grpsCfgs.cacheIds)) { if (log.isDebugEnabled()) { - log.debug("Consuming partition [node=" + node + ", grp=" + grp + + log.debug("Consuming partition [node=" + node + ", grp=" + grpName + ", part=" + part + ']'); } @@ -159,7 +160,7 @@ public DumpReader(DumpReaderConfiguration cfg, IgniteLogger log) { catch (Exception ex) { skip.set(cfg.failFast()); - log.error("Error consuming partition [node=" + node + ", grp=" + grp + + log.error("Error consuming partition [node=" + node + ", grp=" + grpName + ", part=" + part + ']', ex); throw new IgniteException(ex); @@ -365,9 +366,19 @@ private static GridKernalContext standaloneKernalContext(SnapshotFileTree sft, I private GroupsConfigs groupsConfigs(Dump dump) { Map> grpsToNodes = new HashMap<>(); List ccfgs = new ArrayList<>(); + Map grpIdToName = new HashMap<>(); Set grpIds = cfg.groupNames() != null - ? Arrays.stream(cfg.groupNames()).map(CU::cacheId).collect(Collectors.toSet()) + ? Arrays.stream(cfg.groupNames()) + .map(grpName -> { + int grpId = CU.cacheId(grpName); + + if (!grpIdToName.containsKey(grpId)) + grpIdToName.put(grpId, grpName); + + return grpId; + }) + .collect(Collectors.toSet()) : null; Set cacheIds = cfg.cacheNames() != null @@ -392,11 +403,14 @@ private GroupsConfigs groupsConfigs(Dump dump) { } grpsToNodes.get(grp).add(meta.folderName()); + + if (!grpIdToName.containsKey(grp)) + grpIdToName.put(grp, grpCaches.get(0).configuration().getGroupName()); } } // Optimize - skip whole cache if only one in group! - return new GroupsConfigs(grpsToNodes, ccfgs, cacheIds); + return new GroupsConfigs(grpsToNodes, ccfgs, cacheIds, grpIdToName); } /** */ @@ -410,11 +424,20 @@ private static class GroupsConfigs { /** Cache ids. */ public final Set cacheIds; + /** Mapping from group id to group name. */ + public final Map grpIdToName; + /** */ - public GroupsConfigs(Map> grpToNodes, Collection cacheCfgs, Set cacheIds) { + public GroupsConfigs( + Map> grpToNodes, + Collection cacheCfgs, + Set cacheIds, + Map grpIdToName + ) { this.grpToNodes = grpToNodes; this.cacheCfgs = cacheCfgs; this.cacheIds = cacheIds; + this.grpIdToName = grpIdToName; } } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java index dfe11664e853b..662ecb00e513c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java @@ -121,6 +121,7 @@ import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.SNAPSHOT_TRANSFER_RATE_DMS_KEY; import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.CACHE_0; import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.DMP_NAME; +import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.GRP; import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.KEYS_CNT; import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.USER_FACTORY; import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.dump; @@ -1296,6 +1297,185 @@ public void testConfigOnlySnapshotThrows() throws Exception { } } + /** */ + @Test + public void testDumpReaderDebugLogsGroupName() throws Exception { + checkDumpReaderDebugLogsGroupName(new String[]{GRP}); + } + + /** */ + @Test + public void testDumpReaderDebugLogsNullableGroupName() throws Exception { + checkDumpReaderDebugLogsGroupName(null); + } + + /** */ + @Test + public void testDumpReaderSkipCopiesLogsGroupName() throws Exception { + int parts = 4; + String dumpName0 = "dump0"; + String dumpName1 = "dump1"; + + File snapshotPath0 = Files.createTempDirectory("snapshots0").toFile(); + File snapshotPath1 = Files.createTempDirectory("snapshots1").toFile(); + File combinedDumpDir = Files.createTempDirectory("combined_dump").toFile(); + + ListeningTestLogger testLog = new ListeningTestLogger(log); + + LogListener skipLsnr = LogListener.matches("Skip copy partition") + .times(parts) + .andMatches("grp=" + GRP) + .build(); + + testLog.registerListener(skipLsnr); + + try { + IgniteEx node0 = startGrid(getConfiguration("node0") + .setConsistentId("node0") + .setSnapshotPath(snapshotPath0.getAbsolutePath()) + .setGridLogger(testLog)); + + IgniteEx node1 = startGrid(getConfiguration("node1") + .setConsistentId("node1") + .setSnapshotPath(snapshotPath1.getAbsolutePath()) + .setGridLogger(testLog)); + + node0.cluster().state(ClusterState.ACTIVE); + + CacheConfiguration ccfg = new CacheConfiguration() + .setName(DEFAULT_CACHE_NAME) + .setGroupName(GRP) + .setBackups(1) + .setAffinity(new RendezvousAffinityFunction().setPartitions(parts)); + + IgniteCache cache = node0.createCache(ccfg); + + IntStream.range(0, KEYS_CNT).forEach(i -> cache.put(i, i)); + + node0.snapshot().createDump(dumpName0, null).get(getTestTimeout()); + + U.sleep(100); + + node1.snapshot().createDump(dumpName1, null).get(getTestTimeout()); + + File dumpDir0 = new File(snapshotPath0, dumpName0); + File dumpDir1 = new File(snapshotPath1, dumpName1); + + U.copy(dumpDir0, combinedDumpDir, true); + U.copy(dumpDir1, combinedDumpDir, true); + + DumpConsumer dummyConsumer = new DumpConsumer() { + @Override public void start() { + // No-op. + } + + @Override public void onMappings(Iterator mappings) { + // No-op. + } + + @Override public void onTypes(Iterator types) { + // No-op. + } + + @Override public void onCacheConfigs(Iterator caches) { + // No-op. + } + + @Override public void onPartition(int grpId, int partId, Iterator data) { + // No-op. + } + + @Override public void stop() { + // No-op. + } + }; + + new DumpReader( + new DumpReaderConfiguration( + null, + combinedDumpDir.getAbsolutePath(), + null, + dummyConsumer, + DFLT_THREAD_CNT, + DFLT_TIMEOUT, + false, + true, + true, + new String[]{GRP}, + null, + true, + null + ), + testLog + ).run(); + + assertTrue(skipLsnr.check()); + } + finally { + U.delete(snapshotPath0); + U.delete(snapshotPath1); + U.delete(combinedDumpDir); + } + } + + /** */ + private void checkDumpReaderDebugLogsGroupName(String[] grpNames) throws Exception { + String id = "test"; + + setLoggerDebugLevel(); + + ListeningTestLogger testLog = new ListeningTestLogger(log); + + LogListener errLsnr = LogListener.matches("Error consuming partition").andMatches("grp=" + GRP).build(); + LogListener cnsmLsnr = LogListener.matches("Consuming partition").andMatches("grp=" + GRP).build(); + + testLog.registerListener(errLsnr); + testLog.registerListener(cnsmLsnr); + + IgniteEx ign = startGrid(getConfiguration(id).setConsistentId(id).setGridLogger(testLog)); + + ign.cluster().state(ClusterState.ACTIVE); + + IgniteCache cache = ign.createCache(new CacheConfiguration() + .setName(CACHE_0) + .setGroupName(GRP) + .setBackups(1) + .setAffinity(new RendezvousAffinityFunction().setPartitions(3)) + ); + + IntStream.range(0, KEYS_CNT).forEach(i -> cache.put(i, i)); + + ign.snapshot().createDump(DMP_NAME, null).get(getTestTimeout()); + + TestDumpConsumer cnsmr = new TestDumpConsumer() { + @Override public void onPartition(int grp, int part, Iterator data) { + throw new RuntimeException("trigger error log"); + } + }; + + assertThrows(null, () -> new DumpReader( + new DumpReaderConfiguration( + DMP_NAME, + null, + ign.configuration(), + cnsmr, + DFLT_THREAD_CNT, + DFLT_TIMEOUT, + true, + true, + false, + grpNames, + null, + false, + null + ), + testLog + ).run(), RuntimeException.class, "trigger error log"); + + assertTrue("Log with group name not found", errLsnr.check()); + assertTrue("Consuming with group name not found", cnsmLsnr.check()); + } + /** */ public class TestCacheConflictResolutionManager extends GridCacheManagerAdapter implements CacheConflictResolutionManager {