You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dg...@apache.org on 2019/07/16 11:14:44 UTC

[ignite] branch master updated: IGNITE-11982 Fix bugs of pds

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

dgovorukhin 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 9c32314  IGNITE-11982 Fix bugs of pds
9c32314 is described below

commit 9c323149db1cee0ff6586389def059a85428b116
Author: Anton Kalashnikov <ka...@yandex.ru>
AuthorDate: Tue Jul 16 14:14:22 2019 +0300

    IGNITE-11982 Fix bugs of pds
    
    Co-authored-by: Ivan Bessonov <be...@gmail.com>
    Co-authored-by: Sergey Chugunov <se...@gmail.com>
    Co-authored-by: Dmitriy Govorukhin <dm...@gmail.com>
    Signed-off-by: Dmitriy Govorukhin <dm...@gmail.com>
---
 .../thin/JdbcThinDataPageScanPropertySelfTest.java |   9 +-
 .../compatibility/PdsWithTtlCompatibilityTest.java | 197 --------------------
 .../IgniteCompatibilityBasicTestSuite.java         |   3 -
 modules/compress/pom.xml                           |  15 ++
 .../DiskPageCompressionConfigValidationTest.java   | 161 +++++++++++++++++
 .../testsuites/IgnitePdsCompressionTestSuite.java  |   2 +
 modules/compress/src/test/resources/encryption.jks | Bin 0 -> 6737 bytes
 .../apache/ignite/IgniteJdbcThinDataSource.java    |  17 --
 .../org/apache/ignite/cache/query/ScanQuery.java   |  31 ----
 .../apache/ignite/cache/query/SqlFieldsQuery.java  |  32 ----
 .../org/apache/ignite/cache/query/SqlQuery.java    |  31 ----
 .../org/apache/ignite/internal/IgniteKernal.java   |  26 ++-
 .../org/apache/ignite/internal/IgnitionEx.java     |  65 ++++---
 .../internal/commandline/cache/CacheCommands.java  |   3 +-
 .../internal/logger/platform/PlatformLogger.java   |   2 +-
 .../internal/pagemem/wal/record/WALRecord.java     | 166 ++++++++++-------
 .../processors/cache/CacheGroupContext.java        |   6 +-
 .../processors/cache/GridCacheProcessor.java       | 104 +++++++----
 .../cache/IgniteCacheOffheapManagerImpl.java       |  12 +-
 .../processors/cache/IgniteCacheProxyImpl.java     |   2 +-
 .../internal/processors/cache/WalStateManager.java |  13 +-
 .../GridCacheDatabaseSharedManager.java            |  60 +++---
 .../IgniteCacheDatabaseSharedManager.java          |   4 +-
 .../cache/persistence/pagemem/PageMemoryImpl.java  |  13 +-
 .../cache/persistence/tree/BPlusTree.java          |  13 +-
 .../wal/AbstractWalRecordsIterator.java            |  15 +-
 .../persistence/wal/FileWriteAheadLogManager.java  |  11 +-
 .../wal/serializer/RecordV1Serializer.java         |  15 +-
 .../wal/serializer/RecordV2Serializer.java         |   4 +-
 .../processors/cache/tree/CacheDataTree.java       |   8 +-
 .../persistence/DistributedMetaStorageImpl.java    |  52 +++++-
 .../processors/odbc/jdbc/JdbcRequestHandler.java   |   5 +-
 .../twostep/messages/GridQueryNextPageRequest.java |   2 -
 .../util/tostring/GridToStringBuilder.java         |  47 ++++-
 .../util/tostring/GridToStringClassDescriptor.java |  12 +-
 .../util/tostring/GridToStringFieldDescriptor.java |  98 +++++++++-
 .../internal/metric/IoStatisticsCacheSelfTest.java |   2 +-
 .../pagemem/wal/record/WALRecordTest.java}         |  47 ++---
 .../cache/IgniteClusterActivateDeactivateTest.java |  52 +++---
 .../GridCacheRebalancingWithAsyncClearingTest.java |  12 +-
 .../IgnitePdsRemoveDuringRebalancingTest.java      |   8 +-
 ...tePdsRestartAfterFailedToWriteMetaPageTest.java | 201 +++++++++++++++++++++
 ...IgnitePdsCacheWalDisabledOnRebalancingTest.java |   4 +
 .../db/IgnitePdsReserveWalSegmentsTest.java        |   6 +-
 .../db/wal/WalDeletionArchiveAbstractTest.java     |   5 +-
 .../IgniteAbstractWalIteratorInvalidCrcTest.java   |   2 +-
 .../cache/query/CacheDataPageScanQueryTest.java    |  16 +-
 .../cluster/BaselineAutoAdjustInMemoryTest.java    |  26 +++
 .../ignite/testsuites/IgniteBasicTestSuite.java    |   3 +
 .../ignite/testsuites/IgnitePdsTestSuite4.java     |   5 +
 .../GridInternalTaskUnusedWalSegmentsTest.java     |  17 +-
 .../processors/query/h2/IgniteH2Indexing.java      |  16 +-
 .../processors/query/h2/QueryParameters.java       |   5 +-
 .../query/h2/twostep/GridMapQueryExecutor.java     |   1 -
 .../IgniteCacheReplicatedQuerySelfTest.java        |  27 +--
 .../processors/cache/index/H2RowCacheSelfTest.java |  15 +-
 .../processors/query/h2/QueryDataPageScanTest.java |  31 ++--
 parent/pom.xml                                     |   2 +-
 58 files changed, 1068 insertions(+), 691 deletions(-)

diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDataPageScanPropertySelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDataPageScanPropertySelfTest.java
index 9bd9064..5692451 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDataPageScanPropertySelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDataPageScanPropertySelfTest.java
@@ -33,6 +33,7 @@ import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.jetbrains.annotations.Nullable;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -87,6 +88,7 @@ public class JdbcThinDataPageScanPropertySelfTest extends GridCommonAbstractTest
      * Verify single queries.
      */
     @Test
+    @Ignore("https://ggsystems.atlassian.net/browse/GG-20800")
     public void testDataPageScanSingle() throws Exception {
         checkDataPageScan("SELECT * FROM TEST WHERE val > 42", null);
         checkDataPageScan("UPDATE TEST SET val = val + 1 WHERE val > 10", null);
@@ -102,6 +104,7 @@ public class JdbcThinDataPageScanPropertySelfTest extends GridCommonAbstractTest
      * Verify the case property is set on connection and batched operations are performed.
      */
     @Test
+    @Ignore("https://ggsystems.atlassian.net/browse/GG-20800")
     public void testDataPageScanBatching() throws Exception {
         checkDataPageScanInBatch("UPDATE TEST SET val = ? WHERE val > 10", null);
 
@@ -144,8 +147,7 @@ public class JdbcThinDataPageScanPropertySelfTest extends GridCommonAbstractTest
         assertTrue("Original query have not been executed.", containsOrig);
 
         IndexingWithQueries.queries.forEach(query ->
-            assertEquals("Data page scan flag value is unexpected for query " + query, dps,
-                query.isDataPageScanEnabled())
+            assertEquals("Data page scan flag value is unexpected for query " + query, dps, null)
         );
 
         int executed = IndexingWithQueries.queries.size();
@@ -177,8 +179,7 @@ public class JdbcThinDataPageScanPropertySelfTest extends GridCommonAbstractTest
         assertTrue("Original query have not been executed.", containsOrig);
 
         IndexingWithQueries.queries.forEach(executedQry ->
-            assertEquals("Data page scan flag value is unexpected for query " + executedQry, dps,
-                executedQry.isDataPageScanEnabled())
+            assertEquals("Data page scan flag value is unexpected for query " + executedQry, dps, null)
         );
 
         int executed = IndexingWithQueries.queries.size();
diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/PdsWithTtlCompatibilityTest.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/PdsWithTtlCompatibilityTest.java
deleted file mode 100644
index 637616d..0000000
--- a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/PdsWithTtlCompatibilityTest.java
+++ /dev/null
@@ -1,197 +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.compatibility;
-
-import java.util.Collection;
-import java.util.concurrent.TimeUnit;
-import javax.cache.Cache;
-import javax.cache.expiry.AccessedExpiryPolicy;
-import javax.cache.expiry.Duration;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CacheAtomicityMode;
-import org.apache.ignite.cache.CacheWriteSynchronizationMode;
-import org.apache.ignite.compatibility.persistence.IgnitePersistenceCompatibilityAbstractTest;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.DataRegionConfiguration;
-import org.apache.ignite.configuration.DataStorageConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.configuration.MemoryConfiguration;
-import org.apache.ignite.configuration.PersistentStoreConfiguration;
-import org.apache.ignite.configuration.WALMode;
-import org.apache.ignite.internal.IgniteEx;
-import org.apache.ignite.internal.IgniteInterruptedCheckedException;
-import org.apache.ignite.internal.processors.cache.GridCacheAbstractFullApiSelfTest;
-import org.apache.ignite.internal.processors.cache.persistence.migration.UpgradePendingTreeToPerPartitionTask;
-import org.apache.ignite.internal.util.typedef.PA;
-import org.apache.ignite.lang.IgniteFuture;
-import org.apache.ignite.lang.IgniteInClosure;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.testframework.GridTestUtils;
-import org.junit.Test;
-
-/**
- * Test PendingTree upgrading to per-partition basis. Test fill cache with persistence enabled and with ExpirePolicy
- * configured on ignite-2.1 version and check if entries will be correctly expired when a new version node started.
- *
- * Note: Test for ignite-2.3 version will always fails due to entry ttl update fails with assertion on checkpoint lock
- * check.
- */
-public class PdsWithTtlCompatibilityTest extends IgnitePersistenceCompatibilityAbstractTest {
-    /** */
-    static final String TEST_CACHE_NAME = PdsWithTtlCompatibilityTest.class.getSimpleName();
-
-    /** */
-    static final int DURATION_SEC = 10;
-
-    /** */
-    private static final int ENTRIES_CNT = 100;
-
-    /** {@inheritDoc} */
-    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
-        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
-
-        cfg.setPeerClassLoadingEnabled(false);
-
-        cfg.setDataStorageConfiguration(
-            new DataStorageConfiguration()
-                .setDefaultDataRegionConfiguration(
-                    new DataRegionConfiguration()
-                        .setMaxSize(32L * 1024 * 1024)
-                        .setPersistenceEnabled(true)
-                        .setCheckpointPageBufferSize(16L * 1024 * 1024)
-                ).setWalMode(WALMode.LOG_ONLY));
-
-        return cfg;
-    }
-
-    /**
-     * Tests opportunity to read data from previous Ignite DB version.
-     *
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testNodeStartByOldVersionPersistenceData_2_1() throws Exception {
-        doTestStartupWithOldVersion("2.1.0");
-    }
-
-    /**
-     * Tests opportunity to read data from previous Ignite DB version.
-     *
-     * @param igniteVer 3-digits version of ignite
-     * @throws Exception If failed.
-     */
-    protected void doTestStartupWithOldVersion(String igniteVer) throws Exception {
-        try {
-            startGrid(1, igniteVer, new ConfigurationClosure(), new PostStartupClosure());
-
-            stopAllGrids();
-
-            IgniteEx ignite = startGrid(0);
-
-            assertEquals(1, ignite.context().discovery().topologyVersion());
-
-            ignite.active(true);
-
-            validateResultingCacheData(ignite, ignite.cache(TEST_CACHE_NAME));
-        }
-        finally {
-            stopAllGrids();
-        }
-    }
-
-    /**
-     * @param cache to be filled by different keys and values. Results may be validated in {@link
-     * #validateResultingCacheData(Ignite, IgniteCache)}.
-     */
-    public static void saveCacheData(Cache<Object, Object> cache) {
-        for (int i = 0; i < ENTRIES_CNT; i++)
-            cache.put(i, "data-" + i);
-
-        //Touch
-        for (int i = 0; i < ENTRIES_CNT; i++)
-            assertNotNull(cache.get(i));
-    }
-
-    /**
-     * Asserts cache contained all expected values as it was saved before.
-     *
-     * @param cache cache should be filled using {@link #saveCacheData(Cache)}.
-     */
-    public static void validateResultingCacheData(Ignite ignite,
-        IgniteCache<Object, Object> cache) throws IgniteInterruptedCheckedException {
-
-        final long expireTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(DURATION_SEC + 1);
-
-        final IgniteFuture<Collection<Boolean>> future = ignite.compute().broadcastAsync(new UpgradePendingTreeToPerPartitionTask());
-
-        GridTestUtils.waitForCondition(new PA() {
-            @Override public boolean apply() {
-                return future.isDone() && expireTime < System.currentTimeMillis();
-            }
-        }, TimeUnit.SECONDS.toMillis(DURATION_SEC + 2));
-
-        for (Boolean res : future.get())
-            assertTrue(res);
-
-        for (int i = 0; i < ENTRIES_CNT; i++)
-            assertNull(cache.get(i));
-    }
-
-    /** */
-    public static class ConfigurationClosure implements IgniteInClosure<IgniteConfiguration> {
-        /** {@inheritDoc} */
-        @Override public void apply(IgniteConfiguration cfg) {
-            cfg.setLocalHost("127.0.0.1");
-
-            TcpDiscoverySpi disco = new TcpDiscoverySpi();
-            disco.setIpFinder(GridCacheAbstractFullApiSelfTest.LOCAL_IP_FINDER);
-
-            cfg.setDiscoverySpi(disco);
-
-            cfg.setPeerClassLoadingEnabled(false);
-
-            cfg.setMemoryConfiguration(new MemoryConfiguration().setDefaultMemoryPolicySize(256L * 1024 * 1024));
-            cfg.setPersistentStoreConfiguration(new PersistentStoreConfiguration().setWalMode(WALMode.LOG_ONLY)
-                .setCheckpointingPageBufferSize(16L * 1024 * 1024));
-        }
-    }
-
-    /** */
-    public static class PostStartupClosure implements IgniteInClosure<Ignite> {
-        /** {@inheritDoc} */
-        @Override public void apply(Ignite ignite) {
-            ignite.active(true);
-
-            CacheConfiguration<Object, Object> cacheCfg = new CacheConfiguration<>();
-            cacheCfg.setName(TEST_CACHE_NAME);
-            cacheCfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-            cacheCfg.setBackups(1);
-            cacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
-            cacheCfg.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(new Duration(TimeUnit.SECONDS, DURATION_SEC)));
-            cacheCfg.setEagerTtl(true);
-            cacheCfg.setGroupName("myGroup");
-
-            IgniteCache<Object, Object> cache = ignite.createCache(cacheCfg);
-
-            saveCacheData(cache);
-
-            ignite.active(false);
-        }
-    }
-}
diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java
index 014ee5e..19ad466 100644
--- a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java
+++ b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.compatibility.testsuites;
 
-import org.apache.ignite.compatibility.PdsWithTtlCompatibilityTest;
 import org.apache.ignite.compatibility.persistence.FoldersReuseCompatibilityTest;
 import org.apache.ignite.compatibility.persistence.MigratingToWalV2SerializerWithCompactionTest;
 import org.apache.ignite.compatibility.persistence.PersistenceBasicCompatibilityTest;
@@ -31,8 +30,6 @@ import org.junit.runners.Suite;
 @Suite.SuiteClasses({
     PersistenceBasicCompatibilityTest.class,
 
-    PdsWithTtlCompatibilityTest.class,
-
     FoldersReuseCompatibilityTest.class,
 
     MigratingToWalV2SerializerWithCompactionTest.class
diff --git a/modules/compress/pom.xml b/modules/compress/pom.xml
index efcf18f..800d349 100644
--- a/modules/compress/pom.xml
+++ b/modules/compress/pom.xml
@@ -120,6 +120,21 @@
     <build>
         <plugins>
             <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-libs</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <excludeTransitive>false</excludeTransitive>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <executions>
diff --git a/modules/compress/src/test/java/org/apache/ignite/internal/processors/compress/DiskPageCompressionConfigValidationTest.java b/modules/compress/src/test/java/org/apache/ignite/internal/processors/compress/DiskPageCompressionConfigValidationTest.java
new file mode 100644
index 0000000..0e4a348
--- /dev/null
+++ b/modules/compress/src/test/java/org/apache/ignite/internal/processors/compress/DiskPageCompressionConfigValidationTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.util.List;
+import org.apache.ignite.Ignite;
+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.util.IgniteUtils;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static org.apache.ignite.configuration.DataStorageConfiguration.MAX_PAGE_SIZE;
+import static org.apache.ignite.configuration.WALMode.FSYNC;
+
+/**
+ * Test verifies that Disk Page Compression feature cannot be used together with Encryption feature,
+ * corresponding validation rule is triggered when an attempt to start cache with such configuration is made.
+ */
+public class DiskPageCompressionConfigValidationTest extends GridCommonAbstractTest {
+    /** */
+    private static final String KEYSTORE_PATH =
+        IgniteUtils.resolveIgnitePath("modules/compress/src/test/resources/encryption.jks").getAbsolutePath();
+
+    /** */
+    private static final String KEYSTORE_PASSWORD = "encryption";
+
+    /** */
+    private static final String INVALID_CFG_CACHE_NAME = "encrypted_with_compression";
+
+    /** */
+    private CacheConfiguration ccfg;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi();
+
+        encSpi.setKeyStorePath(KEYSTORE_PATH);
+        encSpi.setKeyStorePassword(KEYSTORE_PASSWORD.toCharArray());
+
+        cfg.setEncryptionSpi(encSpi);
+
+        DataStorageConfiguration dsCfg = new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration()
+                    .setMaxSize(10L * 1024 * 1024)
+                    .setPersistenceEnabled(true))
+            .setPageSize(MAX_PAGE_SIZE)
+            .setWalMode(FSYNC);
+
+        cfg.setDataStorageConfiguration(dsCfg);
+
+        if (ccfg != null)
+            cfg.setCacheConfiguration(ccfg);
+
+        return cfg;
+    }
+
+    /**
+     * Test verifies that dynamic cache request with incorrect configuration (encryption and disk page compression
+     * are mixed together) is rejected, corresponding exception is thrown.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testIncorrectDynamicCacheStartRequest() throws Exception {
+        Ignite ig = startGrid();
+
+        ig.cluster().active(true);
+
+        boolean expEThrown = false;
+
+        try {
+            ig.createCache(new CacheConfiguration<>(INVALID_CFG_CACHE_NAME)
+                .setEncryptionEnabled(true)
+                .setDiskPageCompression(DiskPageCompression.ZSTD)
+            );
+        }
+        catch (Exception e) {
+            List<Throwable> suppressedExceptions = X.getSuppressedList(e);
+
+            if (suppressedExceptions.size() == 1) {
+                Throwable cause = suppressedExceptions.get(0).getCause();
+
+                if (cause != null && cause.getMessage() != null && cause.getMessage()
+                    .startsWith("Encryption cannot be used with disk page compression"))
+                    expEThrown = true;
+                else
+                    throw e;
+            }
+            else
+                throw e;
+        }
+
+        assertTrue("Expected exception about cache configuration validation has not been thrown", expEThrown);
+    }
+
+    /**
+     * Test verifies that node with incorrect static configuration (encryption and disk page compression
+     * are mixed together) fails to start, corresponding exception is thrown.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testIncorrectStaticCacheConfiguration() throws Exception {
+        ccfg = new CacheConfiguration(INVALID_CFG_CACHE_NAME)
+            .setEncryptionEnabled(true)
+            .setDiskPageCompression(DiskPageCompression.ZSTD);
+
+        boolean expEThrown = false;
+
+        try {
+            startGrid();
+        }
+        catch (Exception e) {
+            String msg = e.getMessage();
+
+            if (msg != null && msg.contains("Encryption cannot be used with disk page compression"))
+                expEThrown = true;
+            else
+                throw e;
+        }
+
+        assertTrue("Expected exception about cache configuration validation has not been thrown", expEThrown);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+}
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 c24243e..a13427c 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
@@ -25,6 +25,7 @@ import org.apache.ignite.internal.processors.cache.persistence.db.wal.WalRecover
 import org.apache.ignite.internal.processors.cache.persistence.db.wal.WalRecoveryWithPageCompressionTest;
 import org.apache.ignite.internal.processors.compress.CompressionConfigurationTest;
 import org.apache.ignite.internal.processors.compress.CompressionProcessorTest;
+import org.apache.ignite.internal.processors.compress.DiskPageCompressionConfigValidationTest;
 import org.apache.ignite.internal.processors.compress.DiskPageCompressionIntegrationAsyncTest;
 import org.apache.ignite.internal.processors.compress.DiskPageCompressionIntegrationTest;
 import org.apache.ignite.internal.processors.compress.FileSystemUtilsTest;
@@ -49,6 +50,7 @@ public class IgnitePdsCompressionTestSuite {
         suite.add(CompressionProcessorTest.class);
         suite.add(FileSystemUtilsTest.class);
         suite.add(DiskPageCompressionIntegrationTest.class);
+        suite.add(DiskPageCompressionConfigValidationTest.class);
         suite.add(DiskPageCompressionIntegrationAsyncTest.class);
 
         // WAL page records compression.
diff --git a/modules/compress/src/test/resources/encryption.jks b/modules/compress/src/test/resources/encryption.jks
new file mode 100644
index 0000000..b4610ad
Binary files /dev/null and b/modules/compress/src/test/resources/encryption.jks differ
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDataSource.java b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDataSource.java
index f6f0d63..3887717 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDataSource.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDataSource.java
@@ -30,7 +30,6 @@ import org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl;
 import org.apache.ignite.internal.processors.odbc.SqlStateCode;
 import org.apache.ignite.internal.util.HostAndPortRange;
 import org.apache.ignite.internal.util.typedef.F;
-import org.jetbrains.annotations.Nullable;
 
 /**
  * JDBC thin DataSource implementation.
@@ -611,20 +610,4 @@ public class IgniteJdbcThinDataSource implements DataSource, Serializable {
     public String getPassword() {
         return props.getPassword();
     }
-
-    /**
-     * @return {@code True} if data page scan support is enabled for this connection, {@code false} if it's disabled and
-     * {@code null} for server default.
-     */
-    @Nullable public Boolean isDataPageScanEnabled() {
-        return props.isDataPageScanEnabled();
-    }
-
-    /**
-     * @param dataPageScan if {@code True} then data page scan support is enabled for this connection, if {@code false}
-     * then it's disabled, if {@code null} then server should use its default settings.
-     */
-    public void setDataPageScanEnabled(@Nullable Boolean dataPageScan) {
-        props.setDataPageScanEnabled(dataPageScan);
-    }
 }
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/ScanQuery.java b/modules/core/src/main/java/org/apache/ignite/cache/query/ScanQuery.java
index f63581b..abf89e1 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/ScanQuery.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/ScanQuery.java
@@ -19,8 +19,6 @@ package org.apache.ignite.cache.query;
 
 import javax.cache.Cache;
 import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CacheAtomicityMode;
-import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.lang.IgniteBiPredicate;
 import org.jetbrains.annotations.Nullable;
@@ -40,9 +38,6 @@ public final class ScanQuery<K, V> extends Query<Cache.Entry<K, V>> {
     /** */
     private Integer part;
 
-    /** */
-    private Boolean dataPageScanEnabled;
-
     /**
      * Create scan query returning all entries.
      */
@@ -123,32 +118,6 @@ public final class ScanQuery<K, V> extends Query<Cache.Entry<K, V>> {
         return part;
     }
 
-    /**
-     * Sets data page scan enabled or disabled.
-     *
-     * Makes sense only with enabled {@link DataRegionConfiguration#setPersistenceEnabled persistence}
-     * and generally improves performance.
-     * When enabled, result may miss some concurrent updates or produce duplicates for the same key.
-     * To avoid these issues use with {@link CacheAtomicityMode#TRANSACTIONAL_SNAPSHOT}.
-     *
-     * @param dataPageScanEnabled {@code true} If data page scan enabled, {@code false} if not, and {@code null} if not set.
-     * @return {@code this} for chaining.
-     */
-    public ScanQuery<K, V> setDataPageScanEnabled(Boolean dataPageScanEnabled) {
-        this.dataPageScanEnabled = dataPageScanEnabled;
-
-        return this;
-    }
-
-    /**
-     * Checks if data page scan enabled.
-     *
-     * @return {@code true} If data page scan enabled, {@code false} if not, and {@code null} if not set.
-     */
-    public Boolean isDataPageScanEnabled() {
-        return dataPageScanEnabled;
-    }
-
     /** {@inheritDoc} */
     @Override public ScanQuery<K, V> setPageSize(int pageSize) {
         return (ScanQuery<K, V>)super.setPageSize(pageSize);
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
index 7ac80e8..f00d882 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
@@ -20,8 +20,6 @@ package org.apache.ignite.cache.query;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CacheAtomicityMode;
-import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.internal.A;
@@ -88,9 +86,6 @@ public class SqlFieldsQuery extends Query<List<?>> {
     /** Schema. */
     private String schema;
 
-    /** */
-    private Boolean dataPageScanEnabled;
-
     /**
      * Update internal batch size. Default is 1 to prevent deadlock on update where keys sequence are different in
      * several concurrent updates.
@@ -113,7 +108,6 @@ public class SqlFieldsQuery extends Query<List<?>> {
         lazy = qry.lazy;
         parts = qry.parts;
         schema = qry.schema;
-        dataPageScanEnabled = qry.dataPageScanEnabled;
         updateBatchSize = qry.updateBatchSize;
     }
 
@@ -393,32 +387,6 @@ public class SqlFieldsQuery extends Query<List<?>> {
     }
 
     /**
-     * Sets data page scan enabled or disabled.
-     *
-     * Makes sense only with enabled {@link DataRegionConfiguration#setPersistenceEnabled persistence}
-     * and generally improves performance of full-scan SQL queries.
-     * When enabled, result may miss some concurrent updates or produce duplicates for the same key.
-     * To avoid these issues use with {@link CacheAtomicityMode#TRANSACTIONAL_SNAPSHOT}.
-     *
-     * @param dataPageScanEnabled {@code true} If data page scan enabled, {@code false} if not, and {@code null} if not set.
-     * @return {@code this} for chaining.
-     */
-    public SqlFieldsQuery setDataPageScanEnabled(Boolean dataPageScanEnabled) {
-        this.dataPageScanEnabled = dataPageScanEnabled;
-
-        return this;
-    }
-
-    /**
-     * Checks if data page scan enabled.
-     *
-     * @return {@code true} If data page scan enabled, {@code false} if not, and {@code null} if not set.
-     */
-    public Boolean isDataPageScanEnabled() {
-        return dataPageScanEnabled;
-    }
-
-    /**
      * Gets update internal bach size.
      * Default is 1 to prevent deadlock on update where keys sequence are different in
      * several concurrent updates.
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlQuery.java b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlQuery.java
index 74c3ad3..d4c4b88 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlQuery.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlQuery.java
@@ -20,8 +20,6 @@ package org.apache.ignite.cache.query;
 import java.util.concurrent.TimeUnit;
 import javax.cache.Cache;
 import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CacheAtomicityMode;
-import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.internal.A;
@@ -65,9 +63,6 @@ public final class SqlQuery<K, V> extends Query<Cache.Entry<K, V>> {
     /** Partitions for query */
     private int[] parts;
 
-    /** */
-    private Boolean dataPageScanEnabled;
-
     /**
      * Constructs query for the given type name and SQL query.
      *
@@ -288,32 +283,6 @@ public final class SqlQuery<K, V> extends Query<Cache.Entry<K, V>> {
         return this;
     }
 
-    /**
-     * Sets data page scan enabled or disabled.
-     *
-     * Makes sense only with enabled {@link DataRegionConfiguration#setPersistenceEnabled persistence}
-     * and generally improves performance of full-scan SQL queries.
-     * When enabled, result may miss some concurrent updates or produce duplicates for the same key.
-     * To avoid these issues use with {@link CacheAtomicityMode#TRANSACTIONAL_SNAPSHOT}.
-     *
-     * @param dataPageScanEnabled {@code true} If data page scan enabled, {@code false} if not, and {@code null} if not set.
-     * @return {@code this} for chaining.
-     */
-    public SqlQuery<K,V> setDataPageScanEnabled(Boolean dataPageScanEnabled) {
-        this.dataPageScanEnabled = dataPageScanEnabled;
-
-        return this;
-    }
-
-    /**
-     * Checks if data page scan enabled.
-     *
-     * @return {@code true} If data page scan enabled, {@code false} if not, and {@code null} if not set.
-     */
-    public Boolean isDataPageScanEnabled() {
-        return dataPageScanEnabled;
-    }
-
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(SqlQuery.class, this);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index c9e6a11..cc9b77d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -184,6 +184,7 @@ import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions;
 import org.apache.ignite.internal.suggestions.JvmConfigurationSuggestions;
 import org.apache.ignite.internal.suggestions.OsConfigurationSuggestions;
 import org.apache.ignite.internal.util.StripedExecutor;
+import org.apache.ignite.internal.util.TimeBag;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -903,7 +904,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
         @Nullable final Map<String, ? extends ExecutorService> customExecSvcs,
         GridAbsClosure errHnd,
         WorkersRegistry workerRegistry,
-        Thread.UncaughtExceptionHandler hnd
+        Thread.UncaughtExceptionHandler hnd,
+        TimeBag startTimer
     )
         throws IgniteCheckedException {
         gw.compareAndSet(null, new GridKernalGatewayImpl(cfg.getIgniteInstanceName()));
@@ -1127,7 +1129,13 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                 startProcessor(createComponent(DiscoveryNodeValidationProcessor.class, ctx));
                 startProcessor(new GridAffinityProcessor(ctx));
                 startProcessor(createComponent(GridSegmentationProcessor.class, ctx));
+
+                startTimer.finishGlobalStage("Start managers");
+
                 startProcessor(createComponent(IgniteCacheObjectProcessor.class, ctx));
+
+                startTimer.finishGlobalStage("Configure binary metadata");
+
                 startProcessor(createComponent(IGridClusterStateProcessor.class, ctx));
                 startProcessor(new IgniteAuthenticationProcessor(ctx));
                 startProcessor(new GridCacheProcessor(ctx));
@@ -1149,11 +1157,15 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                 startProcessor(new DistributedMetaStorageImpl(ctx));
                 startProcessor(new DistributedConfigurationProcessor(ctx));
 
+                startTimer.finishGlobalStage("Start processors");
+
                 // Start plugins.
                 for (PluginProvider provider : ctx.plugins().allProviders()) {
                     ctx.add(new GridPluginComponent(provider));
 
                     provider.start(ctx.plugins().pluginContextForProvider(provider));
+
+                    startTimer.finishGlobalStage("Start '"+ provider.name() + "' plugin");
                 }
 
                 // Start platform plugins.
@@ -1168,9 +1180,13 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
 
                 ((DistributedMetaStorageImpl)ctx.distributedMetastorage()).inMemoryReadyForRead();
 
-                ctx.cache().context().database().startMemoryRestore(ctx);
+                startTimer.finishGlobalStage("Init metastore");
+
+                ctx.cache().context().database().startMemoryRestore(ctx, startTimer);
 
                 ctx.recoveryMode(false);
+
+                startTimer.finishGlobalStage("Finish recovery");
             }
             catch (Throwable e) {
                 U.error(
@@ -1194,6 +1210,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                 gw.writeUnlock();
             }
 
+            startTimer.finishGlobalStage("Join topology");
+
             // Check whether UTF-8 is the default character encoding.
             checkFileEncoding();
 
@@ -1234,6 +1252,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
             else
                 active = joinData.active();
 
+            startTimer.finishGlobalStage("Await transition");
+
             boolean recon = false;
 
             // Callbacks.
@@ -1415,6 +1435,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
         if (!isDaemon())
             ctx.discovery().ackTopology(ctx.discovery().localJoin().joinTopologyVersion().topologyVersion(),
                 EventType.EVT_NODE_JOINED, localNode());
+
+        startTimer.finishGlobalStage("Await exchange");
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
index eeef23e..570af67 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
@@ -84,6 +84,7 @@ import org.apache.ignite.internal.processors.resource.GridSpringResourceContext;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.StripedExecutor;
+import org.apache.ignite.internal.util.TimeBag;
 import org.apache.ignite.internal.util.spring.IgniteSpringHelper;
 import org.apache.ignite.internal.util.typedef.CA;
 import org.apache.ignite.internal.util.typedef.F;
@@ -127,16 +128,17 @@ import org.apache.ignite.thread.IgniteThread;
 import org.apache.ignite.thread.IgniteThreadPoolExecutor;
 import org.jetbrains.annotations.Nullable;
 
+import static java.util.stream.Collectors.joining;
 import static org.apache.ignite.IgniteState.STARTED;
 import static org.apache.ignite.IgniteState.STOPPED;
 import static org.apache.ignite.IgniteState.STOPPED_ON_FAILURE;
 import static org.apache.ignite.IgniteState.STOPPED_ON_SEGMENTATION;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_CLIENT;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_CONFIG_URL;
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_OVERRIDE_CONSISTENT_ID;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_DEP_MODE_OVERRIDE;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_LOCAL_HOST;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_NO_SHUTDOWN_HOOK;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OVERRIDE_CONSISTENT_ID;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_RESTART_CODE;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SUCCESS_FILE;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SYSTEM_WORKER_BLOCKED_TIMEOUT;
@@ -1682,7 +1684,16 @@ public class IgnitionEx {
                 try {
                     starterThread = Thread.currentThread();
 
-                    start0(startCtx);
+                    IgniteConfiguration myCfg = initializeConfiguration(
+                        startCtx.config() != null ? startCtx.config() : new IgniteConfiguration()
+                    );
+
+                    TimeBag startNodeTimer = new TimeBag(TimeUnit.MILLISECONDS);
+
+                    start0(startCtx, myCfg, startNodeTimer);
+
+                    log.info("Node started : "
+                        + startNodeTimer.stagesTimings().stream().collect(joining(",", "[", "]")));
                 }
                 catch (Exception e) {
                     if (log != null)
@@ -1702,27 +1713,24 @@ public class IgnitionEx {
          * @param startCtx Starting context.
          * @throws IgniteCheckedException If start failed.
          */
-        private void start0(GridStartContext startCtx) throws IgniteCheckedException {
+        private void start0(GridStartContext startCtx, IgniteConfiguration cfg, TimeBag startTimer)
+            throws IgniteCheckedException {
             assert grid == null : "Grid is already started: " + name;
 
-            IgniteConfiguration cfg = startCtx.config() != null ? startCtx.config() : new IgniteConfiguration();
-
-            IgniteConfiguration myCfg = initializeConfiguration(cfg);
-
             // Set configuration URL, if any, into system property.
             if (startCtx.configUrl() != null)
                 System.setProperty(IGNITE_CONFIG_URL, startCtx.configUrl().toString());
 
             // Ensure that SPIs support multiple grid instances, if required.
             if (!startCtx.single()) {
-                ensureMultiInstanceSupport(myCfg.getDeploymentSpi());
-                ensureMultiInstanceSupport(myCfg.getCommunicationSpi());
-                ensureMultiInstanceSupport(myCfg.getDiscoverySpi());
-                ensureMultiInstanceSupport(myCfg.getCheckpointSpi());
-                ensureMultiInstanceSupport(myCfg.getEventStorageSpi());
-                ensureMultiInstanceSupport(myCfg.getCollisionSpi());
-                ensureMultiInstanceSupport(myCfg.getFailoverSpi());
-                ensureMultiInstanceSupport(myCfg.getLoadBalancingSpi());
+                ensureMultiInstanceSupport(cfg.getDeploymentSpi());
+                ensureMultiInstanceSupport(cfg.getCommunicationSpi());
+                ensureMultiInstanceSupport(cfg.getDiscoverySpi());
+                ensureMultiInstanceSupport(cfg.getCheckpointSpi());
+                ensureMultiInstanceSupport(cfg.getEventStorageSpi());
+                ensureMultiInstanceSupport(cfg.getCollisionSpi());
+                ensureMultiInstanceSupport(cfg.getFailoverSpi());
+                ensureMultiInstanceSupport(cfg.getLoadBalancingSpi());
             }
 
             validateThreadPoolSize(cfg.getPublicThreadPoolSize(), "public");
@@ -1876,14 +1884,14 @@ public class IgnitionEx {
                 "callback",
                 oomeHnd);
 
-            if (myCfg.getConnectorConfiguration() != null) {
-                validateThreadPoolSize(myCfg.getConnectorConfiguration().getThreadPoolSize(), "connector");
+            if (cfg.getConnectorConfiguration() != null) {
+                validateThreadPoolSize(cfg.getConnectorConfiguration().getThreadPoolSize(), "connector");
 
                 restExecSvc = new IgniteThreadPoolExecutor(
                     "rest",
-                    myCfg.getIgniteInstanceName(),
-                    myCfg.getConnectorConfiguration().getThreadPoolSize(),
-                    myCfg.getConnectorConfiguration().getThreadPoolSize(),
+                    cfg.getIgniteInstanceName(),
+                    cfg.getConnectorConfiguration().getThreadPoolSize(),
+                    cfg.getConnectorConfiguration().getThreadPoolSize(),
                     DFLT_THREAD_KEEP_ALIVE_TIME,
                     new LinkedBlockingQueue<>(),
                     GridIoPolicy.UNDEFINED,
@@ -1893,14 +1901,14 @@ public class IgnitionEx {
                 restExecSvc.allowCoreThreadTimeOut(true);
             }
 
-            validateThreadPoolSize(myCfg.getUtilityCacheThreadPoolSize(), "utility cache");
+            validateThreadPoolSize(cfg.getUtilityCacheThreadPoolSize(), "utility cache");
 
             utilityCacheExecSvc = new IgniteThreadPoolExecutor(
                 "utility",
                 cfg.getIgniteInstanceName(),
-                myCfg.getUtilityCacheThreadPoolSize(),
-                myCfg.getUtilityCacheThreadPoolSize(),
-                myCfg.getUtilityCacheKeepAliveTime(),
+                cfg.getUtilityCacheThreadPoolSize(),
+                cfg.getUtilityCacheThreadPoolSize(),
+                cfg.getUtilityCacheKeepAliveTime(),
                 new LinkedBlockingQueue<>(),
                 GridIoPolicy.UTILITY_CACHE_POOL,
                 oomeHnd);
@@ -1981,7 +1989,7 @@ public class IgnitionEx {
             }
 
             // Register Ignite MBean for current grid instance.
-            registerFactoryMbean(myCfg.getMBeanServer());
+            registerFactoryMbean(cfg.getMBeanServer());
 
             boolean started = false;
 
@@ -1991,8 +1999,10 @@ public class IgnitionEx {
                 // Init here to make grid available to lifecycle listeners.
                 grid = grid0;
 
+                startTimer.finishGlobalStage("Configure system pool");
+
                 grid0.start(
-                    myCfg,
+                    cfg,
                     utilityCacheExecSvc,
                     execSvc,
                     svcExecSvc,
@@ -2015,7 +2025,8 @@ public class IgnitionEx {
                         }
                     },
                     workerRegistry,
-                    oomeHnd
+                    oomeHnd,
+                    startTimer
                 );
 
                 state = STARTED;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
index 0d879c9..bcb30e7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
@@ -39,7 +39,6 @@ import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.FIND
 import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.HELP;
 import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.LIST;
 import static org.apache.ignite.internal.commandline.cache.CacheSubcommands.VALIDATE_INDEXES;
-import static org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder.DELIM;
 
 /**
  * High-level "cache" command implementation.
@@ -155,7 +154,7 @@ public class CacheCommands implements Command<CacheSubcommands> {
         Map<String, String> paramsDesc,
         String... args
     ) {
-        logger.info(INDENT + DELIM);
+        logger.info("");
         logger.info(INDENT + CommandLogger.join(" ", CACHE, cmd, CommandLogger.join(" ", args)));
         logger.info(DOUBLE_INDENT + description);
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/logger/platform/PlatformLogger.java b/modules/core/src/main/java/org/apache/ignite/internal/logger/platform/PlatformLogger.java
index c082126..cd1f897 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/logger/platform/PlatformLogger.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/logger/platform/PlatformLogger.java
@@ -77,7 +77,7 @@ public class PlatformLogger implements IgniteLogger {
 
     /** Quiet flag. */
     @GridToStringInclude
-    private static final boolean isQuiet = Boolean.valueOf(System.getProperty(IGNITE_QUIET, "true"));
+    private final boolean isQuiet = Boolean.valueOf(System.getProperty(IGNITE_QUIET, "true"));
 
     /**
      * Ctor.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
index 9cf2613..269b2843 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
@@ -23,7 +23,11 @@ import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabase
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
-import static org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordPurpose.*;
+import static org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordPurpose.CUSTOM;
+import static org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordPurpose.INTERNAL;
+import static org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordPurpose.LOGICAL;
+import static org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordPurpose.MIXED;
+import static org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordPurpose.PHYSICAL;
 
 /**
  * Log entry abstract class.
@@ -35,126 +39,126 @@ public abstract class WALRecord {
      */
     public enum RecordType {
         /** */
-        TX_RECORD (LOGICAL),
+        TX_RECORD (0, LOGICAL),
 
         /** */
-        PAGE_RECORD (PHYSICAL),
+        PAGE_RECORD (1, PHYSICAL),
 
         /** */
-        DATA_RECORD (LOGICAL),
+        DATA_RECORD (2, LOGICAL),
 
         /** Checkpoint (begin) record */
-        CHECKPOINT_RECORD (PHYSICAL),
+        CHECKPOINT_RECORD (3, PHYSICAL),
 
         /** WAL segment header record. */
-        HEADER_RECORD (INTERNAL),
+        HEADER_RECORD (4, INTERNAL),
 
         // Delta records.
 
         /** */
-        INIT_NEW_PAGE_RECORD (PHYSICAL),
+        INIT_NEW_PAGE_RECORD (5, PHYSICAL),
 
         /** */
-        DATA_PAGE_INSERT_RECORD (PHYSICAL),
+        DATA_PAGE_INSERT_RECORD (6, PHYSICAL),
 
         /** */
-        DATA_PAGE_INSERT_FRAGMENT_RECORD (PHYSICAL),
+        DATA_PAGE_INSERT_FRAGMENT_RECORD (7, PHYSICAL),
 
         /** */
-        DATA_PAGE_REMOVE_RECORD (PHYSICAL),
+        DATA_PAGE_REMOVE_RECORD (8, PHYSICAL),
 
         /** */
-        DATA_PAGE_SET_FREE_LIST_PAGE (PHYSICAL),
+        DATA_PAGE_SET_FREE_LIST_PAGE (9, PHYSICAL),
 
         /** */
-        BTREE_META_PAGE_INIT_ROOT (PHYSICAL),
+        BTREE_META_PAGE_INIT_ROOT (10, PHYSICAL),
 
         /** */
-        BTREE_META_PAGE_ADD_ROOT (PHYSICAL),
+        BTREE_META_PAGE_ADD_ROOT (11, PHYSICAL),
 
         /** */
-        BTREE_META_PAGE_CUT_ROOT (PHYSICAL),
+        BTREE_META_PAGE_CUT_ROOT (12, PHYSICAL),
 
         /** */
-        BTREE_INIT_NEW_ROOT (PHYSICAL),
+        BTREE_INIT_NEW_ROOT (13, PHYSICAL),
 
         /** */
-        BTREE_PAGE_RECYCLE (PHYSICAL),
+        BTREE_PAGE_RECYCLE (14, PHYSICAL),
 
         /** */
-        BTREE_PAGE_INSERT (PHYSICAL),
+        BTREE_PAGE_INSERT (15, PHYSICAL),
 
         /** */
-        BTREE_FIX_LEFTMOST_CHILD (PHYSICAL),
+        BTREE_FIX_LEFTMOST_CHILD (16, PHYSICAL),
 
         /** */
-        BTREE_FIX_COUNT (PHYSICAL),
+        BTREE_FIX_COUNT (17, PHYSICAL),
 
         /** */
-        BTREE_PAGE_REPLACE (PHYSICAL),
+        BTREE_PAGE_REPLACE (18, PHYSICAL),
 
         /** */
-        BTREE_PAGE_REMOVE (PHYSICAL),
+        BTREE_PAGE_REMOVE (19, PHYSICAL),
 
         /** */
-        BTREE_PAGE_INNER_REPLACE (PHYSICAL),
+        BTREE_PAGE_INNER_REPLACE (20, PHYSICAL),
 
         /** */
-        BTREE_FIX_REMOVE_ID (PHYSICAL),
+        BTREE_FIX_REMOVE_ID (21, PHYSICAL),
 
         /** */
-        BTREE_FORWARD_PAGE_SPLIT (PHYSICAL),
+        BTREE_FORWARD_PAGE_SPLIT (22, PHYSICAL),
 
         /** */
-        BTREE_EXISTING_PAGE_SPLIT (PHYSICAL),
+        BTREE_EXISTING_PAGE_SPLIT (23, PHYSICAL),
 
         /** */
-        BTREE_PAGE_MERGE (PHYSICAL),
+        BTREE_PAGE_MERGE (24, PHYSICAL),
 
         /** */
-        PAGES_LIST_SET_NEXT (PHYSICAL),
+        PAGES_LIST_SET_NEXT (25, PHYSICAL),
 
         /** */
-        PAGES_LIST_SET_PREVIOUS (PHYSICAL),
+        PAGES_LIST_SET_PREVIOUS (26, PHYSICAL),
 
         /** */
-        PAGES_LIST_INIT_NEW_PAGE (PHYSICAL),
+        PAGES_LIST_INIT_NEW_PAGE (27, PHYSICAL),
 
         /** */
-        PAGES_LIST_ADD_PAGE (PHYSICAL),
+        PAGES_LIST_ADD_PAGE (28, PHYSICAL),
 
         /** */
-        PAGES_LIST_REMOVE_PAGE (PHYSICAL),
+        PAGES_LIST_REMOVE_PAGE (29, PHYSICAL),
 
         /** */
-        META_PAGE_INIT (PHYSICAL),
+        META_PAGE_INIT (30, PHYSICAL),
 
         /** */
-        PARTITION_META_PAGE_UPDATE_COUNTERS (PHYSICAL),
+        PARTITION_META_PAGE_UPDATE_COUNTERS (31, PHYSICAL),
 
         /** Memory recovering start marker */
-        MEMORY_RECOVERY,
+        MEMORY_RECOVERY (32),
 
         /** */
-        TRACKING_PAGE_DELTA (PHYSICAL),
+        TRACKING_PAGE_DELTA (33, PHYSICAL),
 
         /** Meta page update last successful snapshot id. */
-        META_PAGE_UPDATE_LAST_SUCCESSFUL_SNAPSHOT_ID (MIXED),
+        META_PAGE_UPDATE_LAST_SUCCESSFUL_SNAPSHOT_ID (34, MIXED),
 
         /** Meta page update last successful full snapshot id. */
-        META_PAGE_UPDATE_LAST_SUCCESSFUL_FULL_SNAPSHOT_ID (MIXED),
+        META_PAGE_UPDATE_LAST_SUCCESSFUL_FULL_SNAPSHOT_ID (35, MIXED),
 
         /** Meta page update next snapshot id. */
-        META_PAGE_UPDATE_NEXT_SNAPSHOT_ID (MIXED),
+        META_PAGE_UPDATE_NEXT_SNAPSHOT_ID (36, MIXED),
 
         /** Meta page update last allocated index. */
-        META_PAGE_UPDATE_LAST_ALLOCATED_INDEX (MIXED),
+        META_PAGE_UPDATE_LAST_ALLOCATED_INDEX (37, MIXED),
 
         /** Partition meta update state. */
-        PART_META_UPDATE_STATE (MIXED),
+        PART_META_UPDATE_STATE (38, MIXED),
 
         /** Page list meta reset count record. */
-        PAGE_LIST_META_RESET_COUNT_RECORD (PHYSICAL),
+        PAGE_LIST_META_RESET_COUNT_RECORD (39, PHYSICAL),
 
         /** Switch segment record.
          *  Marker record for indicate end of segment.
@@ -163,58 +167,64 @@ public abstract class WALRecord {
          *  that one byte in the end,then we write SWITCH_SEGMENT_RECORD as marker end of segment.
          *  No need write CRC or WAL pointer for this record. It is byte marker record.
          *  */
-        SWITCH_SEGMENT_RECORD (INTERNAL),
+        SWITCH_SEGMENT_RECORD (40, INTERNAL),
 
         /** */
-        DATA_PAGE_UPDATE_RECORD (PHYSICAL),
+        DATA_PAGE_UPDATE_RECORD (41, PHYSICAL),
 
         /** init */
-        BTREE_META_PAGE_INIT_ROOT2 (PHYSICAL),
+        BTREE_META_PAGE_INIT_ROOT2 (42, PHYSICAL),
 
         /** Partition destroy. */
-        PARTITION_DESTROY (PHYSICAL),
+        PARTITION_DESTROY (43, PHYSICAL),
 
         /** Snapshot record. */
-        SNAPSHOT,
+        SNAPSHOT (44),
 
         /** Metastore data record. */
-        METASTORE_DATA_RECORD (LOGICAL),
+        METASTORE_DATA_RECORD (45, LOGICAL),
 
         /** Exchange record. */
-        EXCHANGE,
+        EXCHANGE (46),
 
         /** Reserved for future record. */
-        RESERVED,
+        RESERVED (47),
 
         /** Rotated id part record. */
-        ROTATED_ID_PART_RECORD (PHYSICAL),
+        ROTATED_ID_PART_RECORD (48, PHYSICAL),
 
         /** */
-        MVCC_DATA_PAGE_MARK_UPDATED_RECORD (PHYSICAL),
+        MVCC_DATA_PAGE_MARK_UPDATED_RECORD (49, PHYSICAL),
 
         /** */
-        MVCC_DATA_PAGE_TX_STATE_HINT_UPDATED_RECORD (PHYSICAL),
+        MVCC_DATA_PAGE_TX_STATE_HINT_UPDATED_RECORD (50, PHYSICAL),
 
         /** */
-        MVCC_DATA_PAGE_NEW_TX_STATE_HINT_UPDATED_RECORD (PHYSICAL),
+        MVCC_DATA_PAGE_NEW_TX_STATE_HINT_UPDATED_RECORD (51, PHYSICAL),
 
         /** Encrypted WAL-record. */
-        ENCRYPTED_RECORD (PHYSICAL),
+        ENCRYPTED_RECORD (52, PHYSICAL),
 
         /** Ecnrypted data record. */
-        ENCRYPTED_DATA_RECORD (LOGICAL),
+        ENCRYPTED_DATA_RECORD (53, LOGICAL),
 
         /** Mvcc data record. */
-        MVCC_DATA_RECORD (LOGICAL),
+        MVCC_DATA_RECORD (54, LOGICAL),
 
         /** Mvcc Tx state change record. */
-        MVCC_TX_RECORD (LOGICAL),
+        MVCC_TX_RECORD (55, LOGICAL),
+
+        /** Consistent cut record. */
+        CONSISTENT_CUT (56),
 
         /** Rollback tx record. */
-        ROLLBACK_TX_RECORD (LOGICAL),
+        ROLLBACK_TX_RECORD (57, LOGICAL),
 
         /** */
-        PARTITION_META_PAGE_UPDATE_COUNTERS_V2 (PHYSICAL);
+        PARTITION_META_PAGE_UPDATE_COUNTERS_V2 (58, PHYSICAL);
+
+        /** Index for serialization. Should be consistent throughout all versions. */
+        private final int idx;
 
         /**
          * When you're adding a new record don't forget to choose record purpose explicitly
@@ -225,17 +235,28 @@ public abstract class WALRecord {
         private final RecordPurpose purpose;
 
         /**
+         * @param idx Index for serialization.
          * @param purpose Purpose.
          */
-        RecordType(RecordPurpose purpose) {
+        RecordType(int idx, RecordPurpose purpose) {
+            assert idx >= 0 : idx;
+
+            this.idx = idx;
             this.purpose = purpose;
         }
 
         /**
-         * Default constructor.
+         * @param idx Index for serialization.
+         */
+        RecordType(int idx) {
+            this(idx, CUSTOM);
+        }
+
+        /**
+         * @return Index for serialization.
          */
-        RecordType() {
-            this(CUSTOM);
+        public int index() {
+            return idx;
         }
 
         /**
@@ -246,11 +267,24 @@ public abstract class WALRecord {
         }
 
         /** */
-        private static final RecordType[] VALS = RecordType.values();
+        private static final RecordType[] VALS;
+
+        static {
+            RecordType[] recordTypes = RecordType.values();
+
+            int maxIdx = 0;
+            for (RecordType recordType : recordTypes)
+                maxIdx = Math.max(maxIdx, recordType.idx);
+
+            VALS = new RecordType[maxIdx + 1];
+
+            for (RecordType recordType : recordTypes)
+                VALS[recordType.idx] = recordType;
+        }
 
         /** */
-        public static RecordType fromOrdinal(int ord) {
-            return ord < 0 || ord >= VALS.length ? null : VALS[ord];
+        public static RecordType fromIndex(int idx) {
+            return idx < 0 || idx >= VALS.length ? null : VALS[idx];
         }
 
         /**
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 4fc43fd..5f071fd 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
@@ -1252,13 +1252,15 @@ public class CacheGroupContext {
 
     /**
      * @param enabled Local WAL enabled flag.
+     * @param persist If {@code true} then flag state will be persisted into metastorage.
      */
-    public void localWalEnabled(boolean enabled) {
+    public void localWalEnabled(boolean enabled, boolean persist) {
         if (localWalEnabled != enabled){
             log.info("Local WAL state for group=" + cacheOrGroupName() +
                 " changed from " + localWalEnabled + " to " + enabled);
 
-            persistLocalWalState(enabled);
+            if (persist)
+                persistLocalWalState(enabled);
 
             localWalEnabled = enabled;
         }
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 8439939..1dcc2b1 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
@@ -62,6 +62,7 @@ import org.apache.ignite.configuration.DataPageEvictionMode;
 import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.DeploymentMode;
+import org.apache.ignite.configuration.DiskPageCompression;
 import org.apache.ignite.configuration.FileSystemConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.MemoryConfiguration;
@@ -690,19 +691,26 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         }
 
         if (cc.isEncryptionEnabled() && !ctx.clientNode()) {
+            StringBuilder cacheSpec = new StringBuilder("[cacheName=").append(cc.getName())
+                .append(", groupName=").append(cc.getGroupName())
+                .append(", cacheType=").append(cacheType)
+                .append(']');
+
             if (!CU.isPersistentCache(cc, c.getDataStorageConfiguration())) {
                 throw new IgniteCheckedException("Using encryption is not allowed" +
-                    " for not persistent cache  [cacheName=" + cc.getName() + ", groupName=" + cc.getGroupName() +
-                    ", cacheType=" + cacheType + "]");
+                    " for not persistent cache " + cacheSpec.toString());
             }
 
             EncryptionSpi encSpi = c.getEncryptionSpi();
 
             if (encSpi == null) {
                 throw new IgniteCheckedException("EncryptionSpi should be configured to use encrypted cache " +
-                    "[cacheName=" + cc.getName() + ", groupName=" + cc.getGroupName() +
-                    ", cacheType=" + cacheType + "]");
+                    cacheSpec.toString());
             }
+
+            if (cc.getDiskPageCompression() != DiskPageCompression.DISABLED)
+                throw new IgniteCheckedException("Encryption cannot be used with disk page compression " +
+                    cacheSpec.toString());
         }
     }
 
@@ -2443,23 +2451,31 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
         boolean affNode = checkForAffinityNode(desc, reqNearCfg, ccfg);
 
-        CacheGroupContext grp = getOrCreateCacheGroupContext(desc, exchTopVer, cacheObjCtx, affNode, startCfg.getGroupName(), false);
+        ctx.cache().context().database().checkpointReadLock();
 
-        GridCacheContext cacheCtx = createCacheContext(ccfg,
-            grp,
-            null,
-            desc,
-            exchTopVer,
-            cacheObjCtx,
-            affNode,
-            true,
-            disabledAfterStart,
-            false
-        );
+        try {
+            CacheGroupContext grp = getOrCreateCacheGroupContext(
+                desc, exchTopVer, cacheObjCtx, affNode, startCfg.getGroupName(), false);
+
+            GridCacheContext cacheCtx = createCacheContext(ccfg,
+                grp,
+                null,
+                desc,
+                exchTopVer,
+                cacheObjCtx,
+                affNode,
+                true,
+                disabledAfterStart,
+                false
+            );
 
-        initCacheContext(cacheCtx, ccfg);
+            initCacheContext(cacheCtx, ccfg);
 
-        return cacheCtx;
+            return cacheCtx;
+        }
+        finally {
+            ctx.cache().context().database().checkpointReadUnlock();
+        }
     }
 
     /**
@@ -2722,28 +2738,38 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
         preparePageStore(desc, true);
 
-        CacheGroupContext grp = getOrCreateCacheGroupContext(
-            desc,
-            AffinityTopologyVersion.NONE,
-            cacheObjCtx,
-            true,
-            cfg.getGroupName(),
-            true
-        );
+        CacheGroupContext grpCtx;
+        GridCacheContext cacheCtx;
 
-        GridCacheContext cacheCtx = createCacheContext(cfg,
-            grp,
-            null,
-            desc,
-            AffinityTopologyVersion.NONE,
-            cacheObjCtx,
-            true,
-            true,
-            false,
-            true
-        );
+        ctx.cache().context().database().checkpointReadLock();
 
-        initCacheContext(cacheCtx, cfg);
+        try {
+            grpCtx = getOrCreateCacheGroupContext(
+                desc,
+                AffinityTopologyVersion.NONE,
+                cacheObjCtx,
+                true,
+                cfg.getGroupName(),
+                true
+            );
+
+            cacheCtx = createCacheContext(cfg,
+                grpCtx,
+                null,
+                desc,
+                AffinityTopologyVersion.NONE,
+                cacheObjCtx,
+                true,
+                true,
+                false,
+                true
+            );
+
+            initCacheContext(cacheCtx, cfg);
+        }
+        finally {
+            ctx.cache().context().database().checkpointReadUnlock();
+        }
 
         cacheCtx.onStarted();
 
@@ -2752,7 +2778,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         if (dataRegion == null && ctx.config().getDataStorageConfiguration() != null)
             dataRegion = ctx.config().getDataStorageConfiguration().getDefaultDataRegionConfiguration().getName();
 
-        grp.onCacheStarted(cacheCtx);
+        grpCtx.onCacheStarted(cacheCtx);
 
         ctx.query().onCacheStart(new GridCacheContextInfo(cacheCtx, false),
             desc.schema() != null ? desc.schema() : new QuerySchema(), desc.sql());
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index acd9ca0..6f9efa8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -40,6 +40,7 @@ import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.failure.FailureContext;
 import org.apache.ignite.failure.FailureType;
 import org.apache.ignite.internal.NodeStoppingException;
+import org.apache.ignite.internal.metric.IoStatisticsHolder;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.pagemem.wal.record.delta.DataPageMvccMarkUpdatedRecord;
 import org.apache.ignite.internal.pagemem.wal.record.delta.DataPageMvccUpdateNewTxStateHintRecord;
@@ -93,7 +94,6 @@ import org.apache.ignite.internal.processors.cache.tree.mvcc.search.MvccSnapshot
 import org.apache.ignite.internal.processors.cache.tree.mvcc.search.MvccTreeClosure;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.processors.query.GridQueryRowCacheCleaner;
-import org.apache.ignite.internal.metric.IoStatisticsHolder;
 import org.apache.ignite.internal.transactions.IgniteTxUnexpectedStateCheckedException;
 import org.apache.ignite.internal.util.GridAtomicLong;
 import org.apache.ignite.internal.util.GridCloseableIteratorAdapter;
@@ -934,7 +934,8 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
                             curPart = ds.partId();
 
                             // Data page scan is disabled by default for scan queries.
-                            CacheDataTree.setDataPageScanEnabled(dataPageScanEnabled == TRUE);
+                            // TODO https://ggsystems.atlassian.net/browse/GG-20800
+                            CacheDataTree.setDataPageScanEnabled(false);
 
                             try {
                                 if (mvccSnapshot == null)
@@ -1624,11 +1625,12 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
             if (oldRow.expireTime() != dataRow.expireTime())
                 return false;
 
-            // Use grp.sharedGroup() flag since it is possible cacheId is not yet set here.
-            boolean sizeWithCacheId = grp.sharedGroup();
-
             int oldLen = oldRow.size();
 
+            // Use grp.sharedGroup() flag since it is possible cacheId is not yet set here.
+            if (!grp.storeCacheIdInDataPage() && grp.sharedGroup() && oldRow.cacheId() != CU.UNDEFINED_CACHE_ID)
+                oldLen -= 4;
+
             if (oldLen > updateValSizeThreshold)
                 return false;
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxyImpl.java
index 6c9a62a..4e415e3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxyImpl.java
@@ -501,7 +501,7 @@ public class IgniteCacheProxyImpl<K, V> extends AsyncSupportAdapter<IgniteCache<
         IgniteBiPredicate<K, V> p = scanQry.getFilter();
 
         final CacheQuery<R> qry = ctx.queries().createScanQuery(
-            p, transformer, scanQry.getPartition(), isKeepBinary, scanQry.isLocal(), scanQry.isDataPageScanEnabled());
+            p, transformer, scanQry.getPartition(), isKeepBinary, scanQry.isLocal(), null);
 
         if (scanQry.getPageSize() > 0)
             qry.pageSize(scanQry.getPageSize());
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java
index 335caf3..e82babb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java
@@ -37,6 +37,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.NodeStoppingException;
 import org.apache.ignite.internal.managers.communication.GridMessageListener;
 import org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -52,6 +53,7 @@ import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.lang.IgniteInClosureX;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.util.worker.GridWorker;
 import org.apache.ignite.lang.IgniteFuture;
@@ -460,10 +462,10 @@ public class WalStateManager extends GridCacheSharedManagerAdapter {
         }
 
         for (Integer grpId : grpsToEnableWal)
-            cctx.cache().cacheGroup(grpId).localWalEnabled(true);
+            cctx.cache().cacheGroup(grpId).localWalEnabled(true, true);
 
         for (Integer grpId : grpsToDisableWal)
-            cctx.cache().cacheGroup(grpId).localWalEnabled(false);
+            cctx.cache().cacheGroup(grpId).localWalEnabled(false, true);
     }
 
     /**
@@ -491,7 +493,7 @@ public class WalStateManager extends GridCacheSharedManagerAdapter {
                     assert grp != null;
 
                     if (!grp.localWalEnabled())
-                        grp.localWalEnabled(true);
+                        grp.localWalEnabled(true, false);
                 }
 
                 tmpDisabledWal = null;
@@ -506,7 +508,12 @@ public class WalStateManager extends GridCacheSharedManagerAdapter {
             // It's safe to switch partitions to owning state only if checkpoint was successfully finished.
             cpFut.finishFuture().listen(new IgniteInClosureX<IgniteInternalFuture>() {
                 @Override public void applyx(IgniteInternalFuture future) {
+                    if (X.hasCause(future.error(), NodeStoppingException.class))
+                        return;
+
                     for (Integer grpId0 : session0.disabledGrps) {
+                        cctx.database().walEnabled(grpId0, true, true);
+
                         CacheGroupContext grp = cctx.cache().cacheGroup(grpId0);
 
                         if (grp != null)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index 96cbe2d..b1a21de 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -93,6 +93,7 @@ import org.apache.ignite.internal.NodeStoppingException;
 import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.DirectMemoryRegion;
+import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.pagemem.PageIdAllocator;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
@@ -152,13 +153,13 @@ import org.apache.ignite.internal.processors.cache.persistence.wal.crc.IgniteDat
 import org.apache.ignite.internal.processors.compress.CompressionProcessor;
 import org.apache.ignite.internal.processors.port.GridPortRecord;
 import org.apache.ignite.internal.processors.query.GridQueryProcessor;
-import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
 import org.apache.ignite.internal.util.GridCountDownCallback;
 import org.apache.ignite.internal.util.GridMultiCollectionWrapper;
 import org.apache.ignite.internal.util.GridReadOnlyArrayView;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.StripedExecutor;
+import org.apache.ignite.internal.util.TimeBag;
 import org.apache.ignite.internal.util.future.CountDownFuture;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -2026,7 +2027,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
     }
 
     /** {@inheritDoc} */
-    @Override public void startMemoryRestore(GridKernalContext kctx) throws IgniteCheckedException {
+    @Override public void startMemoryRestore(GridKernalContext kctx, TimeBag startTimer) throws IgniteCheckedException {
         if (kctx.clientNode())
             return;
 
@@ -2036,6 +2037,8 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
             // Preform early regions startup before restoring state.
             initAndStartRegions(kctx.config().getDataStorageConfiguration());
 
+            startTimer.finishGlobalStage("Init and start regions");
+
             // Restore binary memory for all not WAL disabled cache groups.
             restoreBinaryMemory(
                 groupsWithEnabledWal(),
@@ -2048,6 +2051,8 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
                 dumpPartitionsInfo(cctx, log);
             }
 
+            startTimer.finishGlobalStage("Restore binary memory");
+
             CheckpointStatus status = readCheckpointStatus();
 
             RestoreLogicalState logicalState = applyLogicalUpdates(
@@ -2063,6 +2068,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
                 dumpPartitionsInfo(cctx, log);
             }
 
+            startTimer.finishGlobalStage("Restore logical state");
+
+            // Should flush all data in buffers before read last WAL pointer.
+            // Iterator read records only from files.
+            cctx.wal().flush(null, true);
+
             // We must return null for NULL_PTR record, because FileWriteAheadLogManager.resumeLogging
             // can't write header without that condition.
             WALPointer lastReadPointer = logicalState.lastReadRecordPointer();
@@ -2263,7 +2274,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         try {
             while (it.hasNextX()) {
                 if (applyError.get() != null)
-                    throw applyError.get();
+                    break;
 
                 WALRecord rec = restoreBinaryState.next();
 
@@ -2363,7 +2374,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
 
                             stripedApplyPage((pageMem) -> {
                                 try {
-                                    applyPageDelta(pageMem, pageDelta);
+                                    applyPageDelta(pageMem, pageDelta, true);
 
                                     applied.incrementAndGet();
                                 }
@@ -2383,9 +2394,9 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         }
         finally {
             it.close();
-        }
 
-        awaitApplyComplete(exec, applyError);
+            awaitApplyComplete(exec, applyError);
+        }
 
         if (!finalizeState)
             return null;
@@ -2440,21 +2451,17 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         StripedExecutor exec,
         AtomicReference<IgniteCheckedException> applyError
     ) throws IgniteCheckedException {
-        if (applyError.get() != null)
-            throw applyError.get(); // Fail-fast check.
-        else {
-            try {
-                // Await completion apply tasks in all stripes.
-                exec.awaitComplete();
-            }
-            catch (InterruptedException e) {
-                throw new IgniteInterruptedException(e);
-            }
-
-            // Checking error after all task applied.
-            if (applyError.get() != null)
-                throw applyError.get();
+        try {
+            // Await completion apply tasks in all stripes.
+            exec.awaitComplete();
+        }
+        catch (InterruptedException e) {
+            throw new IgniteInterruptedException(e);
         }
+
+        // Checking error after all task applied.
+        if (applyError.get() != null)
+            throw applyError.get();
     }
 
     /**
@@ -2564,24 +2571,25 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
     /**
      * @param pageMem Page memory.
      * @param pageDeltaRecord Page delta record.
+     * @param restore Get page for restore.
      * @throws IgniteCheckedException If failed.
      */
-    private void applyPageDelta(PageMemoryEx pageMem, PageDeltaRecord pageDeltaRecord) throws IgniteCheckedException {
+    private void applyPageDelta(PageMemoryEx pageMem, PageDeltaRecord pageDeltaRecord, boolean restore) throws IgniteCheckedException {
         int grpId = pageDeltaRecord.groupId();
         long pageId = pageDeltaRecord.pageId();
 
         // Here we do not require tag check because we may be applying memory changes after
         // several repetitive restarts and the same pages may have changed several times.
-        long page = pageMem.acquirePage(grpId, pageId, IoStatisticsHolderNoOp.INSTANCE, true);
+        long page = pageMem.acquirePage(grpId, pageId, IoStatisticsHolderNoOp.INSTANCE, restore);
 
         try {
-            long pageAddr = pageMem.writeLock(grpId, pageId, page, true);
+            long pageAddr = pageMem.writeLock(grpId, pageId, page, restore);
 
             try {
                 pageDeltaRecord.applyDelta(pageMem, pageAddr);
             }
             finally {
-                pageMem.writeUnlock(grpId, pageId, page, null, true, true);
+                pageMem.writeUnlock(grpId, pageId, page, null, true, restore);
             }
         }
         finally {
@@ -2860,7 +2868,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
 
                         stripedApplyPage((pageMem) -> {
                             try {
-                                applyPageDelta(pageMem, pageDelta);
+                                applyPageDelta(pageMem, pageDelta, false);
                             }
                             catch (IgniteCheckedException e) {
                                 U.error(log, "Failed to apply page delta, " + pageDelta);
@@ -3608,7 +3616,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
 
             long nextNanos = System.nanoTime() + U.millisToNanos(delayFromNow);
 
-            if (sched.nextCpNanos <= nextNanos)
+            if (sched.nextCpNanos - nextNanos <= 0)
                 return new CheckpointProgressSnapshot(sched);
 
             CheckpointProgressSnapshot ret;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
index 69a5d50..d2c8bd1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
@@ -65,6 +65,7 @@ import org.apache.ignite.internal.processors.cache.persistence.metastorage.Metas
 import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
 import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener;
 import org.apache.ignite.internal.processors.cluster.IgniteChangeGlobalStateSupport;
+import org.apache.ignite.internal.util.TimeBag;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.LT;
@@ -906,9 +907,10 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
      * Perform memory restore before {@link GridDiscoveryManager} start.
      *
      * @param kctx Current kernal context.
+     * @param startTimer Holder of start time of stages.
      * @throws IgniteCheckedException If fails.
      */
-    public void startMemoryRestore(GridKernalContext kctx) throws IgniteCheckedException {
+    public void startMemoryRestore(GridKernalContext kctx, TimeBag startTimer) throws IgniteCheckedException {
         // No-op.
     }
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java
index cbb8b76..7877eec 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java
@@ -47,6 +47,8 @@ import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.DirectMemoryRegion;
 import org.apache.ignite.internal.mem.IgniteOutOfMemoryException;
+import org.apache.ignite.internal.metric.IoStatisticsHolder;
+import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.pagemem.PageIdAllocator;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
@@ -75,8 +77,6 @@ import org.apache.ignite.internal.processors.cache.persistence.tree.io.TrackingP
 import org.apache.ignite.internal.processors.cache.persistence.wal.crc.IgniteDataIntegrityViolationException;
 import org.apache.ignite.internal.processors.compress.CompressionProcessor;
 import org.apache.ignite.internal.processors.query.GridQueryRowCacheCleaner;
-import org.apache.ignite.internal.metric.IoStatisticsHolder;
-import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
 import org.apache.ignite.internal.util.GridLongList;
 import org.apache.ignite.internal.util.GridMultiCollectionWrapper;
@@ -1629,13 +1629,14 @@ public class PageMemoryImpl implements PageMemoryEx {
         finally {
             long pageId = PageIO.getPageId(page + PAGE_OVERHEAD);
 
-            assert pageId != 0 : U.hexLong(PageHeader.readPageId(page));
-            assert PageIO.getVersion(page + PAGE_OVERHEAD) != 0 : dumpPage(pageId, fullId.groupId());
-            assert PageIO.getType(page + PAGE_OVERHEAD) != 0 : U.hexLong(pageId);
-
             try {
+                assert pageId != 0 : U.hexLong(PageHeader.readPageId(page));
+
                 rwLock.writeUnlock(page + PAGE_LOCK_OFFSET, PageIdUtils.tag(pageId));
 
+                assert PageIO.getVersion(page + PAGE_OVERHEAD) != 0 : dumpPage(pageId, fullId.groupId());
+                assert PageIO.getType(page + PAGE_OVERHEAD) != 0 : U.hexLong(pageId);
+
                 if (throttlingPlc != ThrottlingPolicy.DISABLED && !restore && markDirty && !wasDirty)
                     writeThrottle.onMarkDirty(isInCheckpoint(fullId));
             }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
index b4b150c..0850d40 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
@@ -33,6 +33,8 @@ import org.apache.ignite.failure.FailureType;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.UnregisteredBinaryTypeException;
 import org.apache.ignite.internal.UnregisteredClassException;
+import org.apache.ignite.internal.metric.IoStatisticsHolder;
+import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
 import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
@@ -61,8 +63,6 @@ import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHan
 import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandlerWrapper;
 import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener;
 import org.apache.ignite.internal.processors.failure.FailureProcessor;
-import org.apache.ignite.internal.metric.IoStatisticsHolder;
-import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.util.GridArrays;
 import org.apache.ignite.internal.util.GridLongList;
 import org.apache.ignite.internal.util.IgniteTree;
@@ -1564,8 +1564,13 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
     /**
      * @param msg Message.
      */
-    private static void fail(Object msg) {
-        throw new AssertionError(msg);
+    private void fail(Object msg) {
+        AssertionError err = new AssertionError(msg);
+
+        if (failureProcessor != null)
+            failureProcessor.process(new FailureContext(FailureType.CRITICAL_ERROR, err));
+
+        throw err;
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java
index f37b154..0392d7e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java
@@ -62,6 +62,11 @@ public abstract class AbstractWalRecordsIterator
     protected IgniteBiTuple<WALPointer, WALRecord> curRec;
 
     /**
+     * The exception which can be thrown during reading next record. It holds until the next calling of next record.
+     */
+    private IgniteCheckedException curException;
+
+    /**
      * Current WAL segment absolute index. <br> Determined as lowest number of file at start, is changed during advance
      * segment
      */
@@ -122,9 +127,17 @@ public abstract class AbstractWalRecordsIterator
 
     /** {@inheritDoc} */
     @Override protected IgniteBiTuple<WALPointer, WALRecord> onNext() throws IgniteCheckedException {
+        if (curException != null)
+            throw curException;
+
         IgniteBiTuple<WALPointer, WALRecord> ret = curRec;
 
-        advance();
+        try {
+            advance();
+        }
+        catch (IgniteCheckedException e) {
+            curException = e;
+        }
 
         return ret;
     }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
index 6acd8c2..9f2c352 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
@@ -614,9 +614,14 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
 
         try {
             fileHandleManager.onDeactivate();
+        }
+        catch (Exception e) {
+            U.error(log, "Failed to gracefully close WAL segment: " + this.currHnd, e);
+        }
 
-            segmentAware.interrupt();
+        segmentAware.interrupt();
 
+        try {
             if (archiver != null)
                 archiver.shutdown();
 
@@ -626,8 +631,8 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
             if (decompressor != null)
                 decompressor.shutdown();
         }
-        catch (Exception e) {
-            U.error(log, "Failed to gracefully close WAL segment: " + this.currHnd, e);
+        catch (IgniteInterruptedCheckedException e) {
+            U.error(log, "Failed to gracefully shutdown WAL components, thread was interrupted.", e);
         }
     }
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV1Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV1Serializer.java
index e64fb8f..79e15a9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV1Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV1Serializer.java
@@ -22,7 +22,6 @@ import java.io.EOFException;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.internal.pagemem.wal.WALPointer;
@@ -33,14 +32,14 @@ import org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordType;
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.CacheVersionIO;
 import org.apache.ignite.internal.processors.cache.persistence.wal.ByteBufferBackedDataInput;
 import org.apache.ignite.internal.processors.cache.persistence.wal.ByteBufferExpander;
+import org.apache.ignite.internal.processors.cache.persistence.wal.FileWALPointer;
+import org.apache.ignite.internal.processors.cache.persistence.wal.SegmentEofException;
+import org.apache.ignite.internal.processors.cache.persistence.wal.WalSegmentTailReachedException;
 import org.apache.ignite.internal.processors.cache.persistence.wal.crc.FastCrc;
 import org.apache.ignite.internal.processors.cache.persistence.wal.io.FileInput;
 import org.apache.ignite.internal.processors.cache.persistence.wal.io.SegmentFileInputFactory;
-import org.apache.ignite.internal.processors.cache.persistence.wal.FileWALPointer;
-import org.apache.ignite.internal.processors.cache.persistence.wal.SegmentEofException;
 import org.apache.ignite.internal.processors.cache.persistence.wal.io.SegmentIO;
 import org.apache.ignite.internal.processors.cache.persistence.wal.io.SimpleFileInput;
-import org.apache.ignite.internal.processors.cache.persistence.wal.WalSegmentTailReachedException;
 import org.apache.ignite.internal.processors.cache.persistence.wal.record.HeaderRecord;
 import org.apache.ignite.internal.processors.cache.persistence.wal.serializer.io.RecordIO;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -56,7 +55,7 @@ import static org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordType
  * Record V1 serializer.
  * Stores records in following format:
  * <ul>
- *     <li>Record type from {@link RecordType#ordinal()} incremented by 1</li>
+ *     <li>Record type from {@link RecordType#index()} incremented by 1</li>
  *     <li>WAL pointer to double check consistency</li>
  *     <li>Data</li>
  *     <li>CRC or zero padding</li>
@@ -264,7 +263,7 @@ public class RecordV1Serializer implements RecordSerializer {
             if (recordType == WALRecord.RecordType.STOP_ITERATION_RECORD_TYPE)
                 throw new SegmentEofException("Reached logical end of the segment", null);
 
-            WALRecord.RecordType type = WALRecord.RecordType.fromOrdinal(recordType - 1);
+            WALRecord.RecordType type = WALRecord.RecordType.fromIndex(recordType - 1);
 
             if (type != WALRecord.RecordType.HEADER_RECORD)
                 throw new IOException("Can't read serializer version", null);
@@ -329,7 +328,7 @@ public class RecordV1Serializer implements RecordSerializer {
      * @param type WAL record type.
      */
     static void putRecordType(ByteBuffer buf, RecordType type) {
-        buf.put((byte)(type.ordinal() + 1));
+        buf.put((byte)(type.index() + 1));
     }
 
     /**
@@ -346,7 +345,7 @@ public class RecordV1Serializer implements RecordSerializer {
         if (type == WALRecord.RecordType.STOP_ITERATION_RECORD_TYPE)
             throw new SegmentEofException("Reached logical end of the segment", null);
 
-        return RecordType.fromOrdinal(type - 1);
+        return RecordType.fromIndex(type - 1);
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
index b977dd9..26913f4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
@@ -28,10 +28,10 @@ import org.apache.ignite.internal.pagemem.wal.record.FilteredRecord;
 import org.apache.ignite.internal.pagemem.wal.record.MarshalledRecord;
 import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
 import org.apache.ignite.internal.processors.cache.persistence.wal.ByteBufferBackedDataInput;
-import org.apache.ignite.internal.processors.cache.persistence.wal.io.FileInput;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileWALPointer;
 import org.apache.ignite.internal.processors.cache.persistence.wal.SegmentEofException;
 import org.apache.ignite.internal.processors.cache.persistence.wal.WalSegmentTailReachedException;
+import org.apache.ignite.internal.processors.cache.persistence.wal.io.FileInput;
 import org.apache.ignite.internal.processors.cache.persistence.wal.serializer.io.RecordIO;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.typedef.F;
@@ -46,7 +46,7 @@ import static org.apache.ignite.internal.processors.cache.persistence.wal.serial
  * Record V2 serializer.
  * Stores records in following format:
  * <ul>
- * <li>Record type from {@link RecordType#ordinal()} incremented by 1</li>
+ * <li>Record type from {@link RecordType#index()} incremented by 1</li>
  * <li>WAL pointer to double check consistency</li>
  * <li>Record length</li>
  * <li>Data</li>
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java
index e9232a1..d2773b4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.cache.tree;
 
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.metric.IoStatisticsHolder;
 import org.apache.ignite.internal.pagemem.PageUtils;
 import org.apache.ignite.internal.pagemem.store.PageStore;
 import org.apache.ignite.internal.processors.cache.CacheGroupContext;
@@ -43,10 +44,10 @@ import org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataInnerI
 import org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataLeafIO;
 import org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataRow;
 import org.apache.ignite.internal.processors.cache.tree.mvcc.search.MvccDataPageClosure;
-import org.apache.ignite.internal.metric.IoStatisticsHolder;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.lang.GridCursor;
 import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.jetbrains.annotations.TestOnly;
 
 import static java.lang.Boolean.FALSE;
 import static java.lang.Boolean.TRUE;
@@ -61,7 +62,7 @@ import static org.apache.ignite.internal.util.GridArrays.clearTail;
  */
 public class CacheDataTree extends BPlusTree<CacheSearchRow, CacheDataRow> {
     /** */
-    private static CacheDataRow[] EMPTY_ROWS = {};
+    private static final CacheDataRow[] EMPTY_ROWS = {};
 
     /** */
     private static Boolean lastFindWithDataPageScan;
@@ -136,6 +137,7 @@ public class CacheDataTree extends BPlusTree<CacheSearchRow, CacheDataRow> {
     /**
      * @return {@code true} If the last observed call to the method {@code find(...)} used data page scan.
      */
+    @TestOnly
     public static Boolean isLastFindWithDataPageScan() {
         Boolean res = lastFindWithDataPageScan;
         lastFindWithDataPageScan = null;
@@ -236,6 +238,8 @@ public class CacheDataTree extends BPlusTree<CacheSearchRow, CacheDataRow> {
                         long pageAddr = ((PageMemoryEx)pageMem).readLock(page, pageId, true, false);
 
                         try {
+                            // TODO https://ggsystems.atlassian.net/browse/GG-20800.
+                            // Here we should also exclude fragmented pages that don't contain the head of the entry.
                             if (PageIO.getType(pageAddr) != T_DATA)
                                 continue; // Not a data page.
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java
index 9e0085e..6cab338 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java
@@ -740,6 +740,9 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
                 }
             }
 
+            if (errorMsg == null)
+                errorMsg = validatePayload(joiningData);
+
             return (errorMsg == null) ? null : new IgniteNodeValidationResult(node.id(), errorMsg);
         }
         finally {
@@ -748,6 +751,25 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
     }
 
     /**
+     * @param joiningData Joining data to validate.
+     * @return {@code null} if contained data is valid otherwise error message.
+     */
+    private String validatePayload(DistributedMetaStorageJoiningNodeData joiningData) {
+        for (DistributedMetaStorageHistoryItem item : joiningData.hist) {
+            for (int i = 0; i < item.keys.length; i++) {
+                try {
+                    unmarshal(marshaller, item.valBytesArray[i]);
+                }
+                catch (IgniteCheckedException e) {
+                    return "Unable to unmarshal key=" + item.keys[i];
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
      * {@inheritDoc}
      * <br/>
      * Since {@link #validateNode(ClusterNode, DiscoveryDataBag.JoiningNodeDiscoveryData)} has already been invoked we
@@ -1087,6 +1109,9 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
                     " feature and this node has not empty distributed metastorage data");
             }
         }
+        catch (IgniteCheckedException ex) {
+            throw new IgniteException("Cannot join the cluster", ex);
+        }
         finally {
             lock.writeLock().unlock();
         }
@@ -1406,6 +1431,19 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
         assert startupExtras != null;
 
         startupExtras.deferredUpdates.add(update);
+
+        for (int i = 0; i < update.keys.length; i++) {
+            try {
+                notifyListeners(
+                    update.keys[i],
+                    bridge.read(update.keys[i], true),
+                    unmarshal(marshaller, update.valBytesArray[i])
+                );
+            }
+            catch (IgniteCheckedException ex) {
+                log.error("Unable to unmarshal new metastore data. key=" + update.keys[i], ex);
+            }
+        }
     }
 
     /**
@@ -1452,22 +1490,18 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
 
         for (DistributedMetaStorageHistoryItem histItem : startupExtras.deferredUpdates)
             completeWrite(bridge, histItem, true, false);
-
-        notifyListenersBeforeReadyForWrite(bridge);
     }
 
     /**
      * Notify listeners at the end of activation. Even if there was no data restoring.
      *
-     * @param bridge Bridge to access data storage.
+     * @param newData Data about which listeners should be notified.
      */
     private void notifyListenersBeforeReadyForWrite(
-        DistributedMetaStorageBridge bridge
+        DistributedMetaStorageKeyValuePair[] newData
     ) throws IgniteCheckedException {
         DistributedMetaStorageKeyValuePair[] oldData = this.bridge.localFullData();
 
-        DistributedMetaStorageKeyValuePair[] newData = bridge.localFullData();
-
         int oldIdx = 0, newIdx = 0;
 
         while (oldIdx < oldData.length && newIdx < newData.length) {
@@ -1514,13 +1548,17 @@ public class DistributedMetaStorageImpl extends GridProcessorAdapter
      *
      * @param nodeData Data received from remote node.
      */
-    private void writeFullDataLater(DistributedMetaStorageClusterNodeData nodeData) {
+    private void writeFullDataLater(
+        @NotNull DistributedMetaStorageClusterNodeData nodeData
+    ) throws IgniteCheckedException {
         assert nodeData.fullData != null;
 
         startupExtras.fullNodeData = nodeData;
 
         startupExtras.deferredUpdates.clear();
 
+        notifyListenersBeforeReadyForWrite(nodeData.fullData);
+
         if (nodeData.updates != null) {
             for (DistributedMetaStorageHistoryItem update : nodeData.updates)
                 updateLater(update);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index 21a2c2b..5f1de25 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -71,9 +71,9 @@ import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.util.worker.GridWorker;
 import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.transactions.TransactionMixedModeException;
 import org.apache.ignite.transactions.TransactionAlreadyCompletedException;
 import org.apache.ignite.transactions.TransactionDuplicateKeyException;
+import org.apache.ignite.transactions.TransactionMixedModeException;
 import org.apache.ignite.transactions.TransactionSerializationException;
 import org.apache.ignite.transactions.TransactionUnsupportedConcurrencyException;
 import org.jetbrains.annotations.Nullable;
@@ -971,9 +971,6 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
         qry.setNestedTxMode(nestedTxMode);
         qry.setSchema(schemaName);
 
-        if (cliCtx.dataPageScanEnabled() != null)
-            qry.setDataPageScanEnabled(cliCtx.dataPageScanEnabled());
-
         if (cliCtx.updateBatchSize() != null)
             qry.setUpdateBatchSize(cliCtx.updateBatchSize());
     }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryNextPageRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryNextPageRequest.java
index 5b008e9..d94915f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryNextPageRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryNextPageRequest.java
@@ -100,8 +100,6 @@ public class GridQueryNextPageRequest implements Message {
         return pageSize;
     }
 
-
-
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(GridQueryNextPageRequest.class, this);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java
index 9313733..be42f2e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java
@@ -38,6 +38,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -1052,17 +1053,46 @@ public class GridToStringBuilder {
                 else
                     first = false;
 
-                String name = fd.getName();
+                buf.a(fd.getName()).a('=');
 
-                Field field = cls.getDeclaredField(name);
+                switch (fd.type()) {
+                    case GridToStringFieldDescriptor.FIELD_TYPE_OBJECT:
+                        toString(buf, fd.fieldClass(), GridUnsafe.getObjectField(obj, fd.offset()));
 
-                field.setAccessible(true);
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_BYTE:
+                        buf.a(GridUnsafe.getByteField(obj, fd.offset()));
 
-                buf.a(name).a('=');
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_BOOLEAN:
+                        buf.a(GridUnsafe.getBooleanField(obj, fd.offset()));
 
-                Class<?> fieldType = field.getType();
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_CHAR:
+                        buf.a(GridUnsafe.getCharField(obj, fd.offset()));
 
-                toString(buf, fieldType, field.get(obj));
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_SHORT:
+                        buf.a(GridUnsafe.getShortField(obj, fd.offset()));
+
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_INT:
+                        buf.a(GridUnsafe.getIntField(obj, fd.offset()));
+
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_FLOAT:
+                        buf.a(GridUnsafe.getFloatField(obj, fd.offset()));
+
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_LONG:
+                        buf.a(GridUnsafe.getLongField(obj, fd.offset()));
+
+                        break;
+                    case GridToStringFieldDescriptor.FIELD_TYPE_DOUBLE:
+                        buf.a(GridUnsafe.getDoubleField(obj, fd.offset()));
+
+                        break;
+                }
             }
 
             appendVals(buf, first, addNames, addVals, addSens, addLen);
@@ -1695,7 +1725,8 @@ public class GridToStringBuilder {
                     add = notSens || INCLUDE_SENSITIVE;
                 }
                 else if (!f.isAnnotationPresent(GridToStringExclude.class) &&
-                    !f.getType().isAnnotationPresent(GridToStringExclude.class)) {
+                    !type.isAnnotationPresent(GridToStringExclude.class)
+                ) {
                     if (
                         // Include only private non-static
                         Modifier.isPrivate(f.getModifiers()) && !Modifier.isStatic(f.getModifiers()) &&
@@ -1724,7 +1755,7 @@ public class GridToStringBuilder {
                 }
 
                 if (add) {
-                    GridToStringFieldDescriptor fd = new GridToStringFieldDescriptor(f.getName());
+                    GridToStringFieldDescriptor fd = new GridToStringFieldDescriptor(f);
 
                     // Get order, if any.
                     final GridToStringOrder annOrder = f.getAnnotation(GridToStringOrder.class);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringClassDescriptor.java
index 700c460..fec6042 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringClassDescriptor.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal.util.tostring;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
@@ -34,7 +33,7 @@ class GridToStringClassDescriptor {
     private final String fqn;
 
     /** */
-    private List<GridToStringFieldDescriptor> fields = new ArrayList<>();
+    private ArrayList<GridToStringFieldDescriptor> fields = new ArrayList<>();
 
     /**
      * @param cls Class.
@@ -57,12 +56,9 @@ class GridToStringClassDescriptor {
 
     /** */
     void sortFields() {
-        Collections.sort(fields, new Comparator<GridToStringFieldDescriptor>() {
-            /** {@inheritDoc} */
-            @Override public int compare(GridToStringFieldDescriptor arg0, GridToStringFieldDescriptor arg1) {
-                return arg0.getOrder() < arg1.getOrder() ? -1 : arg0.getOrder() > arg1.getOrder() ? 1 : 0;
-            }
-        });
+        fields.trimToSize();
+
+        fields.sort(Comparator.comparingInt(GridToStringFieldDescriptor::getOrder));
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringFieldDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringFieldDescriptor.java
index 15d8fb5..6d5719b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringFieldDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringFieldDescriptor.java
@@ -17,23 +17,89 @@
 
 package org.apache.ignite.internal.util.tostring;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.intellij.lang.annotations.MagicConstant;
+
 /**
  * Simple field descriptor containing field name and its order in the class descriptor.
  */
 class GridToStringFieldDescriptor {
+    /** */
+    public static final int FIELD_TYPE_OBJECT = 0;
+
+    /** */
+    public static final int FIELD_TYPE_BYTE = 1;
+
+    /** */
+    public static final int FIELD_TYPE_BOOLEAN = 2;
+
+    /** */
+    public static final int FIELD_TYPE_CHAR = 3;
+
+    /** */
+    public static final int FIELD_TYPE_SHORT = 4;
+
+    /** */
+    public static final int FIELD_TYPE_INT = 5;
+
+    /** */
+    public static final int FIELD_TYPE_FLOAT = 6;
+
+    /** */
+    public static final int FIELD_TYPE_LONG = 7;
+
+    /** */
+    public static final int FIELD_TYPE_DOUBLE = 8;
+
     /** Field name. */
     private final String name;
 
     /** */
     private int order = Integer.MAX_VALUE;
 
-    /**
-     * @param name Field name.
-     */
-    GridToStringFieldDescriptor(String name) {
-        assert name != null;
+    /** Field offset as returned by {@link GridUnsafe#objectFieldOffset(java.lang.reflect.Field)}. */
+    private final long off;
+
+    /** Numeric constant for the field's type. One of {@code FIELD_TYPE_*} constants of current class. */
+    private final int type;
+
+    /** Class of the field. Upper bound in case of generic field types. */
+    private final Class<?> cls;
+
+    /** */
+    GridToStringFieldDescriptor(Field field) {
+        assert (field.getModifiers() & Modifier.STATIC) == 0 : "Static fields are not allowed here: " + field;
 
-        this.name = name;
+        off = GridUnsafe.objectFieldOffset(field);
+
+        cls = field.getType();
+
+        name = field.getName();
+
+        if (!cls.isPrimitive())
+            type = FIELD_TYPE_OBJECT;
+        else {
+            if (cls == byte.class)
+                type = FIELD_TYPE_BYTE;
+            else if (cls == boolean.class)
+                type = FIELD_TYPE_BOOLEAN;
+            else if (cls == char.class)
+                type = FIELD_TYPE_CHAR;
+            else if (cls == short.class)
+                type = FIELD_TYPE_SHORT;
+            else if (cls == int.class)
+                type = FIELD_TYPE_INT;
+            else if (cls == float.class)
+                type = FIELD_TYPE_FLOAT;
+            else if (cls == long.class)
+                type = FIELD_TYPE_LONG;
+            else if (cls == double.class)
+                type = FIELD_TYPE_DOUBLE;
+            else
+                throw new IllegalArgumentException("Unexpected primitive type: " + cls);
+        }
     }
 
     /**
@@ -47,6 +113,26 @@ class GridToStringFieldDescriptor {
     void setOrder(int order) { this.order = order; }
 
     /**
+     * @return Field offset as returned by {@link GridUnsafe#objectFieldOffset(java.lang.reflect.Field)}.
+     */
+    public long offset() {
+        return off;
+    }
+
+    /**
+     * @return Numeric constant for the field's type. One of {@code FIELD_TYPE_*} constants of current class.
+     */
+    @MagicConstant(valuesFromClass = GridToStringFieldDescriptor.class)
+    public int type() {
+        return type;
+    }
+
+    /** */
+    public Class<?> fieldClass() {
+        return cls;
+    }
+
+    /**
      * @return Field name.
      */
     String getName() { return name; }
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsCacheSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsCacheSelfTest.java
index ad1aae8..7ee447a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsCacheSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsCacheSelfTest.java
@@ -217,7 +217,7 @@ public class IoStatisticsCacheSelfTest extends GridCommonAbstractTest {
 
         long logicalReads = logicalReads(mmgr, CACHE_GROUP, CACHE_GROUP_NAME);
 
-        assertEquals(RECORD_COUNT * 6, logicalReads);
+        assertEquals(RECORD_COUNT * 4, logicalReads);
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringFieldDescriptor.java b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/wal/record/WALRecordTest.java
similarity index 50%
copy from modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringFieldDescriptor.java
copy to modules/core/src/test/java/org/apache/ignite/internal/pagemem/wal/record/WALRecordTest.java
index 15d8fb5..8b66d51 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringFieldDescriptor.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/wal/record/WALRecordTest.java
@@ -15,39 +15,32 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.util.tostring;
+package org.apache.ignite.internal.pagemem.wal.record;
 
-/**
- * Simple field descriptor containing field name and its order in the class descriptor.
- */
-class GridToStringFieldDescriptor {
-    /** Field name. */
-    private final String name;
+import java.util.Arrays;
+import org.apache.ignite.internal.pagemem.wal.record.WALRecord.RecordType;
+import org.junit.Test;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+/** */
+public class WALRecordTest {
 
     /** */
-    private int order = Integer.MAX_VALUE;
+    @Test
+    public void testRecordTypeIndex() {
+        RecordType[] recordTypes = RecordType.values();
 
-    /**
-     * @param name Field name.
-     */
-    GridToStringFieldDescriptor(String name) {
-        assert name != null;
+        for (RecordType recordType : recordTypes)
+            assertSame(recordType, RecordType.fromIndex(recordType.index()));
 
-        this.name = name;
-    }
+        int minIdx = Arrays.stream(recordTypes).mapToInt(RecordType::index).min().orElse(Integer.MIN_VALUE);
 
-    /**
-     * @return Field order.
-     */
-    int getOrder() { return order; }
+        assertTrue(minIdx >= 0);
 
-    /**
-     * @param order Field order.
-     */
-    void setOrder(int order) { this.order = order; }
+        int maxIdx = Arrays.stream(recordTypes).mapToInt(RecordType::index).max().orElse(Integer.MAX_VALUE);
 
-    /**
-     * @return Field name.
-     */
-    String getName() { return name; }
+        assertTrue(maxIdx < 256);
+    }
 }
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
index 2c4d7a7..2346047 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
@@ -323,7 +323,18 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
      * @param nodes Number of nodes.
      * @param caches Number of caches.
      */
-    final void checkCaches(int nodes, int caches) {
+    final void checkCaches(int nodes, int caches) throws InterruptedException {
+        checkCaches(nodes, caches, true);
+    }
+
+    /**
+     * @param nodes Number of nodes.
+     * @param caches Number of caches.
+     */
+    final void checkCaches(int nodes, int caches, boolean awaitExchange) throws InterruptedException {
+        if (awaitExchange)
+            awaitPartitionMapExchange();
+
         for (int i = 0; i < nodes; i++) {
             for (int c = 0; c < caches; c++) {
                 IgniteCache<Integer, Integer> cache = ignite(i).cache(CACHE_NAME_PREFIX + c);
@@ -684,9 +695,6 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
             startGrid(i);
         }
 
-        if (persistenceEnabled())
-            ignite(deactivateFrom).cluster().active(true);
-
         ignite(deactivateFrom).cluster().active(true); // Should be no-op.
 
         checkCaches(srvs + clients, CACHES);
@@ -729,7 +737,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
                 checkCache(ignite(i), CACHE_NAME_PREFIX + c, true);
         }
 
-        checkCaches1(srvs + clients + 2);
+        checkCaches(srvs + clients + 2);
     }
 
     /**
@@ -769,11 +777,11 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         checkCache(client, CU.UTILITY_CACHE_NAME, true);
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
 
         IgniteClientReconnectAbstractTest.reconnectClientNode(log, client, srv, null);
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
 
         this.client = false;
 
@@ -783,7 +791,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         startGrid(SRVS + CLIENTS + 1);
 
-        checkCaches1(SRVS + CLIENTS + 2);
+        checkCaches(SRVS + CLIENTS + 2);
     }
 
     /**
@@ -813,7 +821,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         checkCache(client, CU.UTILITY_CACHE_NAME, true);
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
 
         this.client = false;
 
@@ -823,7 +831,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         startGrid(SRVS + CLIENTS + 1);
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
     }
 
     /**
@@ -863,7 +871,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         checkCache(client, CU.UTILITY_CACHE_NAME, true);
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
 
         // Wait for late affinity assignment to finish.
         awaitPartitionMapExchange();
@@ -913,7 +921,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         assertTrue(client.cluster().active());
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
 
         checkCache(client, CACHE_NAME_PREFIX + 0, true);
 
@@ -925,7 +933,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         startGrid(SRVS + CLIENTS + 1);
 
-        checkCaches1(SRVS + CLIENTS + 2);
+        checkCaches(SRVS + CLIENTS + 2);
     }
 
     /**
@@ -1002,7 +1010,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         checkCache(client, CU.UTILITY_CACHE_NAME, true);
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
 
         checkCache(client, CACHE_NAME_PREFIX + 0, true);
 
@@ -1014,7 +1022,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         startGrid(SRVS + CLIENTS + 1);
 
-        checkCaches1(SRVS + CLIENTS + 2);
+        checkCaches(SRVS + CLIENTS + 2);
     }
 
     /**
@@ -1057,7 +1065,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         ignite(0).cluster().active(true);
 
-        checkCaches1(SRVS + CLIENTS);
+        checkCaches(SRVS + CLIENTS);
 
         checkRecordedMessages(true);
 
@@ -1071,7 +1079,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
 
         checkRecordedMessages(true);
 
-        checkCaches1(SRVS + CLIENTS + 2);
+        checkCaches(SRVS + CLIENTS + 2);
     }
 
     /**
@@ -1130,7 +1138,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
             ignite(0).cluster().active(true);
         }
 
-        checkCaches1(9);
+        checkCaches(9);
     }
 
     /**
@@ -1200,7 +1208,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
             ignite(0).cluster().active(true);
         }
 
-        checkCaches1(10);
+        checkCaches(10);
     }
 
     /**
@@ -1269,7 +1277,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
         for (int i = 0; i < 4; i++)
             startGrid(i);
 
-        checkCaches1(6);
+        checkCaches(6);
     }
 
     /**
@@ -1337,8 +1345,8 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
     /**
      * @param nodes Expected nodes number.
      */
-    private void checkCaches1(int nodes) {
-        checkCaches(nodes, 2);
+    private void checkCaches(int nodes) throws InterruptedException {
+        checkCaches(nodes, 2, false);
     }
 
     /**
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingWithAsyncClearingTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingWithAsyncClearingTest.java
index db01b09..b72a19b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingWithAsyncClearingTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingWithAsyncClearingTest.java
@@ -20,7 +20,6 @@ package org.apache.ignite.internal.processors.cache.distributed.rebalancing;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteDataStreamer;
-import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.cache.PartitionLossPolicy;
@@ -37,11 +36,13 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.topology.Grid
 import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.testframework.GridTestUtils.SF;
+import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Assert;
 import org.junit.Test;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_BASELINE_AUTO_ADJUST_ENABLED;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE;
 
 /**
  *
@@ -96,8 +97,6 @@ public class GridCacheRebalancingWithAsyncClearingTest extends GridCommonAbstrac
 
     /** {@inheritDoc} */
     @Override protected void beforeTest() throws Exception {
-        System.clearProperty(IgniteSystemProperties.IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE);
-
         stopAllGrids();
 
         cleanPersistenceDir();
@@ -105,8 +104,6 @@ public class GridCacheRebalancingWithAsyncClearingTest extends GridCommonAbstrac
 
     /** {@inheritDoc} */
     @Override protected void afterTest() throws Exception {
-        System.clearProperty(IgniteSystemProperties.IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE);
-
         stopAllGrids();
 
         cleanPersistenceDir();
@@ -125,10 +122,9 @@ public class GridCacheRebalancingWithAsyncClearingTest extends GridCommonAbstrac
      * @throws Exception If failed.
      */
     @Test
+    @WithSystemProperty(key = IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, value = "1")
     public void testPartitionClearingNotBlockExchange() throws Exception {
-        System.setProperty(IgniteSystemProperties.IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, "1");
-
-        IgniteEx ig = startGrids(3);
+        IgniteEx ig = (IgniteEx) startGrids(3);
         ig.cluster().active(true);
 
         // High number of keys triggers long partition eviction.
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRemoveDuringRebalancingTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRemoveDuringRebalancingTest.java
index 53556bd..68c8f7a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRemoveDuringRebalancingTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRemoveDuringRebalancingTest.java
@@ -48,7 +48,7 @@ public class IgnitePdsRemoveDuringRebalancingTest extends GridCommonAbstractTest
         IgniteConfiguration cfg = super.getConfiguration(gridName);
 
         cfg.setCacheConfiguration(
-            new CacheConfiguration()
+            new CacheConfiguration(DEFAULT_CACHE_NAME)
                 .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)
                 .setBackups(1)
                 .setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
@@ -96,14 +96,14 @@ public class IgnitePdsRemoveDuringRebalancingTest extends GridCommonAbstractTest
 
         ig.active(true);
 
-        try (IgniteDataStreamer<Object, Object> streamer = ig.dataStreamer(null)) {
+        try (IgniteDataStreamer<Object, Object> streamer = ig.dataStreamer(DEFAULT_CACHE_NAME)) {
             streamer.allowOverwrite(true);
 
             for (int i = 0; i < 100_000; i++)
                 streamer.addData(i, i);
         }
 
-        final IgniteCache<Object, Object> cache = ig.cache(null);
+        final IgniteCache<Object, Object> cache = ig.cache(DEFAULT_CACHE_NAME);
 
         IgniteInternalFuture<Object> fut = GridTestUtils.runAsync(new Callable<Object>() {
             @Override public Object call() throws Exception {
@@ -118,7 +118,7 @@ public class IgnitePdsRemoveDuringRebalancingTest extends GridCommonAbstractTest
 
         IgniteEx another = grid(1);
 
-        IgniteCache<Object, Object> cache1 = another.cache(null);
+        IgniteCache<Object, Object> cache1 = another.cache(DEFAULT_CACHE_NAME);
 
         for (int i = 0; i < 100_000; i++)
             assertNull(cache1.localPeek(i));
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRestartAfterFailedToWriteMetaPageTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRestartAfterFailedToWriteMetaPageTest.java
new file mode 100644
index 0000000..6dabad9
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRestartAfterFailedToWriteMetaPageTest.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.persistence;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.file.OpenOption;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.failure.FailureHandler;
+import org.apache.ignite.failure.StopNodeFailureHandler;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.processors.cache.persistence.file.FileIO;
+import org.apache.ignite.internal.processors.cache.persistence.file.FileIODecorator;
+import org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory;
+import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+/**
+ */
+public class IgnitePdsRestartAfterFailedToWriteMetaPageTest extends GridCommonAbstractTest implements Serializable {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setConsistentId(gridName);
+
+        DataStorageConfiguration memCfg = new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration()
+                    .setMaxSize(32L * 1024 * 1024)
+                    .setPersistenceEnabled(true))
+            .setWalMode(WALMode.FSYNC)
+            .setCheckpointFrequency(500L);
+
+        memCfg.setFileIOFactory(new MyIOFactory());
+
+        cfg.setDataStorageConfiguration(memCfg);
+
+        CacheConfiguration ccfg = new CacheConfiguration();
+
+        ccfg.setName(DEFAULT_CACHE_NAME);
+        ccfg.setCacheMode(CacheMode.REPLICATED);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void test() throws Exception {
+        IgniteEx grid = startGrid(0);
+
+        startGrid(1);
+
+        grid.cluster().active(true);
+
+        AtomicBoolean stop = new AtomicBoolean();
+
+        IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(() -> {
+            IgniteCache<Integer, Integer> cache = grid.cache(DEFAULT_CACHE_NAME);
+
+            ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+            while (!stop.get())
+                cache.put(rnd.nextInt(100_000), rnd.nextInt());
+        }, 12, "cache-insert-thread");
+
+        try {
+            Thread.sleep(1_000);
+
+            stopGrid(1);
+
+            Thread.sleep(5_000);
+
+            failNextCheckpoint = true;
+
+            GridTestUtils.assertThrows(log, () -> startGrid(1), Exception.class, "");
+
+            assertTrue(GridTestUtils.waitForCondition(() -> grid.cluster().nodes().size() == 1, 10_000));
+
+            failNextCheckpoint = false;
+
+            startGrid(1);
+        }
+        finally {
+            stop.set(true);
+
+            try {
+                fut.get();
+            }
+            catch (Exception ignore) {
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected FailureHandler getFailureHandler(String igniteInstanceName) {
+        return new StopNodeFailureHandler();
+    }
+
+    /** */
+    private volatile boolean failNextCheckpoint;
+
+    /** */
+    private class MyIOFactory implements FileIOFactory {
+        /** Serial version uid. */
+        private static final long serialVersionUID = 0L;
+
+        /** */
+        private AtomicInteger cpCnt = new AtomicInteger();
+
+        /** {@inheritDoc} */
+        @Override public FileIO create(File file, OpenOption... modes) throws IOException {
+            FileIO delegate = new RandomAccessFileIOFactory().create(file, modes);
+
+            String nodeName = IgnitePdsRestartAfterFailedToWriteMetaPageTest.class.getSimpleName() + "1";
+
+            if (file.getAbsolutePath().contains(nodeName)) {
+                if (failNextCheckpoint && file.getName().contains("-START.bin"))
+                    cpCnt.incrementAndGet();
+                else if (file.getName().contains("part-") && !file.getAbsolutePath().contains("metastorage")) {
+                    return new FileIODecorator(delegate) {
+                        @Override public int write(ByteBuffer srcBuf) throws IOException {
+                            maybeThrowException();
+
+                            return super.write(srcBuf);
+                        }
+
+                        @Override public int write(ByteBuffer srcBuf, long position) throws IOException {
+                            maybeThrowException();
+
+                            return super.write(srcBuf, position);
+                        }
+
+                        @Override public int write(byte[] buf, int off, int len) throws IOException {
+                            maybeThrowException();
+
+                            return super.write(buf, off, len);
+                        }
+
+                        private void maybeThrowException() throws IOException {
+                            if (failNextCheckpoint && cpCnt.get() > 0)
+                                throw new IOException("Checkpoint failed.");
+                        }
+                    };
+                }
+            }
+
+            return delegate;
+        }
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsCacheWalDisabledOnRebalancingTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsCacheWalDisabledOnRebalancingTest.java
index b83becf..29bc3e5 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsCacheWalDisabledOnRebalancingTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsCacheWalDisabledOnRebalancingTest.java
@@ -118,6 +118,10 @@ public class IgnitePdsCacheWalDisabledOnRebalancingTest extends GridCommonAbstra
 
     /** {@inheritDoc} */
     @Override protected void afterTest() throws Exception {
+        fileIoBlockingSemaphore.drainPermits();
+
+        fileIoBlockingSemaphore.release(Integer.MAX_VALUE);
+
         stopAllGrids();
 
         cleanPersistenceDir();
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsReserveWalSegmentsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsReserveWalSegmentsTest.java
index e120096..4a77523 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsReserveWalSegmentsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsReserveWalSegmentsTest.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
 import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
 import org.apache.ignite.internal.processors.cache.persistence.checkpoint.CheckpointHistory;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileWALPointer;
+import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
@@ -37,6 +38,7 @@ import static org.apache.ignite.IgniteSystemProperties.IGNITE_PDS_MAX_CHECKPOINT
 /**
  * Test correctness of truncating unused WAL segments.
  */
+@WithSystemProperty(key = IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, value = "2")
 public class IgnitePdsReserveWalSegmentsTest extends GridCommonAbstractTest {
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
@@ -70,8 +72,6 @@ public class IgnitePdsReserveWalSegmentsTest extends GridCommonAbstractTest {
         stopAllGrids();
 
         cleanPersistenceDir();
-
-        System.setProperty(IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, "2");
     }
 
     /** {@inheritDoc} */
@@ -79,8 +79,6 @@ public class IgnitePdsReserveWalSegmentsTest extends GridCommonAbstractTest {
         stopAllGrids();
 
         cleanPersistenceDir();
-
-        System.clearProperty(IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE);
     }
 
     /**
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalDeletionArchiveAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalDeletionArchiveAbstractTest.java
index 7d142a5..ded83c2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalDeletionArchiveAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalDeletionArchiveAbstractTest.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabase
 import org.apache.ignite.internal.processors.cache.persistence.checkpoint.CheckpointHistory;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileDescriptor;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
@@ -82,8 +83,6 @@ public abstract class WalDeletionArchiveAbstractTest extends GridCommonAbstractT
         stopAllGrids();
 
         cleanPersistenceDir();
-
-        System.clearProperty(IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE);
     }
 
     /** {@inheritDoc} */
@@ -236,8 +235,8 @@ public abstract class WalDeletionArchiveAbstractTest extends GridCommonAbstractT
      * doesn't delete because deleting was disabled.
      */
     @Test
+    @WithSystemProperty(key = IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, value = "2")
     public void testCorrectDeletedCheckpointHistoryButKeepWalFiles() throws Exception {
-        System.setProperty(IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, "2");
         //given: configured grid with disabled WAL removing.
         Ignite ignite = startGrid(dbCfg -> {
             dbCfg.setMaxWalArchiveSize(Long.MAX_VALUE);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteAbstractWalIteratorInvalidCrcTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteAbstractWalIteratorInvalidCrcTest.java
index 2c3f0a5..da44ea7 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteAbstractWalIteratorInvalidCrcTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteAbstractWalIteratorInvalidCrcTest.java
@@ -218,7 +218,7 @@ public abstract class IgniteAbstractWalIteratorInvalidCrcTest extends GridCommon
 
             // WAL iterator advances to the next record and only then returns current one,
             // so next record has to be valid as well.
-            assertEquals(lastReadPtr.next(), beforeCorruptedPtr);
+            assertEquals(lastReadPtr, beforeCorruptedPtr);
         }
         else
             try (WALIterator iter = getWalIterator(walMgr, ignoreArchiveDir)) {
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/CacheDataPageScanQueryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/CacheDataPageScanQueryTest.java
index e99331b..910485b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/CacheDataPageScanQueryTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/CacheDataPageScanQueryTest.java
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicInteger;
 import javax.cache.Cache;
 import org.apache.ignite.IgniteCache;
@@ -35,7 +36,9 @@ import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.cache.tree.CacheDataTree;
 import org.apache.ignite.mxbean.CacheGroupMetricsMXBean;
+import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
@@ -90,6 +93,7 @@ public class CacheDataPageScanQueryTest extends GridCommonAbstractTest {
      */
     @SuppressWarnings("ConstantConditions")
     @Test
+    @Ignore("https://ggsystems.atlassian.net/browse/GG-20800")
     public void testDataPageScanWithRestart() throws Exception {
         IgniteEx ignite = startGrid(0);
         ignite.cluster().active(true);
@@ -98,7 +102,7 @@ public class CacheDataPageScanQueryTest extends GridCommonAbstractTest {
         CacheGroupMetricsMXBean gmx = cache.context().group().mxBean();
         DataRegionMetricsImpl rmx = cache.context().dataRegion().memoryMetrics();
 
-        long maxKey = 100_000;
+        long maxKey = 10_000;
 
         Map<Long,String> map = new ConcurrentHashMap<>();
 
@@ -106,11 +110,13 @@ public class CacheDataPageScanQueryTest extends GridCommonAbstractTest {
         AtomicInteger threadShift = new AtomicInteger();
 
         multithreaded((Callable<Void>)() -> {
+            ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
             int shift = threadShift.getAndIncrement();
 
             for (int i = shift; i < maxKey; i += threads) {
                 Long k = (long)i;
-                String v = String.valueOf(i);
+                String v = GridTestUtils.randomString(rnd, 6 * 1024); // Bigger than single page.
 
                 cache.put(k, v);
                 map.put(k, v);
@@ -118,8 +124,6 @@ public class CacheDataPageScanQueryTest extends GridCommonAbstractTest {
             return null;
         }, threads);
 
-//        forceCheckpoint(ignite);
-
         assertEquals(map.size(), cache.size());
 
         info("Page mem  : " + rmx.getPhysicalMemorySize());
@@ -129,7 +133,7 @@ public class CacheDataPageScanQueryTest extends GridCommonAbstractTest {
         HashMap<Long,String> map2 = new HashMap<>(map);
 
         IgniteCache<Long,String> c = ignite.cache(CACHE);
-        for (Cache.Entry<Long,String> e : c.query(new ScanQuery<Long,String>().setDataPageScanEnabled(true)).getAll())
+        for (Cache.Entry<Long,String> e : c.query(new ScanQuery<Long,String>()).getAll())
             assertEquals(e.getValue(), map.remove(e.getKey()));
 
         assertTrue(map.isEmpty());
@@ -141,7 +145,7 @@ public class CacheDataPageScanQueryTest extends GridCommonAbstractTest {
         ignite.cluster().active(true);
 
         c = ignite.cache(CACHE);
-        for (Cache.Entry<Long,String> e : c.query(new ScanQuery<Long,String>().setDataPageScanEnabled(true)).getAll())
+        for (Cache.Entry<Long,String> e : c.query(new ScanQuery<Long,String>()).getAll())
             assertEquals(e.getValue(), map2.remove(e.getKey()));
 
         assertTrue(map2.isEmpty());
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustInMemoryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustInMemoryTest.java
index 25c4217..a9584c4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustInMemoryTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustInMemoryTest.java
@@ -61,4 +61,30 @@ public class BaselineAutoAdjustInMemoryTest extends BaselineAutoAdjustTest {
 
         assertEquals(3, grid(0).cluster().currentBaselineTopology().size());
     }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testSetBaselineManually() throws Exception {
+        IgniteEx ignite0 = startGrid(0);
+
+        ignite0.cluster().active(true);
+
+        assertEquals(1, ignite0.cluster().currentBaselineTopology().size());
+
+        ignite0.cluster().baselineAutoAdjustEnabled(false);
+
+        IgniteEx ignite1 = startGrid(1);
+
+        assertEquals(1, ignite0.cluster().currentBaselineTopology().size());
+        assertEquals(1, ignite1.cluster().currentBaselineTopology().size());
+
+        assertFalse(ignite1.cluster().isBaselineAutoAdjustEnabled());
+
+        ignite0.cluster().setBaselineTopology(ignite0.context().discovery().aliveServerNodes());
+
+        assertEquals(2, ignite0.cluster().currentBaselineTopology().size());
+        assertEquals(2, ignite1.cluster().currentBaselineTopology().size());
+    }
 }
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
index beeea1a..50bfa02 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.TransactionsMXBeanImplTest;
 import org.apache.ignite.internal.managers.IgniteDiagnosticMessagesMultipleConnectionsTest;
 import org.apache.ignite.internal.managers.IgniteDiagnosticMessagesTest;
 import org.apache.ignite.internal.managers.discovery.IncompleteDeserializationExceptionTest;
+import org.apache.ignite.internal.pagemem.wal.record.WALRecordTest;
 import org.apache.ignite.internal.processors.DeadLockOnNodeLeftExchangeTest;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentV2Test;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentV2TestNoOptimizations;
@@ -184,6 +185,8 @@ import org.junit.runners.Suite;
 
     AttributeNodeFilterSelfTest.class,
 
+    WALRecordTest.class,
+
     // Basic DB data structures.
     BPlusTreeSelfTest.class,
     BPlusTreeFakeReuseSelfTest.class,
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java
index 13ea27c..2254956 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java
@@ -27,6 +27,8 @@ import org.apache.ignite.internal.processors.cache.distributed.rebalancing.Ignit
 import org.apache.ignite.internal.processors.cache.persistence.CorruptedTreeFailureHandlingTest;
 import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsContinuousRestartTestWithSharedGroupAndIndexes;
 import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsRecoveryAfterFileCorruptionTest;
+import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsRemoveDuringRebalancingTest;
+import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsRestartAfterFailedToWriteMetaPageTest;
 import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsTaskCancelingTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsCacheWalDisabledOnRebalancingTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsPageEvictionDuringPartitionClearTest;
@@ -75,6 +77,9 @@ public class IgnitePdsTestSuite4 {
         GridTestUtils.addTestIfNeeded(suite, IgnitePdsStartWIthEmptyArchive.class, ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, CorruptedTreeFailureHandlingTest.class, ignoredTests);
 
+        GridTestUtils.addTestIfNeeded(suite, IgnitePdsRestartAfterFailedToWriteMetaPageTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgnitePdsRemoveDuringRebalancingTest.class, ignoredTests);
+
         // Page lock tracker tests.
         GridTestUtils.addTestIfNeeded(suite, PageLockTrackerManagerTest.class, ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, SharedPageLockTrackerTest.class, ignoredTests);
diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridInternalTaskUnusedWalSegmentsTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridInternalTaskUnusedWalSegmentsTest.java
index f3b8991..3b96ae3 100644
--- a/modules/core/src/test/java/org/apache/ignite/util/GridInternalTaskUnusedWalSegmentsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/util/GridInternalTaskUnusedWalSegmentsTest.java
@@ -17,6 +17,11 @@
 
 package org.apache.ignite.util;
 
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 import org.apache.ignite.IgniteDataStreamer;
 import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -30,13 +35,8 @@ import org.apache.ignite.internal.visor.misc.VisorWalTask;
 import org.apache.ignite.internal.visor.misc.VisorWalTaskArg;
 import org.apache.ignite.internal.visor.misc.VisorWalTaskOperation;
 import org.apache.ignite.internal.visor.misc.VisorWalTaskResult;
+import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-
-import java.io.File;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
 import org.junit.Test;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE;
@@ -75,15 +75,11 @@ public class GridInternalTaskUnusedWalSegmentsTest extends GridCommonAbstractTes
     /** {@inheritDoc} */
     @Override protected void beforeTest() throws Exception {
         cleanPersistenceDir();
-
-        System.setProperty(IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, "2");
     }
 
     /** {@inheritDoc} */
     @Override protected void afterTest() throws Exception {
         cleanPersistenceDir();
-
-        System.clearProperty(IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE);
     }
 
     /**
@@ -92,6 +88,7 @@ public class GridInternalTaskUnusedWalSegmentsTest extends GridCommonAbstractTes
      * @throws Exception if failed.
      */
     @Test
+    @WithSystemProperty(key = IGNITE_PDS_MAX_CHECKPOINT_MEMORY_HISTORY_SIZE, value = "2")
     public void testCorrectnessOfDeletionTaskSegments() throws Exception {
         try {
             IgniteEx ig0 = (IgniteEx)startGrids(4);
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 64e7197..2003424 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -176,7 +176,6 @@ import org.h2.table.IndexColumn;
 import org.h2.util.JdbcUtils;
 import org.jetbrains.annotations.Nullable;
 
-import static java.lang.Boolean.FALSE;
 import static java.util.Collections.singletonList;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_MVCC_TX_SIZE_CACHING_THRESHOLD;
 import static org.apache.ignite.internal.processors.cache.mvcc.MvccCachingManager.TX_SIZE_THRESHOLD;
@@ -191,7 +190,6 @@ import static org.apache.ignite.internal.processors.query.h2.H2Utils.generateFie
 import static org.apache.ignite.internal.processors.query.h2.H2Utils.session;
 import static org.apache.ignite.internal.processors.query.h2.H2Utils.validateTypeDescriptor;
 import static org.apache.ignite.internal.processors.query.h2.H2Utils.zeroCursor;
-import static org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2QueryRequest.isDataPageScanEnabled;
 
 /**
  * Indexing implementation based on H2 database engine. In this implementation main query language is SQL,
@@ -850,7 +848,8 @@ public class IgniteH2Indexing implements GridQueryIndexing {
      */
     public void enableDataPageScan(Boolean dataPageScanEnabled) {
         // Data page scan is enabled by default for SQL.
-        CacheDataTree.setDataPageScanEnabled(dataPageScanEnabled != FALSE);
+        // TODO https://ggsystems.atlassian.net/browse/GG-20800
+        CacheDataTree.setDataPageScanEnabled(false);
     }
 
     /**
@@ -937,7 +936,6 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         res.setReplicatedOnly(qry.isReplicatedOnly());
         res.setSchema(schemaName);
         res.setSql(sql);
-        res.setDataPageScanEnabled(qry.isDataPageScanEnabled());
 
         if (qry.getTimeout() > 0)
             res.setTimeout(qry.getTimeout(), TimeUnit.MILLISECONDS);
@@ -1514,7 +1512,6 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         fldsQry.setTimeout(timeout, TimeUnit.MILLISECONDS);
         fldsQry.setPageSize(pageSize);
         fldsQry.setLocal(true);
-        fldsQry.setDataPageScanEnabled(isDataPageScanEnabled(flags));
 
         boolean loc = true;
 
@@ -1554,8 +1551,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
             .setEnforceJoinOrder(fldsQry.isEnforceJoinOrder())
             .setLocal(fldsQry.isLocal())
             .setPageSize(fldsQry.getPageSize())
-            .setTimeout(fldsQry.getTimeout(), TimeUnit.MILLISECONDS)
-            .setDataPageScanEnabled(fldsQry.isDataPageScanEnabled());
+            .setTimeout(fldsQry.getTimeout(), TimeUnit.MILLISECONDS);
 
         QueryCursorImpl<List<?>> cur;
 
@@ -2670,8 +2666,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
             .setEnforceJoinOrder(qryDesc.enforceJoinOrder())
             .setLocal(qryDesc.local())
             .setPageSize(qryParams.pageSize())
-            .setTimeout(qryParams.timeout(), TimeUnit.MILLISECONDS)
-            .setDataPageScanEnabled(qryParams.dataPageScanEnabled());
+            .setTimeout(qryParams.timeout(), TimeUnit.MILLISECONDS);
 
         Iterable<List<?>> cur;
 
@@ -2798,8 +2793,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
                         .setEnforceJoinOrder(qryDesc.enforceJoinOrder())
                         .setLocal(qryDesc.local())
                         .setPageSize(qryParams.pageSize())
-                        .setTimeout((int)timeout, TimeUnit.MILLISECONDS)
-                        .setDataPageScanEnabled(qryParams.dataPageScanEnabled());
+                        .setTimeout((int)timeout, TimeUnit.MILLISECONDS);
 
                     FieldsQueryCursor<List<?>> cur = executeSelectForDml(
                         qryDesc.schemaName(),
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java
index 72c9273..49a5658 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java
@@ -18,12 +18,11 @@
 
 package org.apache.ignite.internal.processors.query.h2;
 
+import java.util.List;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.processors.query.NestedTxMode;
 
-import java.util.List;
-
 /**
  * Query parameters which vary between requests having the same execution plan. Essentially, these are the arguments
  * of original {@link org.apache.ignite.cache.query.SqlFieldsQuery} which are not part of {@link QueryDescriptor}.
@@ -90,7 +89,7 @@ public class QueryParameters {
             qry.getTimeout(),
             qry.isLazy(),
             qry.getPageSize(),
-            qry.isDataPageScanEnabled(),
+            null,
             nestedTxMode,
             autoCommit,
             batchedArgs,
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
index a747c63..7d38dff 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
@@ -599,7 +599,6 @@ public class GridMapQueryExecutor {
             fldsQry.setTimeout(req.timeout(), TimeUnit.MILLISECONDS);
             fldsQry.setPageSize(req.pageSize());
             fldsQry.setLocal(true);
-            fldsQry.setDataPageScanEnabled(req.isDataPageScanEnabled());
 
             boolean local = true;
 
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/IgniteCacheReplicatedQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/IgniteCacheReplicatedQuerySelfTest.java
index 9aea06d..4d0cdc2 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/IgniteCacheReplicatedQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/IgniteCacheReplicatedQuerySelfTest.java
@@ -356,12 +356,12 @@ public class IgniteCacheReplicatedQuerySelfTest extends IgniteCacheAbstractQuery
      */
     @Test
     public void testNodeLeft() throws Exception {
-        Ignite g = startGrid("client");
+        Ignite client = startGrid("client");
 
         try {
-            assertTrue(g.configuration().isClientMode());
+            assertTrue(client.configuration().isClientMode());
 
-            IgniteCache<Integer, Integer> cache = jcache(g, Integer.class, Integer.class);
+            IgniteCache<Integer, Integer> cache = jcache(client, Integer.class, Integer.class);
 
             for (int i = 0; i < 1000; i++)
                 cache.put(i, i);
@@ -381,18 +381,21 @@ public class IgniteCacheReplicatedQuerySelfTest extends IgniteCacheAbstractQuery
 
             assertEquals(1, mapNode1.size() + mapNode2.size() + mapNode3.size());
 
-            final UUID nodeId = g.cluster().localNode().id();
+            final UUID nodeId = client.cluster().localNode().id();
 
-            final CountDownLatch latch = new CountDownLatch(1);
+            final CountDownLatch latch = new CountDownLatch(3);
 
-            grid(0).events().localListen(new IgnitePredicate<Event>() {
-                @Override public boolean apply(Event evt) {
-                    if (((DiscoveryEvent)evt).eventNode().id().equals(nodeId))
-                        latch.countDown();
+            // Add listeners on all nodes.
+            for (int i = 0; i < 3; i++) {
+                grid(i).events().localListen(new IgnitePredicate<Event>() {
+                    @Override public boolean apply(Event evt) {
+                        if (((DiscoveryEvent)evt).eventNode().id().equals(nodeId))
+                            latch.countDown();
 
-                    return true;
-                }
-            }, EVT_NODE_LEFT, EVT_NODE_FAILED);
+                        return true;
+                    }
+                }, EVT_NODE_LEFT, EVT_NODE_FAILED);
+            }
 
             stopGrid("client");
 
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java
index 9177c8c..d3129c6 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java
@@ -174,14 +174,12 @@ public class H2RowCacheSelfTest extends AbstractIndexingCommonTest {
         assertEquals(0, rowCache.size());
 
         // Warmup cache.
-        cache.query(new SqlFieldsQuery("SELECT * FROM Value")
-            .setDataPageScanEnabled(false)).getAll();
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
 
         assertEquals(maxSize / 2, rowCache.size());
 
         // Query again - are there any leaks?
-        cache.query(new SqlFieldsQuery("SELECT * FROM Value")
-            .setDataPageScanEnabled(false)).getAll();
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
 
         assertEquals(maxSize / 2, rowCache.size());
 
@@ -191,8 +189,7 @@ public class H2RowCacheSelfTest extends AbstractIndexingCommonTest {
 
         assertEquals(maxSize / 2, rowCache.size());
 
-        cache.query(new SqlFieldsQuery("SELECT * FROM Value")
-            .setDataPageScanEnabled(false)).getAll();
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
 
         assertEquals(maxSize, rowCache.size());
 
@@ -202,16 +199,16 @@ public class H2RowCacheSelfTest extends AbstractIndexingCommonTest {
 
         assertEquals(maxSize, rowCache.size());
 
-        cache.query(new SqlFieldsQuery("SELECT * FROM Value").setDataPageScanEnabled(false)).getAll();
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
 
         assertEquals(maxSize, rowCache.size());
 
         // Delete all.
-        cache.query(new SqlFieldsQuery("DELETE FROM Value").setDataPageScanEnabled(false)).getAll();
+        cache.query(new SqlFieldsQuery("DELETE FROM Value")).getAll();
 
         assertEquals(0, rowCache.size());
 
-        cache.query(new SqlFieldsQuery("SELECT * FROM Value").setDataPageScanEnabled(false)).getAll();
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
 
         assertEquals(0, rowCache.size());
     }
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/QueryDataPageScanTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/QueryDataPageScanTest.java
index 1c5a88c..1012d18 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/QueryDataPageScanTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/QueryDataPageScanTest.java
@@ -62,6 +62,7 @@ import org.apache.ignite.testframework.MvccFeatureChecker;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.transactions.Transaction;
 import org.jetbrains.annotations.Nullable;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import static java.lang.Boolean.FALSE;
@@ -99,6 +100,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     @Test
+    @Ignore("https://ggsystems.atlassian.net/browse/GG-20800")
     public void testMultipleIndexedTypes() throws Exception {
         final String cacheName = "test_multi_type";
 
@@ -137,32 +139,27 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
 
         CacheDataTree.isLastFindWithDataPageScan();
 
-        List<List<?>> res = cache.query(new SqlFieldsQuery("select z, _key, _val from TestData use index()")
-            .setDataPageScanEnabled(true)).getAll();
+        List<List<?>> res = cache.query(new SqlFieldsQuery("select z, _key, _val from TestData use index()")).getAll();
         assertEquals(1, res.size());
         assertEquals(777L, res.get(0).get(0));
         assertTrue(CacheDataTree.isLastFindWithDataPageScan());
 
-        res = cache.query(new SqlFieldsQuery("select _val, _key from String use index()")
-            .setDataPageScanEnabled(true)).getAll();
+        res = cache.query(new SqlFieldsQuery("select _val, _key from String use index()")).getAll();
         assertEquals(1, res.size());
         assertEquals("bla-bla", res.get(0).get(0));
         assertTrue(CacheDataTree.isLastFindWithDataPageScan());
 
-        res = cache.query(new SqlFieldsQuery("select _key, _val from Integer use index()")
-            .setDataPageScanEnabled(true)).getAll();
+        res = cache.query(new SqlFieldsQuery("select _key, _val from Integer use index()")).getAll();
         assertEquals(1, res.size());
         assertEquals(3, res.get(0).get(0));
         assertTrue(CacheDataTree.isLastFindWithDataPageScan());
 
-        res = cache.query(new SqlFieldsQuery("select _key, _val from uuids use index()")
-            .setDataPageScanEnabled(true)).getAll();
+        res = cache.query(new SqlFieldsQuery("select _key, _val from uuids use index()")).getAll();
         assertEquals(1, res.size());
         assertEquals(7, res.get(0).get(0));
         assertTrue(CacheDataTree.isLastFindWithDataPageScan());
 
-        res = cache.query(new SqlFieldsQuery("select age, name from my_persons use index()")
-            .setDataPageScanEnabled(true)).getAll();
+        res = cache.query(new SqlFieldsQuery("select age, name from my_persons use index()")).getAll();
         assertEquals(1, res.size());
         assertEquals(99, res.get(0).get(0));
         assertEquals("Vasya", res.get(0).get(1));
@@ -173,6 +170,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     @Test
+    @Ignore("https://ggsystems.atlassian.net/browse/GG-20800")
     public void testConcurrentUpdatesWithMvcc() throws Exception {
         doTestConcurrentUpdates(true);
     }
@@ -181,6 +179,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     @Test
+    @Ignore("https://ggsystems.atlassian.net/browse/GG-20800")
     public void testConcurrentUpdatesNoMvcc() throws Exception {
         try {
             doTestConcurrentUpdates(false);
@@ -214,7 +213,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
 
         assertEquals(accounts * initialBalance,((Number)
             cache.query(new SqlFieldsQuery("select sum(_val) from Long use index()")
-                .setDataPageScanEnabled(true)).getAll().get(0).get(0)).longValue());
+                ).getAll().get(0).get(0)).longValue());
         assertTrue(CacheDataTree.isLastFindWithDataPageScan());
 
         AtomicBoolean cancel = new AtomicBoolean();
@@ -285,7 +284,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
             while (!cancel.get() && !Thread.interrupted()) {
                 assertEquals("wrong sum!", accounts * initialBalance, ((Number)
                     cache.query(new SqlFieldsQuery("select sum(_val) from Long use index()")
-                        .setDataPageScanEnabled(true)).getAll().get(0).get(0)).longValue());
+                        ).getAll().get(0).get(0)).longValue());
 //                info("query ok!");
             }
         }, 2, "query");
@@ -308,6 +307,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     @Test
+    @Ignore("https://ggsystems.atlassian.net/browse/GG-20800")
     public void testDataPageScan() throws Exception {
         final String cacheName = "test";
 
@@ -365,7 +365,6 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
                         "where a.z between ? and ? " +
                         "and check_scan_flag(?,true)")
                     .setLazy(true)
-                    .setDataPageScanEnabled(DirectPageScanIndexing.expectedDataPageScanEnabled)
                     .setArgs(1, expNestedLoops, DirectPageScanIndexing.expectedDataPageScanEnabled)
                     .setPageSize(keysCnt / 10) // Must be less than keysCnt.
             )
@@ -416,7 +415,6 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
 
         assertEquals(0L, cache.query(new SqlFieldsQuery(
             "update TestData set z = z + 1 where check_scan_flag(?,false)")
-            .setDataPageScanEnabled(DirectPageScanIndexing.expectedDataPageScanEnabled)
             .setArgs(DirectPageScanIndexing.expectedDataPageScanEnabled)
         ).getAll().get(0).get(0));
 
@@ -454,7 +452,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
         assertTrue(cache.query(new SqlQuery<>(TestData.class,
             "from TestData use index() where check_scan_flag(?,false)") // Force full scan with USE INDEX()
             .setArgs(DirectPageScanIndexing.expectedDataPageScanEnabled)
-            .setDataPageScanEnabled(DirectPageScanIndexing.expectedDataPageScanEnabled))
+            )
             .getAll().isEmpty());
 
         checkSqlLastFindDataPageScan(dataPageScanEnabled);
@@ -483,8 +481,7 @@ public class QueryDataPageScanTest extends GridCommonAbstractTest {
     }
 
     private void checkScanQuery(IgniteCache<Long,TestData> cache, Boolean dataPageScanEnabled, Boolean expLastDataPageScan) {
-        assertTrue(cache.query(new ScanQuery<>(new TestPredicate())
-            .setDataPageScanEnabled(dataPageScanEnabled)).getAll().isEmpty());
+        assertTrue(cache.query(new ScanQuery<>(new TestPredicate())).getAll().isEmpty());
         assertEquals(expLastDataPageScan, CacheDataTree.isLastFindWithDataPageScan());
     }
 
diff --git a/parent/pom.xml b/parent/pom.xml
index 21324ab..d66828e 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -90,7 +90,7 @@
         <jmh.version>1.13</jmh.version>
         <jms.spec.version>1.1.1</jms.spec.version>
         <jna.version>4.5.2</jna.version>
-        <jnr.posix.version>3.0.46</jnr.posix.version>
+        <jnr.posix.version>3.0.50</jnr.posix.version>
         <jotm.version>2.2.3</jotm.version>
         <jsch.bundle.version>0.1.54_1</jsch.bundle.version>
         <jsch.version>0.1.54</jsch.version>