This is an automated email from the ASF dual-hosted git repository.
ivandasch 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 8cfa8b046a1 IGNITE-18198 Implement snapshots of caches with disk page
compression. (#10430)
8cfa8b046a1 is described below
commit 8cfa8b046a1b4782ebca75a506247d4331f89e3c
Author: Ivan Daschinskiy <[email protected]>
AuthorDate: Fri Dec 23 14:07:36 2022 +0300
IGNITE-18198 Implement snapshots of caches with disk page compression.
(#10430)
---
modules/compress/pom.xml | 14 +
.../compress/CompressionProcessorImpl.java | 34 ++
.../snapshot/SnapshotCompressionBasicTest.java | 385 +++++++++++++++++++++
.../DiskPageCompressionIntegrationTest.java | 2 +
.../testsuites/IgnitePdsCompressionTestSuite.java | 12 +
.../processors/cache/CacheCompressionManager.java | 102 ------
.../processors/cache/CacheGroupContext.java | 15 +-
.../processors/cache/GridCacheContext.java | 14 -
.../processors/cache/GridCacheProcessor.java | 16 +-
.../CachePartitionDefragmentationManager.java | 3 +-
.../pagemem/PageReadWriteManagerImpl.java | 9 +-
.../snapshot/IgniteSnapshotManager.java | 47 ++-
.../persistence/snapshot/SnapshotFutureTask.java | 21 +-
.../persistence/snapshot/SnapshotMetadata.java | 35 +-
.../snapshot/SnapshotPartitionsVerifyHandler.java | 67 +++-
.../snapshot/SnapshotRestoreProcess.java | 23 ++
.../wal/reader/StandaloneGridKernalContext.java | 26 +-
.../processors/cache/verify/IdleVerifyUtility.java | 23 ++
.../processors/compress/CompressionHandler.java | 130 +++++++
.../snapshot/AbstractSnapshotSelfTest.java | 20 +-
.../snapshot/IgniteClusterSnapshotCheckTest.java | 31 +-
.../snapshot/IgniteClusterSnapshotDeltaTest.java | 8 +-
.../snapshot/IgniteSnapshotManagerSelfTest.java | 5 +-
.../IgniteSnapshotWithMetastorageTest.java | 6 +-
.../loadtests/hashmap/GridCacheTestContext.java | 2 -
.../junits/multijvm/JavaVersionCommandParser.java | 4 +-
.../multijvm/JavaVersionCommandParserTest.java | 6 +
.../ignite/testsuites/IgniteSnapshotTestSuite.java | 52 ++-
.../IgniteSnapshotWithIndexingTestSuite.java | 30 +-
29 files changed, 960 insertions(+), 182 deletions(-)
diff --git a/modules/compress/pom.xml b/modules/compress/pom.xml
index 67ac1da1c0d..f9c4db51f42 100644
--- a/modules/compress/pom.xml
+++ b/modules/compress/pom.xml
@@ -117,6 +117,20 @@
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest</artifactId>
+ <version>${hamcrest.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git
a/modules/compress/src/main/java/org/apache/ignite/internal/processors/compress/CompressionProcessorImpl.java
b/modules/compress/src/main/java/org/apache/ignite/internal/processors/compress/CompressionProcessorImpl.java
index 6d53e0ef016..623ff50ee3d 100644
---
a/modules/compress/src/main/java/org/apache/ignite/internal/processors/compress/CompressionProcessorImpl.java
+++
b/modules/compress/src/main/java/org/apache/ignite/internal/processors/compress/CompressionProcessorImpl.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.compress;
+import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Path;
@@ -29,12 +30,15 @@ import org.apache.ignite.IgniteException;
import org.apache.ignite.configuration.DiskPageCompression;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.pagemem.PageUtils;
+import
org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIO;
import
org.apache.ignite.internal.processors.cache.persistence.tree.io.CompactablePageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.xerial.snappy.Snappy;
+import static java.nio.file.StandardOpenOption.CREATE;
+import static java.nio.file.StandardOpenOption.WRITE;
import static
org.apache.ignite.configuration.DataStorageConfiguration.MAX_PAGE_SIZE;
import static org.apache.ignite.configuration.DiskPageCompression.SKIP_GARBAGE;
import static org.apache.ignite.internal.util.GridUnsafe.NATIVE_BYTE_ORDER;
@@ -90,6 +94,8 @@ public class CompressionProcessorImpl extends
CompressionProcessor {
"must be at least 2 times larger than the underlying storage
block size (detected to be " + fsBlockSize +
" bytes at '" + storagePath + "') for page compression.");
}
+
+ checkPunchHole(storagePath, fsBlockSize);
}
/** {@inheritDoc} */
@@ -170,6 +176,34 @@ public class CompressionProcessorImpl extends
CompressionProcessor {
return compactPage;
}
+ /** Check if filesystem actually supports punching holes. */
+ private void checkPunchHole(Path storagePath, int fsBlockSz) throws
IgniteException {
+ ByteBuffer buffer = null;
+ File testFile = null;
+ try {
+ testFile = File.createTempFile("punch_hole_", null,
storagePath.toFile());
+
+ buffer = GridUnsafe.allocateBuffer(fsBlockSz * 2);
+ GridUnsafe.zeroMemory(GridUnsafe.bufferAddress(buffer),
buffer.capacity());
+
+ try (RandomAccessFileIO testFileIO = new
RandomAccessFileIO(testFile, CREATE, WRITE)) {
+ testFileIO.writeFully(buffer);
+
+ testFileIO.punchHole(fsBlockSz, fsBlockSz);
+ }
+ }
+ catch (Exception e) {
+ throw new IgniteException("File system does not support punching
holes on path " + storagePath, e);
+ }
+ finally {
+ if (buffer != null)
+ GridUnsafe.freeBuffer(buffer);
+
+ if (testFile != null)
+ testFile.delete();
+ }
+ }
+
/**
* @param page Page.
* @param compactSize Compacted page size.
diff --git
a/modules/compress/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotCompressionBasicTest.java
b/modules/compress/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotCompressionBasicTest.java
new file mode 100644
index 00000000000..acfb53deb1a
--- /dev/null
+++
b/modules/compress/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotCompressionBasicTest.java
@@ -0,0 +1,385 @@
+/*
+ * 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.snapshot;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DiskPageCompression;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.GridKernalContextImpl;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.persistence.file.FileIO;
+import
org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIO;
+import org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2;
+import org.apache.ignite.internal.processors.compress.CompressionProcessor;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+
+import static
org.apache.ignite.configuration.IgniteConfiguration.DFLT_SNAPSHOT_DIRECTORY;
+import static org.apache.ignite.events.EventType.EVTS_CLUSTER_SNAPSHOT;
+import static
org.apache.ignite.events.EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_FINISHED;
+import static
org.apache.ignite.events.EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_STARTED;
+
+/** */
+public class SnapshotCompressionBasicTest extends AbstractSnapshotSelfTest {
+ /** */
+ protected static final DiskPageCompression DISK_PAGE_COMPRESSION =
DiskPageCompression.SNAPPY;
+
+ /** */
+ protected static final int PAGE_SIZE = 8 * 1024;
+
+ /** */
+ protected static final String SNAPSHOT_WITHOUT_HOLES =
"testSnapshotWithoutHoles";
+
+ /** */
+ protected static final String SNAPSHOT_WITH_HOLES =
"testSnapshotWithHoles";
+
+ /** */
+ protected static final long TIMEOUT = 30_000;
+
+ /** */
+ private static final Map<String, String> CACHES = new HashMap<>();
+
+ static {
+ CACHES.put("cache1", "group1");
+ CACHES.put("cache2", "group1");
+ CACHES.put("cache3", null);
+ CACHES.put("cache4", null);
+ }
+
+ /** */
+ private static final Set<String> COMPRESSED_CACHES = new HashSet<>();
+
+ static {
+ COMPRESSED_CACHES.add("cache1");
+ COMPRESSED_CACHES.add("cache2");
+ COMPRESSED_CACHES.add("cache3");
+ }
+
+ /** */
+ @Parameterized.Parameters(name = "Encryption={0}")
+ public static Collection<Boolean> encryptionParams() {
+ return Collections.singletonList(false);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String
igniteInstanceName) throws Exception {
+ IgniteConfiguration config =
super.getConfiguration(igniteInstanceName);
+
+ config.getDataStorageConfiguration().setPageSize(PAGE_SIZE);
+
+ return config;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ cleanPersistenceDir();
+ createTestSnapshot();
+ }
+
+ /** {@inheritDoc} */
+ @Before
+ @Override public void beforeTestSnapshot() {
+ locEvts.clear();
+ }
+
+ /** {@inheritDoc} */
+ @After
+ @Override public void afterTestSnapshot() throws Exception {
+ if (G.allGrids().isEmpty())
+ return;
+
+ IgniteEx ig = grid(0);
+ for (String cacheName : ig.cacheNames()) {
+ IgniteCache cache = ig.cache(cacheName);
+
+ cache.destroy();
+ }
+
+ stopAllGrids();
+ }
+
+ /** */
+ @Test
+ public void testRestoreFullSnapshot() throws Exception {
+ IgniteEx ignite = startGrids(3);
+ ignite.events().localListen(e -> locEvts.add(e.type()),
EVTS_CLUSTER_SNAPSHOT);
+ ignite.cluster().state(ClusterState.ACTIVE);
+
+ for (String snpName: Arrays.asList(SNAPSHOT_WITH_HOLES,
SNAPSHOT_WITHOUT_HOLES)) {
+ try {
+ ignite.snapshot().restoreSnapshot(snpName, null).get(TIMEOUT);
+
+ waitForEvents(EVT_CLUSTER_SNAPSHOT_RESTORE_STARTED,
EVT_CLUSTER_SNAPSHOT_RESTORE_FINISHED);
+
+ for (String cacheName : CACHES.keySet()) {
+ IgniteCache cache = ignite.cache(cacheName);
+
+ assertCacheKeys(cache, 1000);
+
+ cache.destroy();
+ }
+ }
+ finally {
+ locEvts.clear();
+ }
+ }
+ }
+
+ /** */
+ @Test
+ public void testRestoreFail_OnGridWithoutCompression() throws Exception {
+ IgniteEx ignite = startGrids(3);
+ ignite.events().localListen(e -> locEvts.add(e.type()),
EVTS_CLUSTER_SNAPSHOT);
+ ignite.cluster().state(ClusterState.ACTIVE);
+
+ G.allGrids().forEach(this::failCompressionProcessor);
+
+ for (String snpName: Arrays.asList(SNAPSHOT_WITH_HOLES,
SNAPSHOT_WITHOUT_HOLES)) {
+ GridTestUtils.assertThrows(log, () ->
ignite.snapshot().restoreSnapshot(snpName, null).get(TIMEOUT),
+ IgniteException.class, "Snapshot contains compressed cache
groups");
+ }
+ }
+
+
+ /** */
+ @Test
+ public void testRestoreNotCompressed_OnGridWithoutCompression() throws
Exception {
+ IgniteEx ignite = startGrids(3);
+ ignite.events().localListen(e -> locEvts.add(e.type()),
EVTS_CLUSTER_SNAPSHOT);
+ ignite.cluster().state(ClusterState.ACTIVE);
+
+ G.allGrids().forEach(i -> failCompressionProcessor(i));
+
+ Collection<String> groupsWithoutCompression =
CACHES.entrySet().stream()
+ .filter(e -> !COMPRESSED_CACHES.contains(e.getKey()))
+ .map(e -> e.getValue() != null ? e.getValue() : e.getKey())
+ .distinct().collect(Collectors.toList());
+
+ for (String snpName: Arrays.asList(SNAPSHOT_WITH_HOLES,
SNAPSHOT_WITHOUT_HOLES)) {
+ try {
+ ignite.snapshot().restoreSnapshot(snpName,
groupsWithoutCompression).get(TIMEOUT);
+
+ waitForEvents(EVT_CLUSTER_SNAPSHOT_RESTORE_STARTED,
EVT_CLUSTER_SNAPSHOT_RESTORE_FINISHED);
+
+ CACHES.keySet().stream().filter(c ->
!COMPRESSED_CACHES.contains(c)).forEach(cacheName -> {
+ IgniteCache cache = ignite.cache(cacheName);
+
+ assertCacheKeys(cache, 1000);
+
+ cache.destroy();
+ });
+ }
+ finally {
+ locEvts.clear();
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Function<Integer, Object> valueBuilder() {
+ return i -> new Value("name_" + i);
+ }
+
+ /** */
+ protected void createTestSnapshot() throws Exception {
+ CacheConfiguration[] caches = CACHES.entrySet().stream()
+ .map(cache -> {
+ CacheConfiguration config = new
CacheConfiguration(cache.getKey());
+
+ config.setQueryEntities(Collections.singletonList(
+ new QueryEntity()
+ .setKeyType(Integer.class.getName())
+ .setValueType(Value.class.getName())
+ .addQueryField("id", Integer.class.getName(), null)
+ .addQueryField("name", String.class.getName(), null)
+ .setIndexes(F.asList(new QueryIndex("name")))
+ ));
+
+ if (cache.getValue() != null)
+ config.setGroupName(cache.getValue());
+
+ if (COMPRESSED_CACHES.contains(cache.getKey()))
+ config.setDiskPageCompression(DISK_PAGE_COMPRESSION);
+ else
+
config.setDiskPageCompression(DiskPageCompression.DISABLED);
+
+ return config;
+ }).toArray(CacheConfiguration[]::new);
+
+ IgniteEx ignite = startGridsWithCache(3, 1000, valueBuilder(), caches);
+
+ forceCheckpoint();
+
+ G.allGrids().forEach(i -> failCompressionProcessor(i,
SNAPSHOT_WITHOUT_HOLES));
+
+ for (String snpName : Arrays.asList(SNAPSHOT_WITH_HOLES,
SNAPSHOT_WITHOUT_HOLES)) {
+ ignite.snapshot().createSnapshot(snpName).get(TIMEOUT);
+
+ IdleVerifyResultV2 res =
ignite.context().cache().context().snapshotMgr().checkSnapshot(snpName, null)
+ .get().idleVerifyResult();
+
+ StringBuilder b = new StringBuilder();
+ res.print(b::append, true);
+
+ assertTrue("Exceptions: " + b, F.isEmpty(res.exceptions()));
+ assertTrue(F.isEmpty(res.exceptions()));
+ }
+
+ Path withHolesPath =
Paths.get(U.resolveWorkDirectory(U.defaultWorkDirectory(),
DFLT_SNAPSHOT_DIRECTORY, false)
+ .toString(), SNAPSHOT_WITH_HOLES);
+
+ Path withoutHolesPath =
Paths.get(U.resolveWorkDirectory(U.defaultWorkDirectory(),
DFLT_SNAPSHOT_DIRECTORY, false)
+ .toString(), SNAPSHOT_WITHOUT_HOLES);
+
+ long withHolesSize = directorySize(withHolesPath);
+ long withoutHolesSize = directorySize(withoutHolesPath);
+
+ assertTrue("withHolesSize < withoutHolesSize: " + withHolesSize + " <
" + withoutHolesSize,
+ withHolesSize < withoutHolesSize);
+
+ long idxWithHolesSize = directorySize(withHolesPath, "index\\.bin");
+ long idxWithoutHolesSize = directorySize(withoutHolesPath,
"index\\.bin");
+
+ assertTrue("idxWithHolesSize < idxWithoutHolesSize: " +
idxWithHolesSize + " < " + idxWithoutHolesSize,
+ idxWithHolesSize < idxWithoutHolesSize);
+
+ ignite.cacheNames().forEach(c -> ignite.getOrCreateCache(c).destroy());
+
+ G.stopAll(true);
+ }
+
+ /** */
+ private void failCompressionProcessor(Ignite ignite, String... snpNames) {
+ CompressionProcessor compressProc =
((IgniteEx)ignite).context().compress();
+
+ CompressionProcessor spyCompressProc = Mockito.spy(compressProc);
+
+ if (F.isEmpty(snpNames)) {
+ try {
+ Mockito.doAnswer(inv -> {
+ throw new IgniteCheckedException(new
IgniteException("errno: -12"));
+ }).when(spyCompressProc).checkPageCompressionSupported();
+
+ Mockito.doAnswer(inv -> {
+ throw new IgniteCheckedException(new
IgniteException("errno: -12"));
+
}).when(spyCompressProc).checkPageCompressionSupported(Mockito.any(),
Mockito.anyInt());
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
+ else {
+ for (String snpName : snpNames) {
+ try {
+ Mockito.doAnswer(inv -> {
+ if (snpName != null &&
((Path)inv.getArgument(0)).endsWith(snpName))
+ throw new IgniteCheckedException(new
IgniteException("errno: -12"));
+ return null;
+
}).when(spyCompressProc).checkPageCompressionSupported(Mockito.any(),
Mockito.anyInt());
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
+ }
+
+
((GridKernalContextImpl)((IgniteEx)ignite).context()).add(spyCompressProc);
+ }
+
+ /** */
+ private static long directorySize(Path path) throws IOException {
+ return directorySize(path, null);
+ }
+
+ /** */
+ private static long directorySize(Path path, String pattern) throws
IOException {
+ try (Stream<Path> walk = Files.walk(path)) {
+ return walk.filter(Files::isRegularFile)
+ .filter(f -> F.isEmpty(pattern) ||
f.getFileName().toString().matches(pattern))
+ .mapToLong(p -> {
+ try (FileIO fio = new RandomAccessFileIO(p.toFile(),
StandardOpenOption.READ)) {
+ return fio.getSparseSize();
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }).sum();
+ }
+ }
+
+ /** */
+ private static class Value {
+ /** */
+ String name;
+
+ /** */
+ Value(String name) {
+ this.name = name;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ Value value = (Value)o;
+
+ return Objects.equals(name, value.name);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return Objects.hash(name);
+ }
+ }
+}
diff --git
a/modules/compress/src/test/java/org/apache/ignite/internal/processors/compress/DiskPageCompressionIntegrationTest.java
b/modules/compress/src/test/java/org/apache/ignite/internal/processors/compress/DiskPageCompressionIntegrationTest.java
index d833a337a58..00a2ae2cd93 100644
---
a/modules/compress/src/test/java/org/apache/ignite/internal/processors/compress/DiskPageCompressionIntegrationTest.java
+++
b/modules/compress/src/test/java/org/apache/ignite/internal/processors/compress/DiskPageCompressionIntegrationTest.java
@@ -63,12 +63,14 @@ public class DiskPageCompressionIntegrationTest extends
AbstractPageCompressionI
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String
igniteName) throws Exception {
DataRegionConfiguration drCfg = new DataRegionConfiguration()
+ .setMetricsEnabled(true)
.setPersistenceEnabled(true);
factory = getFileIOFactory();
DataStorageConfiguration dsCfg = new DataStorageConfiguration()
.setPageSize(MAX_PAGE_SIZE)
+ .setMetricsEnabled(true)
.setDefaultDataRegionConfiguration(drCfg)
.setFileIOFactory(U.isLinux() ? factory : new
PunchFileIOFactory(factory));
diff --git
a/modules/compress/src/test/java/org/apache/ignite/testsuites/IgnitePdsCompressionTestSuite.java
b/modules/compress/src/test/java/org/apache/ignite/testsuites/IgnitePdsCompressionTestSuite.java
index a13427c4624..aae13a64ac0 100644
---
a/modules/compress/src/test/java/org/apache/ignite/testsuites/IgnitePdsCompressionTestSuite.java
+++
b/modules/compress/src/test/java/org/apache/ignite/testsuites/IgnitePdsCompressionTestSuite.java
@@ -18,11 +18,15 @@
package org.apache.ignite.testsuites;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import
org.apache.ignite.internal.processors.cache.persistence.db.wal.IgnitePdsCheckpointSimulationWithRealCpDisabledAndWalCompressionTest;
import
org.apache.ignite.internal.processors.cache.persistence.db.wal.WalCompactionAndPageCompressionTest;
import
org.apache.ignite.internal.processors.cache.persistence.db.wal.WalRecoveryWithPageCompressionAndTdeTest;
import
org.apache.ignite.internal.processors.cache.persistence.db.wal.WalRecoveryWithPageCompressionTest;
+import
org.apache.ignite.internal.processors.cache.persistence.snapshot.EncryptedSnapshotTest;
+import
org.apache.ignite.internal.processors.cache.persistence.snapshot.PlainSnapshotTest;
+import
org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotCompressionBasicTest;
import
org.apache.ignite.internal.processors.compress.CompressionConfigurationTest;
import org.apache.ignite.internal.processors.compress.CompressionProcessorTest;
import
org.apache.ignite.internal.processors.compress.DiskPageCompressionConfigValidationTest;
@@ -60,7 +64,15 @@ public class IgnitePdsCompressionTestSuite {
suite.add(IgnitePdsCheckpointSimulationWithRealCpDisabledAndWalCompressionTest.class);
suite.add(WalCompactionAndPageCompressionTest.class);
+ // Snapshots.
+ suite.add(SnapshotCompressionBasicTest.class);
+
+ //Snapshot tests from common suites.
enableCompressionByDefault();
+ IgniteSnapshotTestSuite.addSnapshotTests(suite,
Arrays.asList(PlainSnapshotTest.class, EncryptedSnapshotTest.class));
+ IgniteSnapshotWithIndexingTestSuite.addSnapshotTests(suite, null);
+
+ // PDS test suite with compression.
IgnitePdsTestSuite.addRealPageStoreTests(suite, null);
return suite;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheCompressionManager.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheCompressionManager.java
deleted file mode 100644
index 3bf2b8bbb48..00000000000
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheCompressionManager.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.io.File;
-import java.nio.ByteBuffer;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.DataStorageConfiguration;
-import org.apache.ignite.configuration.DiskPageCompression;
-import org.apache.ignite.internal.pagemem.store.PageStore;
-import org.apache.ignite.internal.processors.compress.CompressionProcessor;
-import org.apache.ignite.internal.util.typedef.internal.CU;
-import org.apache.ignite.internal.util.typedef.internal.U;
-
-import static
org.apache.ignite.internal.processors.compress.CompressionProcessor.checkCompressionLevelBounds;
-import static
org.apache.ignite.internal.processors.compress.CompressionProcessor.getDefaultCompressionLevel;
-
-/**
- * Cache compression manager.
- */
-public class CacheCompressionManager extends GridCacheManagerAdapter {
- /** */
- private DiskPageCompression diskPageCompression;
-
- /** */
- private int diskPageCompressLevel;
-
- /** */
- private CompressionProcessor compressProc;
-
- /** {@inheritDoc} */
- @Override protected void start0() throws IgniteCheckedException {
- CacheConfiguration cfg = cctx.config();
-
- if (cctx.kernalContext().clientNode() || !CU.isPersistentCache(cfg,
cctx.gridConfig().getDataStorageConfiguration())) {
- diskPageCompression = DiskPageCompression.DISABLED;
-
- return;
- }
-
- compressProc = cctx.kernalContext().compress();
-
- diskPageCompression = cctx.kernalContext().config().isClientMode() ?
null : cfg.getDiskPageCompression();
-
- if (diskPageCompression != DiskPageCompression.DISABLED) {
- if (!cctx.dataRegion().config().isPersistenceEnabled())
- throw new IgniteCheckedException("Disk page compression makes
sense only with enabled persistence.");
-
- Integer lvl = cfg.getDiskPageCompressionLevel();
- diskPageCompressLevel = lvl != null ?
- checkCompressionLevelBounds(lvl, diskPageCompression) :
- getDefaultCompressionLevel(diskPageCompression);
-
- DataStorageConfiguration dsCfg =
cctx.kernalContext().config().getDataStorageConfiguration();
-
- File dbPath =
cctx.kernalContext().pdsFolderResolver().resolveFolders().persistentStoreRootPath();
-
- assert dbPath != null;
-
- compressProc.checkPageCompressionSupported(dbPath.toPath(),
dsCfg.getPageSize());
-
- if (log.isInfoEnabled()) {
- log.info("Disk page compression is enabled [cache=" +
cctx.name() +
- ", compression=" + diskPageCompression + ", level=" +
diskPageCompressLevel + "]");
- }
- }
- }
-
- /**
- * @param page Page buffer.
- * @param store Page store.
- * @return Compressed or the same buffer.
- * @throws IgniteCheckedException If failed.
- */
- public ByteBuffer compressPage(ByteBuffer page, PageStore store) throws
IgniteCheckedException {
- if (diskPageCompression == DiskPageCompression.DISABLED)
- return page;
-
- int blockSize = store.getBlockSize();
-
- if (blockSize <= 0)
- throw new IgniteCheckedException("Failed to detect storage block
size on " + U.osString());
-
- return compressProc.compressPage(page, store.getPageSize(), blockSize,
diskPageCompression, diskPageCompressLevel);
- }
-}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
index e26a8b93ef4..28dc32fe20f 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
@@ -56,6 +56,7 @@ import
org.apache.ignite.internal.processors.cache.persistence.GridCacheOffheapM
import
org.apache.ignite.internal.processors.cache.persistence.freelist.FreeList;
import
org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
import
org.apache.ignite.internal.processors.cache.query.continuous.CounterSkipContext;
+import org.apache.ignite.internal.processors.compress.CompressionHandler;
import org.apache.ignite.internal.processors.metric.GridMetricManager;
import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
import org.apache.ignite.internal.processors.query.QueryUtils;
@@ -71,6 +72,7 @@ import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.plugin.CacheTopologyValidatorProvider;
import org.jetbrains.annotations.Nullable;
+
import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
import static
org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT;
import static org.apache.ignite.cache.CacheMode.REPLICATED;
@@ -192,6 +194,9 @@ public class CacheGroupContext {
/** Topology validators. */
private final Collection<TopologyValidator> topValidators;
+ /** Disk page compression method. */
+ private final CompressionHandler compressHandler;
+
/**
* @param ctx Context.
* @param grpId Group ID.
@@ -206,6 +211,7 @@ public class CacheGroupContext {
* @param locStartVer Topology version when group was started on local
node.
* @param persistenceEnabled Persistence enabled flag.
* @param walEnabled Wal enabled flag.
+ * @param compressHandler Compresion handler.
*/
public CacheGroupContext(
GridCacheSharedContext ctx,
@@ -221,7 +227,8 @@ public class CacheGroupContext {
AffinityTopologyVersion locStartVer,
boolean persistenceEnabled,
boolean walEnabled,
- boolean recoveryMode
+ boolean recoveryMode,
+ CompressionHandler compressHandler
) {
assert ccfg != null;
assert dataRegion != null || !affNode;
@@ -242,6 +249,7 @@ public class CacheGroupContext {
this.persistenceEnabled = persistenceEnabled;
this.localWalEnabled = true;
this.recoveryMode = new AtomicBoolean(recoveryMode);
+ this.compressHandler = compressHandler;
ioPlc = cacheType.ioPolicy();
@@ -1329,6 +1337,11 @@ public class CacheGroupContext {
return ctx.wal(cdcEnabled());
}
+ /** */
+ public CompressionHandler compressionHandler() {
+ return compressHandler;
+ }
+
/**
* @param ccfg Cache configuration.
* @param plugins Ignite plugin processor.
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
index 89f15fe57ff..fb48c74a141 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
@@ -186,9 +186,6 @@ public class GridCacheContext<K, V> implements
Externalizable {
/** Store manager. */
private CacheStoreManager storeMgr;
- /** Compression manager. */
- private CacheCompressionManager compressMgr;
-
/** Replication manager. */
private GridCacheDrManager drMgr;
@@ -339,8 +336,6 @@ public class GridCacheContext<K, V> implements
Externalizable {
* Managers in starting order!
* ===========================
*/
-
- CacheCompressionManager compressMgr,
GridCacheEventManager evtMgr,
CacheStoreManager storeMgr,
CacheEvictionManager evictMgr,
@@ -359,7 +354,6 @@ public class GridCacheContext<K, V> implements
Externalizable {
assert cacheCfg != null;
assert locStartTopVer != null : cacheCfg.getName();
- assert compressMgr != null;
assert grp != null;
assert evtMgr != null;
assert storeMgr != null;
@@ -386,7 +380,6 @@ public class GridCacheContext<K, V> implements
Externalizable {
* Managers in starting order!
* ===========================
*/
- this.compressMgr = add(compressMgr);
this.evtMgr = add(evtMgr);
this.storeMgr = add(storeMgr);
this.evictMgr = add(evictMgr);
@@ -1236,13 +1229,6 @@ public class GridCacheContext<K, V> implements
Externalizable {
return EMPTY_VERSION;
}
- /**
- * @return Compression manager.
- */
- public CacheCompressionManager compress() {
- return compressMgr;
- }
-
/**
* Sets cache object context.
*
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 c5a56bceccf..0ff4fda1727 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
@@ -141,6 +141,7 @@ import
org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProces
import
org.apache.ignite.internal.processors.cluster.ChangeGlobalStateFinishMessage;
import org.apache.ignite.internal.processors.cluster.ChangeGlobalStateMessage;
import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState;
+import org.apache.ignite.internal.processors.compress.CompressionHandler;
import
org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor;
import org.apache.ignite.internal.processors.metric.MetricRegistry;
import
org.apache.ignite.internal.processors.platform.cache.PlatformCacheManager;
@@ -194,6 +195,7 @@ import
org.apache.ignite.spi.systemview.view.CachePagesListView;
import org.apache.ignite.spi.systemview.view.PartitionStateView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
@@ -1269,7 +1271,6 @@ public class GridCacheProcessor extends
GridProcessorAdapter {
boolean nearEnabled = GridCacheUtils.isNearEnabled(cfg);
- CacheCompressionManager compressMgr = new CacheCompressionManager();
GridCacheAffinityManager affMgr = new GridCacheAffinityManager();
GridCacheEventManager evtMgr = new GridCacheEventManager();
CacheEvictionManager evictMgr = (nearEnabled ||
cfg.isOnheapCacheEnabled())
@@ -1309,7 +1310,6 @@ public class GridCacheProcessor extends
GridProcessorAdapter {
* Managers in starting order!
* ===========================
*/
- compressMgr,
evtMgr,
storeMgr,
evictMgr,
@@ -1427,7 +1427,6 @@ public class GridCacheProcessor extends
GridProcessorAdapter {
* Managers in starting order!
* ===========================
*/
- compressMgr,
evtMgr,
storeMgr,
evictMgr,
@@ -2480,6 +2479,14 @@ public class GridCacheProcessor extends
GridProcessorAdapter {
boolean persistenceEnabled = recoveryMode ||
sharedCtx.localNode().isClient() ? desc.persistenceEnabled() :
dataRegion != null && dataRegion.config().isPersistenceEnabled();
+ CompressionHandler compressHandler = CompressionHandler.create(ctx,
cfg);
+
+ if (log.isInfoEnabled() && compressHandler.compressionEnabled()) {
+ log.info("Disk page compression is enabled [cacheGrp=" +
CU.cacheOrGroupName(cfg) +
+ ", compression=" + compressHandler.diskPageCompression() + ",
level=" +
+ compressHandler.diskPageCompressionLevel() + "]");
+ }
+
CacheGroupContext grp = new CacheGroupContext(sharedCtx,
desc.groupId(),
desc.receivedFrom(),
@@ -2493,7 +2500,8 @@ public class GridCacheProcessor extends
GridProcessorAdapter {
exchTopVer,
persistenceEnabled,
desc.walEnabled(),
- recoveryMode
+ recoveryMode,
+ compressHandler
);
for (Object obj : grp.configuredUserObjects())
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/defragmentation/CachePartitionDefragmentationManager.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/defragmentation/CachePartitionDefragmentationManager.java
index 6d5185ac76d..70de48d2aaf 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/defragmentation/CachePartitionDefragmentationManager.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/defragmentation/CachePartitionDefragmentationManager.java
@@ -362,7 +362,8 @@ public class CachePartitionDefragmentationManager {
oldGrpCtx.localStartVersion(),
true,
false,
- true
+ true,
+ oldGrpCtx.compressionHandler()
);
defragmentationCheckpoint.checkpointTimeoutLock().checkpointReadLock();
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageReadWriteManagerImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageReadWriteManagerImpl.java
index 63ff696e617..4e19c286b74 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageReadWriteManagerImpl.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageReadWriteManagerImpl.java
@@ -25,7 +25,7 @@ import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.pagemem.PageIdUtils;
import org.apache.ignite.internal.pagemem.store.PageStore;
import org.apache.ignite.internal.pagemem.store.PageStoreCollection;
-import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
import
org.apache.ignite.internal.processors.cache.persistence.StorageException;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -93,12 +93,11 @@ public class PageReadWriteManagerImpl implements
PageReadWriteManager {
int pageSize = store.getPageSize();
int compressedPageSize = pageSize;
- GridCacheContext<?, ?> cctx0 =
ctx.cache().context().cacheContext(grpId);
-
- if (cctx0 != null) {
+ CacheGroupContext grpCtx = ctx.cache().cacheGroup(grpId);
+ if (grpCtx != null) {
assert pageBuf.position() == 0 && pageBuf.limit() == pageSize
: pageBuf;
- ByteBuffer compressedPageBuf =
cctx0.compress().compressPage(pageBuf, store);
+ ByteBuffer compressedPageBuf =
grpCtx.compressionHandler().compressPage(pageBuf, store);
if (compressedPageBuf != pageBuf) {
compressedPageSize =
PageIO.getCompressedSize(compressedPageBuf);
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 26270b900bd..4bf57ead781 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
@@ -81,6 +81,7 @@ import org.apache.ignite.binary.BinaryType;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.compute.ComputeTask;
import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DiskPageCompression;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.DiscoveryEvent;
import org.apache.ignite.events.SnapshotEvent;
@@ -142,6 +143,7 @@ import
org.apache.ignite.internal.processors.cache.tree.DataRow;
import org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2;
import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState;
import
org.apache.ignite.internal.processors.cluster.IgniteChangeGlobalStateSupport;
+import org.apache.ignite.internal.processors.compress.CompressionProcessor;
import
org.apache.ignite.internal.processors.configuration.distributed.DistributedConfigurationLifecycleListener;
import
org.apache.ignite.internal.processors.configuration.distributed.DistributedLongProperty;
import
org.apache.ignite.internal.processors.configuration.distributed.DistributedPropertyDispatcher;
@@ -795,6 +797,10 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
}
List<Integer> grpIds = new ArrayList<>(F.viewReadOnly(req.groups(),
CU::cacheId));
+ Collection<Integer> comprGrpIds = F.view(grpIds, i -> {
+ CacheGroupDescriptor desc = cctx.cache().cacheGroupDescriptor(i);
+ return desc != null && desc.config().getDiskPageCompression() !=
DiskPageCompression.DISABLED;
+ });
Set<Integer> leftGrps = new HashSet<>(grpIds);
leftGrps.removeAll(cctx.cache().cacheGroupDescriptors().keySet());
@@ -853,6 +859,7 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
pdsSettings.folderName(),
cctx.gridConfig().getDataStorageConfiguration().getPageSize(),
grpIds,
+ comprGrpIds,
blts,
(Set<GroupPartitionId>)fut.result(),
cctx.gridConfig().getEncryptionSpi().masterKeyDigest()
@@ -1458,6 +1465,27 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
return;
}
+ if (meta.hasCompressedGroups() &&
grpIds.keySet().stream().anyMatch(meta::isGroupWithCompresion)) {
+ try {
+
kctx0.compress().checkPageCompressionSupported();
+ }
+ catch (IgniteCheckedException e) {
+ String grpWithCompr =
grpIds.entrySet().stream()
+ .filter(grp ->
meta.isGroupWithCompresion(grp.getKey()))
+
.map(Map.Entry::getValue).collect(Collectors.joining(", "));
+
+ String msg = "Requested cache groups [" +
grpWithCompr + "] for check " +
+ "from snapshot '" + meta.snapshotName() +
"' are compressed while " +
+ "disk page compression is disabled. To
check these groups please " +
+ "start Ignite with ignite-compress module
in classpath";
+
+ res.onDone(new
SnapshotPartitionsVerifyTaskResult(metas, new IdleVerifyResultV2(
+ Collections.singletonMap(cctx.localNode(),
new IllegalArgumentException(msg)))));
+
+ return;
+ }
+ }
+
grpIds.keySet().removeAll(meta.partitions().keySet());
}
}
@@ -1914,9 +1942,12 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
* @return Standalone kernal context related to the snapshot.
* @throws IgniteCheckedException If fails.
*/
- public StandaloneGridKernalContext createStandaloneKernalContext(File
snpDir, String folderName) throws IgniteCheckedException {
- return new StandaloneGridKernalContext(log,
- resolveBinaryWorkDir(snpDir.getAbsolutePath(), folderName),
+ public StandaloneGridKernalContext createStandaloneKernalContext(
+ CompressionProcessor cmpProc,
+ File snpDir,
+ String folderName
+ ) throws IgniteCheckedException {
+ return new StandaloneGridKernalContext(log, cmpProc,
resolveBinaryWorkDir(snpDir.getAbsolutePath(), folderName),
resolveMappingFileStoreWorkDir(snpDir.getAbsolutePath()));
}
@@ -2495,6 +2526,9 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
/** Batch of rows read through iteration. */
private final Deque<CacheDataRow> rows = new LinkedList<>();
+ /** */
+ private final CompressionProcessor compressProc;
+
/** {@code true} if the iteration though partition reached its end. */
private boolean secondScanComplete;
@@ -2524,6 +2558,7 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
this.partId = partId;
this.coctx = coctx;
this.sctx = sctx;
+ compressProc = sctx.kernalContext().compress();
store.ensure();
pages = store.pages();
@@ -2670,6 +2705,9 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
assert read : toDetailString(pageId);
+ if (PageIO.getCompressionType(buff) !=
CompressionProcessor.UNCOMPRESSED_PAGE)
+ compressProc.decompressPage(buff, store.getPageSize());
+
return getType(buff) == flag(pageId);
}
@@ -3399,8 +3437,9 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
transferRateLimiter.acquire(pageSize);
ByteBuffer page = deltaIter.next();
+ long pageId = PageIO.getPageId(page);
- pageStore.write(PageIO.getPageId(page), page, 0, false);
+ pageStore.write(pageId, page, 0, false);
}
pageStore.finishRecover();
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotFutureTask.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotFutureTask.java
index 797fcba2d18..7f2477d3331 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotFutureTask.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotFutureTask.java
@@ -68,8 +68,10 @@ import
org.apache.ignite.internal.processors.cache.persistence.metastorage.MetaS
import
org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.processors.cache.persistence.wal.crc.FastCrc;
+import org.apache.ignite.internal.processors.compress.CompressionProcessor;
import org.apache.ignite.internal.processors.marshaller.MappedName;
import
org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl;
+import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.lang.IgniteThrowableRunner;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -943,12 +945,27 @@ class SnapshotFutureTask extends
AbstractSnapshotFutureTask<Set<GroupPartitionId
if (!store.read(pageId, locBuf, true))
return;
- locBuf.flip();
+ locBuf.clear();
writePage0(pageId, locBuf);
}
else {
// Direct buffer is needs to be written, associated
checkpoint not finished yet.
+ if
(PageIO.getCompressionType(GridUnsafe.bufferAddress(buf)) !=
CompressionProcessor.UNCOMPRESSED_PAGE) {
+ final ByteBuffer locBuf = locBuff.get();
+
+ assert locBuf.capacity() == store.getPageSize();
+
+ locBuf.clear();
+
+
GridUnsafe.copyOffheapOffheap(GridUnsafe.bufferAddress(buf),
GridUnsafe.bufferAddress(locBuf), buf.limit());
+
+ locBuf.limit(locBuf.capacity());
+ locBuf.position(0);
+
+ buf = locBuf;
+ }
+
writePage0(pageId, buf);
// Page marked as written to delta file, so there is no
need to
@@ -990,6 +1007,8 @@ class SnapshotFutureTask extends
AbstractSnapshotFutureTask<Set<GroupPartitionId
// Write buffer to the end of the file.
int len = deltaFileIo.writeFully(pageBuf);
+ assert len == pageBuf.capacity();
+
totalSize.addAndGet(len);
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
index 0a74d50cdb2..fd68e9a3219 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -31,6 +32,7 @@ import java.util.Set;
import java.util.UUID;
import
org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
@@ -83,6 +85,12 @@ public class SnapshotMetadata implements Serializable {
@GridToStringInclude
@Nullable private List<String> warnings;
+ /** */
+ private transient Set<Integer> comprGrpIds;
+
+ /** */
+ private boolean hasComprGrps;
+
/**
* F@param snpName Snapshot name.
* @param consId Consistent id of a node to which this metadata relates.
@@ -99,6 +107,7 @@ public class SnapshotMetadata implements Serializable {
String folderName,
int pageSize,
List<Integer> grpIds,
+ Collection<Integer> compGrpIds,
Set<String> bltNodes,
Set<GroupPartitionId> pairs,
@Nullable byte[] masterKeyDigest
@@ -112,6 +121,12 @@ public class SnapshotMetadata implements Serializable {
this.bltNodes = bltNodes;
this.masterKeyDigest = masterKeyDigest;
+ if (!F.isEmpty(compGrpIds)) {
+ hasComprGrps = true;
+
+ comprGrpIds = new HashSet<>(compGrpIds);
+ }
+
pairs.forEach(p ->
locParts.computeIfAbsent(p.getGroupId(), k -> new HashSet<>())
.add(p.getPartitionId()));
@@ -174,6 +189,16 @@ public class SnapshotMetadata implements Serializable {
return Collections.unmodifiableMap(locParts);
}
+ /** */
+ public boolean isGroupWithCompresion(int grpId) {
+ return hasComprGrps && comprGrpIds.contains(grpId);
+ }
+
+ /** */
+ public boolean hasCompressedGroups() {
+ return hasComprGrps;
+ }
+
/** Save the state of this <tt>HashMap</tt> partitions and cache groups to
a stream. */
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
@@ -191,6 +216,9 @@ public class SnapshotMetadata implements Serializable {
for (Integer partId : e.getValue())
s.writeInt(partId);
}
+
+ if (hasComprGrps)
+ U.writeCollection(s, comprGrpIds);
}
/** Reconstitute the <tt>HashMap</tt> instance of partitions and cache
groups from a stream. */
@@ -221,6 +249,9 @@ public class SnapshotMetadata implements Serializable {
locParts.put(grpId, parts);
}
+
+ if (hasComprGrps)
+ comprGrpIds = U.readSet(s);
}
/**
@@ -275,7 +306,9 @@ public class SnapshotMetadata implements Serializable {
Objects.equals(grpIds, meta.grpIds) &&
Objects.equals(bltNodes, meta.bltNodes) &&
Arrays.equals(masterKeyDigest, meta.masterKeyDigest) &&
- Objects.equals(warnings, meta.warnings);
+ Objects.equals(warnings, meta.warnings) &&
+ Objects.equals(hasComprGrps, hasComprGrps) &&
+ Objects.equals(comprGrpIds, comprGrpIds);
}
/** {@inheritDoc} */
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java
index 1a0ea4f1e68..90a7b71fe4e 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java
@@ -54,6 +54,7 @@ import
org.apache.ignite.internal.processors.cache.persistence.tree.io.PageParti
import org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2;
import
org.apache.ignite.internal.processors.cache.verify.PartitionHashRecordV2;
import org.apache.ignite.internal.processors.cache.verify.PartitionKeyV2;
+import org.apache.ignite.internal.processors.compress.CompressionProcessor;
import org.apache.ignite.internal.util.GridStringBuilder;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.F;
@@ -145,13 +146,16 @@ public class SnapshotPartitionsVerifyHandler implements
SnapshotHandler<Map<Part
", meta=" + meta + ']');
}
+ boolean punchHoleEnabled = isPunchHoleEnabled(opCtx, grpDirs.keySet());
+
Map<PartitionKeyV2, PartitionHashRecordV2> res = new
ConcurrentHashMap<>();
ThreadLocal<ByteBuffer> buff = ThreadLocal.withInitial(() ->
ByteBuffer.allocateDirect(meta.pageSize())
.order(ByteOrder.nativeOrder()));
IgniteSnapshotManager snpMgr = cctx.snapshotMgr();
- GridKernalContext snpCtx =
snpMgr.createStandaloneKernalContext(opCtx.snapshotDirectory(),
meta.folderName());
+ GridKernalContext snpCtx =
snpMgr.createStandaloneKernalContext(cctx.kernalContext().compress(),
+ opCtx.snapshotDirectory(), meta.folderName());
FilePageStoreManager storeMgr = (FilePageStoreManager)cctx.pageStore();
@@ -173,14 +177,38 @@ public class SnapshotPartitionsVerifyHandler implements
SnapshotHandler<Map<Part
(FilePageStore)storeMgr.getPageStoreFactory(grpId,
snpEncrKeyProvider.getActiveKey(grpId) != null ?
snpEncrKeyProvider :
null).createPageStore(getTypeByPartId(partId), part::toPath, val -> {})
) {
+ pageStore.init();
+
+ if (punchHoleEnabled &&
meta.isGroupWithCompresion(grpId) && type() == SnapshotHandlerType.CREATE) {
+ byte pageType = partId == INDEX_PARTITION ?
FLAG_IDX : FLAG_DATA;
+
+ checkPartitionsPageCrcSum(() -> pageStore, partId,
pageType, (id, buffer) -> {
+ if (PageIO.getCompressionType(buffer) ==
CompressionProcessor.UNCOMPRESSED_PAGE)
+ return;
+
+ int comprPageSz =
PageIO.getCompressedSize(buffer);
+
+ if (comprPageSz < pageStore.getPageSize()) {
+ try {
+ pageStore.punchHole(id, comprPageSz);
+ }
+ catch (Exception ignored) {
+ // No-op.
+ }
+ }
+ });
+ }
+
if (partId == INDEX_PARTITION) {
- checkPartitionsPageCrcSum(() -> pageStore,
INDEX_PARTITION, FLAG_IDX);
+ if (!skipHash())
+ checkPartitionsPageCrcSum(() -> pageStore,
INDEX_PARTITION, FLAG_IDX);
return null;
}
if (grpId == MetaStorage.METASTORAGE_CACHE_ID) {
- checkPartitionsPageCrcSum(() -> pageStore, partId,
FLAG_DATA);
+ if (!skipHash())
+ checkPartitionsPageCrcSum(() -> pageStore,
partId, FLAG_DATA);
return null;
}
@@ -191,6 +219,9 @@ public class SnapshotPartitionsVerifyHandler implements
SnapshotHandler<Map<Part
long pageAddr = GridUnsafe.bufferAddress(pageBuff);
+ if (PageIO.getCompressionType(pageBuff) !=
CompressionProcessor.UNCOMPRESSED_PAGE)
+ snpCtx.compress().decompressPage(pageBuff,
pageStore.getPageSize());
+
PagePartitionMetaIO io = PageIO.getPageIO(pageBuff);
GridDhtPartitionState partState =
fromOrdinal(io.getPartitionState(pageAddr));
@@ -285,6 +316,36 @@ public class SnapshotPartitionsVerifyHandler implements
SnapshotHandler<Map<Part
return false;
}
+ /** */
+ protected boolean isPunchHoleEnabled(SnapshotHandlerContext opCtx,
Set<Integer> grpIds) {
+ SnapshotMetadata meta = opCtx.metadata();
+ Path snapshotDirectory = opCtx.snapshotDirectory().toPath();
+
+ if (meta.hasCompressedGroups() &&
grpIds.stream().anyMatch(meta::isGroupWithCompresion)) {
+ try {
+
cctx.kernalContext().compress().checkPageCompressionSupported();
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException("Snapshot contains compressed cache
groups " +
+ "[grps=[" +
grpIds.stream().filter(meta::isGroupWithCompresion).collect(Collectors.toList())
+
+ "], snpName=" + meta.snapshotName() + "], but compression
module is not enabled. " +
+ "Make sure that ignite-compress module is in classpath.");
+ }
+
+ try {
+
cctx.kernalContext().compress().checkPageCompressionSupported(snapshotDirectory,
meta.pageSize());
+
+ return true;
+ }
+ catch (Exception e) {
+ log.info("File system doesn't support page compression on
snapshot directory: " + snapshotDirectory
+ + ", snapshot may have larger size than expected.");
+ }
+ }
+
+ return false;
+ }
+
/**
* Provides encryption keys stored within snapshot.
* <p>
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java
index e53acf4a8ae..b414632bdd4 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java
@@ -680,6 +680,7 @@ public class SnapshotRestoreProcess {
// Collect the cache configurations and prepare a temporary directory
for copying files.
// Metastorage can be restored only manually by directly copying files.
+ boolean skipCompressCheck = false;
for (SnapshotMetadata meta : metas) {
for (File snpCacheDir :
cctx.snapshotMgr().snapshotCacheDirectories(req.snapshotName(),
req.snapshotPath(), meta.folderName(),
name -> !METASTORAGE_CACHE_NAME.equals(name))) {
@@ -688,6 +689,28 @@ public class SnapshotRestoreProcess {
if (!F.isEmpty(req.groups()) &&
!req.groups().contains(grpName))
continue;
+ if (!skipCompressCheck &&
meta.isGroupWithCompresion(CU.cacheId(grpName))) {
+ try {
+ File path =
ctx.pdsFolderResolver().resolveFolders().persistentStoreRootPath();
+
+
ctx.compress().checkPageCompressionSupported(path.toPath(), meta.pageSize());
+ }
+ catch (Exception e) {
+ String grpWithCompr = req.groups().stream().filter(s
-> meta.isGroupWithCompresion(CU.cacheId(grpName)))
+ .collect(Collectors.joining(", "));
+
+ String msg = "Requested cache groups [" + grpWithCompr
+ "] for restore " +
+ "from snapshot '" + meta.snapshotName() + "' are
compressed while " +
+ "disk page compression is disabled. To restore
these groups please " +
+ "start Ignite with configured disk page
compression";
+
+ throw new IgniteCheckedException(msg);
+ }
+ finally {
+ skipCompressCheck = true;
+ }
+ }
+
File cacheDir =
pageStore.cacheWorkDir(snpCacheDir.getName().startsWith(CACHE_GRP_DIR_PREFIX),
grpName);
if (cacheDir.exists()) {
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
index ac416515f46..890c1198c38 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
@@ -144,8 +144,29 @@ public class StandaloneGridKernalContext implements
GridKernalContext {
/** Marshaller context implementation. */
private MarshallerContextImpl marshallerCtx;
+ /** */
+ @Nullable private CompressionProcessor compressProc;
+
+ /**
+ * @param log Logger.
+ * @param binaryMetadataFileStoreDir folder specifying location of
metadata File Store.
+ * {@code null} means no specific folder is configured. <br>
+ *
+ * @param marshallerMappingFileStoreDir folder specifying location of
marshaller mapping file store.
+ * {@code null} means no specific folder is configured.
+ * Providing {@code null} will disable unmarshall for non primitive
objects, BinaryObjects will be provided <br>
+ */
+ public StandaloneGridKernalContext(
+ IgniteLogger log,
+ @Nullable File binaryMetadataFileStoreDir,
+ @Nullable File marshallerMappingFileStoreDir
+ ) throws IgniteCheckedException {
+ this(log, null, binaryMetadataFileStoreDir,
marshallerMappingFileStoreDir);
+ }
+
/**
* @param log Logger.
+ * @param compressProc Compression processor.
* @param binaryMetadataFileStoreDir folder specifying location of
metadata File Store.
* {@code null} means no specific folder is configured. <br>
*
@@ -155,6 +176,7 @@ public class StandaloneGridKernalContext implements
GridKernalContext {
*/
public StandaloneGridKernalContext(
IgniteLogger log,
+ @Nullable CompressionProcessor compressProc,
@Nullable File binaryMetadataFileStoreDir,
@Nullable File marshallerMappingFileStoreDir
) throws IgniteCheckedException {
@@ -187,6 +209,8 @@ public class StandaloneGridKernalContext implements
GridKernalContext {
marshallerCtx.setMarshallerMappingFileStoreDir(marshallerMappingFileStoreDir);
marshallerCtx.onMarshallerProcessorStarted(this, null);
}
+
+ this.compressProc = compressProc;
}
/**
@@ -643,7 +667,7 @@ public class StandaloneGridKernalContext implements
GridKernalContext {
/** {@inheritDoc} */
@Override public CompressionProcessor compress() {
- return null;
+ return compressProc;
}
/** {@inheritDoc} */
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java
index 8d4b8ed755e..e288679e69a 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.BiConsumer;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.IgniteEx;
@@ -73,6 +74,25 @@ public class IdleVerifyUtility {
IgniteThrowableSupplier<FilePageStore> pageStoreSup,
int partId,
byte pageType
+ ) {
+ checkPartitionsPageCrcSum(pageStoreSup, partId, pageType, null);
+ }
+
+ /**
+ * Checks CRC sum of pages with {@code pageType} page type stored in
partition with {@code partId} id
+ * and associated with cache group.
+ *
+ * @param pageStoreSup Page store supplier.
+ * @param partId Partition id.
+ * @param pageType Page type. Possible types {@link
PageIdAllocator#FLAG_DATA}, {@link PageIdAllocator#FLAG_IDX}
+ * and {@link PageIdAllocator#FLAG_AUX}.
+ * @param pagePostProcessor Page post processor closure.
+ */
+ public static void checkPartitionsPageCrcSum(
+ IgniteThrowableSupplier<FilePageStore> pageStoreSup,
+ int partId,
+ byte pageType,
+ @Nullable BiConsumer<Long, ByteBuffer> pagePostProcessor
) {
assert pageType == FLAG_DATA || pageType == FLAG_IDX || pageType ==
FLAG_AUX : pageType;
@@ -89,6 +109,9 @@ public class IdleVerifyUtility {
buf.clear();
pageStore.read(pageId, buf, true, true);
+
+ if (pagePostProcessor != null)
+ pagePostProcessor.accept(pageId, buf);
}
}
catch (Throwable e) {
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/compress/CompressionHandler.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/compress/CompressionHandler.java
new file mode 100644
index 00000000000..a1dd5146aad
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/compress/CompressionHandler.java
@@ -0,0 +1,130 @@
+/*
+ * 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.compress;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.DiskPageCompression;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.pagemem.store.PageStore;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/** */
+public class CompressionHandler {
+ /** */
+ private final CompressionProcessor compressProc;
+
+ /** */
+ private final int diskPageCompressLevel;
+
+ /** */
+ private final DiskPageCompression diskPageCompression;
+
+ /** */
+ private CompressionHandler(
+ CompressionProcessor compressProc,
+ DiskPageCompression diskPageCompression,
+ int diskPageCompressLevel
+ ) {
+ this.diskPageCompression = diskPageCompression;
+ this.diskPageCompressLevel = diskPageCompressLevel;
+ this.compressProc = compressProc;
+ }
+
+ /** */
+ private CompressionHandler() {
+ diskPageCompression = DiskPageCompression.DISABLED;
+ diskPageCompressLevel = 0;
+ compressProc = null;
+ }
+
+ /**
+ * @return Disk page compression algorithm..
+ */
+ public DiskPageCompression diskPageCompression() {
+ return diskPageCompression;
+ }
+
+ /**
+ * @return Disk page compression level.
+ */
+ public int diskPageCompressionLevel() {
+ return diskPageCompressLevel;
+ }
+
+ /**
+ * @return {@code true} if disk page compression is enabled.
+ */
+ public boolean compressionEnabled() {
+ return diskPageCompression != DiskPageCompression.DISABLED;
+ }
+
+ /**
+ * @param page Page buffer.
+ * @param store Page store.
+ * @return Compressed or the same buffer.
+ * @throws IgniteCheckedException If failed.
+ */
+ public ByteBuffer compressPage(ByteBuffer page, PageStore store) throws
IgniteCheckedException {
+ if (diskPageCompression == DiskPageCompression.DISABLED)
+ return page;
+
+ int blockSize = store.getBlockSize();
+
+ if (blockSize <= 0)
+ throw new IgniteCheckedException("Failed to detect storage block
size on " + U.osString());
+
+ return compressProc.compressPage(page, store.getPageSize(), blockSize,
diskPageCompression, diskPageCompressLevel);
+ }
+
+ /**
+ * Creates compression handler.
+ *
+ * @param ctx Grid kernal context.
+ * @param cfg Cache or cache group configuration.
+ * @return Compression handler.
+ */
+ public static CompressionHandler create(
+ GridKernalContext ctx,
+ CacheConfiguration cfg
+ ) throws IgniteCheckedException {
+ DiskPageCompression diskPageCompr = cfg.getDiskPageCompression();
+ DataStorageConfiguration dsCfg =
ctx.config().getDataStorageConfiguration();
+
+ if (ctx.clientNode() || diskPageCompr == DiskPageCompression.DISABLED
|| !CU.isPersistentCache(cfg, dsCfg))
+ return new CompressionHandler();
+
+ CompressionProcessor comprProc = ctx.compress();
+
+ int lvl = cfg.getDiskPageCompressionLevel() == null ?
+ CompressionProcessor.getDefaultCompressionLevel(diskPageCompr) :
+
CompressionProcessor.checkCompressionLevelBounds(cfg.getDiskPageCompressionLevel(),
diskPageCompr);
+
+ File dbPath =
ctx.pdsFolderResolver().resolveFolders().persistentStoreRootPath();
+
+ assert dbPath != null;
+
+ comprProc.checkPageCompressionSupported(dbPath.toPath(),
dsCfg.getPageSize());
+
+ return new CompressionHandler(comprProc, diskPageCompr, lvl);
+ }
+}
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
index 6b647084ed9..0f2aef16714 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
@@ -28,6 +28,7 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -48,6 +49,7 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.binary.BinaryType;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
@@ -58,6 +60,7 @@ 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.DiskPageCompression;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteEx;
@@ -94,6 +97,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static java.nio.file.Files.newDirectoryStream;
+import static
org.apache.ignite.IgniteSystemProperties.IGNITE_DEFAULT_DATA_STORAGE_PAGE_SIZE;
+import static
org.apache.ignite.IgniteSystemProperties.IGNITE_DEFAULT_DISK_PAGE_COMPRESSION;
import static
org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction.DFLT_PARTITION_COUNT;
import static org.apache.ignite.cluster.ClusterState.ACTIVE;
import static org.apache.ignite.cluster.ClusterState.INACTIVE;
@@ -124,6 +129,14 @@ public abstract class AbstractSnapshotSelfTest extends
GridCommonAbstractTest {
/** Timeout in milliseconds to await for snapshot operation being
completed. */
protected static final long TIMEOUT = 15_000;
+ /** */
+ protected static final DiskPageCompression DISK_PAGE_COMPRESSION =
+ IgniteSystemProperties.getEnum(IGNITE_DEFAULT_DISK_PAGE_COMPRESSION,
DiskPageCompression.DISABLED);
+
+ /** */
+ protected static final int PAGE_SIZE =
+
IgniteSystemProperties.getInteger(IGNITE_DEFAULT_DATA_STORAGE_PAGE_SIZE,
DFLT_PAGE_SIZE);
+
/** List of collected snapshot test events. */
protected final List<Integer> locEvts = new CopyOnWriteArrayList<>();
@@ -153,6 +166,9 @@ public abstract class AbstractSnapshotSelfTest extends
GridCommonAbstractTest {
/** Parameters. */
@Parameterized.Parameters(name = "Encryption={0}")
public static Collection<Boolean> encryptionParams() {
+ if (DISK_PAGE_COMPRESSION != DiskPageCompression.DISABLED)
+ return Collections.singletonList(false);
+
return Arrays.asList(false, true);
}
@@ -171,10 +187,10 @@ public abstract class AbstractSnapshotSelfTest extends
GridCommonAbstractTest {
.setCommunicationSpi(new TestRecordingCommunicationSpi())
.setDataStorageConfiguration(new DataStorageConfiguration()
.setDefaultDataRegionConfiguration(new
DataRegionConfiguration()
- .setMaxSize(100L * 1024 * 1024)
+ .setMaxSize(512L * 1024 * 1024)
.setPersistenceEnabled(persistence))
.setCheckpointFrequency(3000)
- .setPageSize(DFLT_PAGE_SIZE))
+ .setPageSize(PAGE_SIZE))
.setClusterStateOnStart(INACTIVE)
.setIncludeEventTypes(EVTS_CLUSTER_SNAPSHOT)
.setDiscoverySpi(discoSpi);
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java
index c17f9004c82..af574b63b97 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java
@@ -49,6 +49,7 @@ import org.apache.ignite.internal.binary.BinaryContext;
import org.apache.ignite.internal.binary.BinaryObjectImpl;
import org.apache.ignite.internal.managers.communication.GridMessageListener;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
@@ -67,6 +68,7 @@ import
org.apache.ignite.internal.processors.cache.verify.PartitionHashRecordV2;
import org.apache.ignite.internal.processors.cache.verify.PartitionKeyV2;
import
org.apache.ignite.internal.processors.cache.verify.VerifyBackupPartitionsTaskV2;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.processors.compress.CompressionProcessor;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.lang.GridIterator;
import org.apache.ignite.internal.util.typedef.F;
@@ -257,15 +259,36 @@ public class IgniteClusterSnapshotCheckTest extends
AbstractSnapshotSelfTest {
buff.clear();
pageStore.read(0, buff, false);
- PagePartitionMetaIO io = PageIO.getPageIO(buff);
-
long pageAddr = GridUnsafe.bufferAddress(buff);
+ boolean shouldCompress = false;
+ if (PageIO.getCompressionType(pageAddr) !=
CompressionProcessor.UNCOMPRESSED_PAGE) {
+ shouldCompress = true;
+
+ ignite.context().compress().decompressPage(buff,
pageStore.getPageSize());
+ }
+
+ PagePartitionMetaIO io = PageIO.getPageIO(buff);
+
io.setUpdateCounter(pageAddr, CACHE_KEYS_RANGE * 2);
- pageStore.beginRecover();
+ if (shouldCompress) {
+ CacheGroupContext grpCtx =
ignite.context().cache().cacheGroup(grpId);
- buff.flip();
+ assertNotNull("Group context for grpId:" + grpId, grpCtx);
+
+ ByteBuffer compressedPageBuf =
grpCtx.compressionHandler().compressPage(buff, pageStore);
+
+ if (compressedPageBuf != buff) {
+ buff = compressedPageBuf;
+
+ PageIO.setCrc(buff, 0);
+ }
+ }
+ else
+ buff.flip();
+
+ pageStore.beginRecover();
pageStore.write(PageIO.getPageId(buff), buff, 0, true);
pageStore.finishRecover();
}
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
index 8912396d691..758c90a524d 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
@@ -44,7 +44,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static
org.apache.ignite.IgniteSystemProperties.IGNITE_SNAPSHOT_SEQUENTIAL_WRITE;
-import static
org.apache.ignite.configuration.DataStorageConfiguration.DFLT_PAGE_SIZE;
+import static
org.apache.ignite.internal.pagemem.PageIdAllocator.INDEX_PARTITION;
import static
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_DIR_PREFIX;
import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DeltaSortedIterator.DELTA_SORT_BATCH_SIZE;
import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.partDeltaIndexFile;
@@ -77,7 +77,7 @@ public class IgniteClusterSnapshotDeltaTest extends
AbstractSnapshotSelfTest {
@Test
public void testSendDelta() throws Exception {
int keys = 10_000;
- byte[] payload = new byte[DFLT_PAGE_SIZE / 2];
+ byte[] payload = new byte[PAGE_SIZE / 2];
int partCnt = 2;
System.setProperty(IGNITE_SNAPSHOT_SEQUENTIAL_WRITE,
String.valueOf(sequentialWrite));
@@ -121,8 +121,8 @@ public class IgniteClusterSnapshotDeltaTest extends
AbstractSnapshotSelfTest {
}
@Override public void sendDelta0(File delta, String cacheDirName,
GroupPartitionId pair) {
- if (cacheDir.equals(cacheDirName))
- assertTrue(delta.length() > 0);
+ if (cacheDir.equals(cacheDirName) && pair.getPartitionId() !=
INDEX_PARTITION)
+ assertTrue("Delta length : " + delta.length() + " > 0",
delta.length() > 0);
if (!sequentialWrite)
U.delete(partDeltaIndexFile(delta));
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
index 4631a82202f..59923bebe08 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
@@ -68,7 +68,6 @@ import org.apache.ignite.testframework.LogListener;
import org.junit.Test;
import static java.util.Objects.nonNull;
-import static
org.apache.ignite.configuration.DataStorageConfiguration.DFLT_PAGE_SIZE;
import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.CP_SNAPSHOT_REASON;
import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.SNAPSHOT_RUNNER_THREAD_PREFIX;
import static
org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
@@ -79,7 +78,7 @@ import static
org.apache.ignite.testframework.GridTestUtils.setFieldValue;
*/
public class IgniteSnapshotManagerSelfTest extends AbstractSnapshotSelfTest {
/** The size of value array to fit 3 pages. */
- private static final int SIZE_FOR_FIT_3_PAGES = 12008;
+ private static final int SIZE_FOR_FIT_3_PAGES = PAGE_SIZE * 2 + PAGE_SIZE
/ 2;
/** Listenning logger. */
private ListeningTestLogger listenLog;
@@ -462,7 +461,7 @@ public class IgniteSnapshotManagerSelfTest extends
AbstractSnapshotSelfTest {
IgniteEx ignite = startGridsWithoutCache(2);
- assertEquals(DFLT_PAGE_SIZE,
ignite.configuration().getDataStorageConfiguration().getPageSize());
+ assertEquals(PAGE_SIZE,
ignite.configuration().getDataStorageConfiguration().getPageSize());
for (int i = 0; i < keys; i++)
ignite.getOrCreateCache(ccfg).put(i, new Value(new
byte[SIZE_FOR_FIT_3_PAGES]));
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
index 0c9df199145..6781c2e31d2 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
@@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteInternalFuture;
@@ -57,7 +58,10 @@ public class IgniteSnapshotWithMetastorageTest extends
AbstractSnapshotSelfTest
/** @throws Exception If fails. */
@Test
public void testClusterSnapshotWithMetastorage() throws Exception {
- IgniteEx ignite = startGridsWithCache(2, dfltCacheCfg,
CACHE_KEYS_RANGE);
+ CacheConfiguration<Integer, Object> cfg2 = txCacheConfig(new
CacheConfiguration<>("test"));
+
+ IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE,
Integer::new, dfltCacheCfg, cfg2);
+
startClientGrid();
ignite.context().distributedMetastorage().write("key", "value");
diff --git
a/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridCacheTestContext.java
b/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridCacheTestContext.java
index 018fccbe6c1..0bb13e9710d 100644
---
a/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridCacheTestContext.java
+++
b/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridCacheTestContext.java
@@ -22,7 +22,6 @@ import org.apache.ignite.cache.store.CacheStore;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheAffinitySharedManager;
-import org.apache.ignite.internal.processors.cache.CacheCompressionManager;
import org.apache.ignite.internal.processors.cache.CacheDiagnosticManager;
import
org.apache.ignite.internal.processors.cache.CacheOsConflictResolutionManager;
import org.apache.ignite.internal.processors.cache.CacheType;
@@ -97,7 +96,6 @@ public class GridCacheTestContext<K, V> extends
GridCacheContext<K, V> {
true,
false,
false,
- new CacheCompressionManager(),
new GridCacheEventManager(),
new CacheOsStoreManager(null, new CacheConfiguration()),
new GridCacheEvictionManager(),
diff --git
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParser.java
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParser.java
index 2ce890ca8d5..6b97f9696be 100644
---
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParser.java
+++
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParser.java
@@ -26,7 +26,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
*/
class JavaVersionCommandParser {
/** Pattern for parsing 'java -version' command output. */
- private static final Pattern versionPattern = Pattern.compile("java
version \"([^\"]+)\".*", Pattern.DOTALL);
+ private static final Pattern versionPattern =
Pattern.compile("(java|openjdk) version \"([^\"]+)\".*", Pattern.DOTALL);
/**
* Extracts major java version (like '17' or '1.8') from 'java -version'
output.
@@ -41,7 +41,7 @@ class JavaVersionCommandParser {
versionCommandOutput + "'");
}
- String fullJavaVersion = matcher.group(1);
+ String fullJavaVersion = matcher.group(2);
return U.majorJavaVersion(fullJavaVersion);
}
diff --git
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParserTest.java
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParserTest.java
index cbd12b910b4..07bb067e2cd 100644
---
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParserTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/JavaVersionCommandParserTest.java
@@ -49,6 +49,12 @@ public class JavaVersionCommandParserTest {
"Java HotSpot(TM) Server VM (build 25.311-b11, mixed
mode)",
8
},
+ new Object[] {
+ "openjdk version \"1.8.0_352\"\n" +
+ "OpenJDK Runtime Environment (build
1.8.0_352-8u352-ga-1~22.04-b08)\n" +
+ "OpenJDK 64-Bit Server VM (build 25.352-b08, mixed mode)",
+ 8
+ },
new Object[]{
"java version \"11.0.6\" 2020-01-14 LTS\n" +
"Java(TM) SE Runtime Environment 18.9 (build
11.0.6+8-LTS)\n" +
diff --git
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotTestSuite.java
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotTestSuite.java
index 33419af614b..7bcbd34be38 100644
---
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotTestSuite.java
+++
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotTestSuite.java
@@ -17,6 +17,9 @@
package org.apache.ignite.testsuites;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.EncryptedSnapshotTest;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteClusterSnapshotCheckTest;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteClusterSnapshotDeltaTest;
@@ -32,27 +35,38 @@ import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSn
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotRestoreFromRemoteTest;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotWithMetastorageTest;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.PlainSnapshotTest;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.DynamicSuite;
import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
/** */
-@RunWith(Suite.class)
[email protected]({
- IgniteSnapshotManagerSelfTest.class,
- IgniteClusterSnapshotSelfTest.class,
- IgniteSnapshotRemoteRequestTest.class,
- IgniteClusterSnapshotCheckTest.class,
- IgniteSnapshotWithMetastorageTest.class,
- IgniteSnapshotMXBeanTest.class,
- IgniteClusterSnapshotRestoreSelfTest.class,
- IgniteClusterSnapshotHandlerTest.class,
- IgniteSnapshotRestoreFromRemoteTest.class,
- PlainSnapshotTest.class,
- EncryptedSnapshotTest.class,
- IgniteClusterSnapshotWalRecordTest.class,
- IgniteClusterSnapshotStreamerTest.class,
- IgniteSnapshotConsistencyTest.class,
- IgniteClusterSnapshotDeltaTest.class
-})
+@RunWith(DynamicSuite.class)
public class IgniteSnapshotTestSuite {
+ /** */
+ public static List<Class<?>> suite() {
+ List<Class<?>> suite = new ArrayList<>();
+
+ addSnapshotTests(suite, null);
+
+ return suite;
+ }
+
+ /** */
+ public static void addSnapshotTests(List<Class<?>> suite,
Collection<Class> ignoredTests) {
+ GridTestUtils.addTestIfNeeded(suite,
IgniteSnapshotManagerSelfTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotSelfTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteSnapshotRemoteRequestTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotCheckTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteSnapshotWithMetastorageTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite, IgniteSnapshotMXBeanTest.class,
ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotRestoreSelfTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotHandlerTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteSnapshotRestoreFromRemoteTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite, PlainSnapshotTest.class,
ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite, EncryptedSnapshotTest.class,
ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotWalRecordTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotStreamerTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteSnapshotConsistencyTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotDeltaTest.class, ignoredTests);
+ }
}
diff --git
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotWithIndexingTestSuite.java
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotWithIndexingTestSuite.java
index be36d972ca1..240e8161226 100644
---
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotWithIndexingTestSuite.java
+++
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotWithIndexingTestSuite.java
@@ -17,20 +17,34 @@
package org.apache.ignite.testsuites;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteClusterSnapshotCheckWithIndexesTest;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteClusterSnapshotMetricsTest;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteClusterSnapshotRestoreWithIndexingTest;
import
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteClusterSnapshotWithIndexesTest;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.DynamicSuite;
import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
/** */
-@RunWith(Suite.class)
[email protected]({
- IgniteClusterSnapshotWithIndexesTest.class,
- IgniteClusterSnapshotCheckWithIndexesTest.class,
- IgniteClusterSnapshotRestoreWithIndexingTest.class,
- IgniteClusterSnapshotMetricsTest.class
-})
+@RunWith(DynamicSuite.class)
public class IgniteSnapshotWithIndexingTestSuite {
+ /** */
+ public static List<Class<?>> suite() {
+ List<Class<?>> suite = new ArrayList<>();
+
+ addSnapshotTests(suite, null);
+
+ return suite;
+ }
+
+ /** */
+ public static void addSnapshotTests(List<Class<?>> suite,
Collection<Class> ignoredTests) {
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotWithIndexesTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotCheckWithIndexesTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotRestoreWithIndexingTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
IgniteClusterSnapshotMetricsTest.class, ignoredTests);
+ }
}