You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2019/09/04 12:45:15 UTC

[ignite] branch master updated: IGNITE-12112: H2TreeIndex should throw CorruptTreeException with cacheId, cacheName and indexName. This closes #6817.

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

amashenkov 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 27f6d82  IGNITE-12112: H2TreeIndex should throw CorruptTreeException with cacheId, cacheName and indexName. This closes #6817.
27f6d82 is described below

commit 27f6d824f4b1a055d6e1960e7b65786156f00243
Author: denis-chudov <mo...@gmail.com>
AuthorDate: Wed Sep 4 15:39:52 2019 +0300

    IGNITE-12112: H2TreeIndex should throw CorruptTreeException with cacheId, cacheName and indexName. This closes #6817.
---
 .../benchmarks/jmh/tree/BPlusTreeBenchmark.java    |   1 +
 .../processors/cache/mvcc/txlog/TxLogTree.java     |   1 +
 .../cache/persistence/DataStructure.java           |  12 +-
 .../cache/persistence/IndexStorageImpl.java        |   7 +-
 .../cache/persistence/freelist/PagesList.java      |   2 +-
 .../persistence/metastorage/MetastorageTree.java   |   1 +
 .../cache/persistence/tree/BPlusTree.java          |  41 ++++--
 .../persistence/tree/CorruptedTreeException.java   |  67 +++++++--
 .../processors/cache/tree/CacheDataTree.java       |   1 +
 .../processors/cache/tree/PendingEntriesTree.java  |   1 +
 .../processors/database/BPlusTreeSelfTest.java     |   1 +
 .../processors/query/h2/IgniteH2Indexing.java      |   1 +
 .../processors/query/h2/database/H2Tree.java       |  25 +++-
 .../processors/query/h2/database/H2TreeIndex.java  |   1 +
 .../index/H2TreeCorruptedTreeExceptionTest.java    | 162 +++++++++++++++++++++
 .../IgniteCacheWithIndexingTestSuite.java          |   5 +-
 16 files changed, 295 insertions(+), 34 deletions(-)

diff --git a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java
index c7ea741..7a35430 100644
--- a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java
+++ b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java
@@ -178,6 +178,7 @@ public class BPlusTreeBenchmark extends JmhAbstractBenchmark {
             super(
                 "test",
                 cacheId,
+                null,
                 pageMem,
                 null,
                 new AtomicLong(),
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java
index 200bc66..c850928 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java
@@ -53,6 +53,7 @@ public class TxLogTree extends BPlusTree<TxKey, TxRow> {
         super(
             TxLog.TX_LOG_CACHE_NAME,
             TxLog.TX_LOG_CACHE_ID,
+            TxLog.TX_LOG_CACHE_NAME,
             pageMem,
             wal,
             new AtomicLong(),
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
index 252e48f..9004a6d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
@@ -52,6 +52,9 @@ public abstract class DataStructure {
     protected final int grpId;
 
     /** */
+    protected final String grpName;
+
+    /** */
     protected final PageMemory pageMem;
 
     /** */
@@ -64,19 +67,22 @@ public abstract class DataStructure {
     protected ReuseList reuseList;
 
     /**
-     * @param cacheId Cache group ID.
+     * @param cacheGrpId Cache group ID.
+     * @param grpName Cache group name.
      * @param pageMem Page memory.
      * @param wal Write ahead log manager.
      */
     public DataStructure(
-        int cacheId,
+        int cacheGrpId,
+        String grpName,
         PageMemory pageMem,
         IgniteWriteAheadLogManager wal,
         PageLockListener lockLsnr
     ) {
         assert pageMem != null;
 
-        this.grpId = cacheId;
+        this.grpId = cacheGrpId;
+        this.grpName = grpName;
         this.pageMem = pageMem;
         this.wal = wal;
         this.lockLsnr = lockLsnr == null ? NOOP_LSNR : lockLsnr;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java
index 2be0c7a..1be0b97 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java
@@ -192,18 +192,18 @@ public class IndexStorageImpl implements IndexStorage {
     /** {@inheritDoc} */
     @Override public Collection<String> getIndexNames() throws IgniteCheckedException {
         assert metaTree != null;
-        
+
         GridCursor<IndexItem> cursor = metaTree.find(null, null);
 
         ArrayList<String> names = new ArrayList<>((int)metaTree.size());
 
         while (cursor.next()) {
             IndexItem item = cursor.get();
-            
+
             if (item != null)
                 names.add(new String(item.idxName));
         }
-        
+
         return names;
     }
 
@@ -259,6 +259,7 @@ public class IndexStorageImpl implements IndexStorage {
             super(
                 treeName("meta", "Meta"),
                 cacheId,
+                null,
                 pageMem,
                 wal,
                 globalRmvId,
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
index 7734ba4..a4767b3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
@@ -144,7 +144,7 @@ public abstract class PagesList extends DataStructure {
         long metaPageId,
         PageLockListener lockLsnr
     ) {
-        super(cacheId, pageMem, wal, lockLsnr);
+        super(cacheId, null, pageMem, wal, lockLsnr);
 
         this.name = name;
         this.buckets = buckets;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java
index 556a79a..970be5b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java
@@ -75,6 +75,7 @@ public class MetastorageTree extends BPlusTree<MetastorageSearchRow, Metastorage
         super(
             name,
             cacheId,
+            null,
             pageMem,
             wal,
             globalRmvId,
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 a24896d..fc14a5b 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
@@ -737,7 +737,8 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
 
     /**
      * @param name Tree name.
-     * @param cacheId Cache ID.
+     * @param cacheGrpId Cache group ID.
+     * @param cacheGrpName Cache group name.
      * @param pageMem Page memory.
      * @param wal Write ahead log manager.
      * @param globalRmvId Remove ID.
@@ -750,7 +751,8 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
      */
     protected BPlusTree(
         String name,
-        int cacheId,
+        int cacheGrpId,
+        String cacheGrpName,
         PageMemory pageMem,
         IgniteWriteAheadLogManager wal,
         AtomicLong globalRmvId,
@@ -763,7 +765,8 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
     ) throws IgniteCheckedException {
         this(
             name,
-            cacheId,
+            cacheGrpId,
+            cacheGrpName,
             pageMem,
             wal,
             globalRmvId,
@@ -778,7 +781,8 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
 
     /**
      * @param name Tree name.
-     * @param cacheId Cache ID.
+     * @param cacheGrpId Cache ID.
+     * @param grpName Cache group name.
      * @param pageMem Page memory.
      * @param wal Write ahead log manager.
      * @param globalRmvId Remove ID.
@@ -789,7 +793,8 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
      */
     protected BPlusTree(
         String name,
-        int cacheId,
+        int cacheGrpId,
+        String grpName,
         PageMemory pageMem,
         IgniteWriteAheadLogManager wal,
         AtomicLong globalRmvId,
@@ -798,7 +803,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
         @Nullable FailureProcessor failureProcessor,
         @Nullable PageLockListener lsnr
     ) throws IgniteCheckedException {
-        super(cacheId, pageMem, wal, lsnr);
+        super(cacheGrpId, grpName, pageMem, wal, lsnr);
 
         assert !F.isEmpty(name);
 
@@ -1570,8 +1575,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
     private void fail(Object msg) {
         AssertionError err = new AssertionError(msg);
 
-        if (failureProcessor != null)
-            failureProcessor.process(new FailureContext(FailureType.CRITICAL_ERROR, err));
+        processFailure(FailureType.CRITICAL_ERROR, err);
 
         throw err;
     }
@@ -2902,8 +2906,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
                     "(the tree may be corrupted). Increase " + IGNITE_BPLUS_TREE_LOCK_RETRIES + " system property " +
                     "if you regularly see this message (current value is " + getLockRetries() + ").");
 
-                if (failureProcessor != null)
-                    failureProcessor.process(new FailureContext(FailureType.CRITICAL_ERROR, e));
+                processFailure(FailureType.CRITICAL_ERROR, e);
 
                 throw e;
             }
@@ -5920,12 +5923,22 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
      * @param pageIds Pages ids.
      * @return New CorruptedTreeException instance.
      */
-    private CorruptedTreeException corruptedTreeException(String msg, Throwable cause, int grpId, long... pageIds) {
-        CorruptedTreeException e = new CorruptedTreeException(msg, cause, grpId, pageIds);
+    protected CorruptedTreeException corruptedTreeException(String msg, Throwable cause, int grpId, long... pageIds) {
+        CorruptedTreeException e = new CorruptedTreeException(msg, cause, grpId, grpName, pageIds);
 
-        if (failureProcessor != null)
-            failureProcessor.process(new FailureContext(FailureType.CRITICAL_ERROR, e));
+        processFailure(FailureType.CRITICAL_ERROR, e);
 
         return e;
     }
+
+    /**
+     * Processes failure with failure processor.
+     *
+     * @param failureType Failure type.
+     * @param e Exception.
+     */
+    protected void processFailure(FailureType failureType, Throwable e) {
+        if (failureProcessor != null)
+            failureProcessor.process(new FailureContext(failureType, e));
+    }
 }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/CorruptedTreeException.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/CorruptedTreeException.java
index 56dc7db..215584a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/CorruptedTreeException.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/CorruptedTreeException.java
@@ -25,9 +25,10 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.pagemem.PageIdAllocator;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
 import org.apache.ignite.internal.processors.cache.persistence.CorruptedPersistenceException;
+import org.apache.ignite.internal.util.GridStringBuilder;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.jetbrains.annotations.Nullable;
 
 import static java.util.Arrays.asList;
@@ -46,19 +47,51 @@ public class CorruptedTreeException extends IgniteCheckedException implements Co
      * @param msg Message.
      * @param cause Cause.
      * @param grpId Group id of potentially corrupted pages.
+     * @param grpName Group name of potentially corrupted pages.
      * @param pageIds Potentially corrupted pages.
      */
-    public CorruptedTreeException(String msg, @Nullable Throwable cause, int grpId, long... pageIds) {
-        this(msg, cause, toPagesArray(grpId, pageIds));
+    public CorruptedTreeException(String msg, @Nullable Throwable cause, int grpId, String grpName, long... pageIds) {
+        this(msg, null, null, grpName, cause, toPagesArray(grpId, pageIds));
     }
 
     /**
      * @param msg Message.
      * @param cause Cause.
+     * @param grpId Group id of potentially corrupted pages.
+     * @param grpName Group name of potentially corrupted pages.
+     * @param cacheName Cache name.
+     * @param indexName Index name.
+     * @param pageIds Potentially corrupted pages.
+     */
+    public CorruptedTreeException(
+        String msg,
+        @Nullable Throwable cause,
+        int grpId,
+        String grpName,
+        String cacheName,
+        String indexName,
+        long... pageIds
+    ) {
+        this(msg, cacheName, indexName, grpName,  cause, toPagesArray(grpId, pageIds));
+    }
+
+    /**
+     * @param msg Message.
+     * @param cacheName Cache name.
+     * @param indexName Index name.
+     * @param grpName Cache group name.
+     * @param cause Cause.
      * @param pages (groupId, pageId) pairs for pages that might be corrupted.
      */
-    public CorruptedTreeException(String msg, @Nullable Throwable cause, T2<Integer, Long>... pages) {
-        super(getMsg(msg, pages), cause);
+    public CorruptedTreeException(
+        String msg,
+        String cacheName,
+        String indexName,
+        String grpName,
+        @Nullable Throwable cause,
+        T2<Integer, Long>... pages
+    ) {
+        super(getMsg(msg, cacheName, indexName, grpName, pages), cause);
 
         this.pages = expandPagesArray(pages, cause);
     }
@@ -99,11 +132,25 @@ public class CorruptedTreeException extends IgniteCheckedException implements Co
     }
 
     /** */
-    private static String getMsg(String msg, T2<Integer, Long>... pages) {
-        return S.toString("B+Tree is corrupted",
-            "pages(groupId, pageId)", Arrays.toString(pages), false,
-            "msg", msg, false
-        );
+    private static String getMsg(String msg, String cacheName, String indexName, String grpName, T2<Integer, Long>... pages) {
+        GridStringBuilder stringBuilder = new GridStringBuilder("B+Tree is corrupted [")
+            .a("pages(groupId, pageId)=").a(Arrays.toString(pages));
+
+        if (cacheName != null) {
+            stringBuilder
+                .a(", cacheId=").a(CU.cacheId(cacheName))
+                .a(", cacheName=").a(cacheName);
+        }
+
+        if (indexName != null)
+            stringBuilder.a(", indexName=").a(indexName);
+
+        if (grpName != null)
+            stringBuilder.a(", groupName=").a(grpName);
+
+        stringBuilder.a(", msg=").a(msg).a("]");
+
+        return stringBuilder.toString();
     }
 
     /**
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 4bc71fa..a8f9c51 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
@@ -98,6 +98,7 @@ public class CacheDataTree extends BPlusTree<CacheSearchRow, CacheDataRow> {
         super(
             name,
             grp.groupId(),
+            grp.name(),
             grp.dataRegion().pageMemory(),
             grp.dataRegion().config().isPersistenceEnabled() ? grp.shared().wal() : null,
             grp.offheap().globalRemoveId(),
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java
index 88de417..763ea93 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java
@@ -57,6 +57,7 @@ public class PendingEntriesTree extends BPlusTree<PendingRow, PendingRow> {
         super(
             name,
             grp.groupId(),
+            grp.name(),
             pageMem,
             grp.dataRegion().config().isPersistenceEnabled() ? grp.shared().wal() : null,
             grp.offheap().globalRemoveId(),
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java
index 9490c29..f946382 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java
@@ -2743,6 +2743,7 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest {
             super(
                 "test",
                 cacheId,
+                null,
                 pageMem,
                 null,
                 new AtomicLong(),
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 5ac88d4..f1b9959 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
@@ -2364,6 +2364,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         BPlusTree<H2Row, H2Row> tree = new BPlusTree<H2Row, H2Row>(
             indexName,
             grpId,
+            grpName,
             pageMemory,
             ctx.cache().context().wal(),
             removeId,
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java
index 2297b3d..7ab1d74 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java
@@ -26,6 +26,8 @@ import java.util.stream.Collectors;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.failure.FailureType;
+import org.apache.ignite.internal.metric.IoStatisticsHolder;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
 import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
@@ -33,6 +35,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.mvcc.MvccUtils;
 import org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter;
 import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree;
+import org.apache.ignite.internal.processors.cache.persistence.tree.CorruptedTreeException;
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO;
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusMetaIO;
 import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
@@ -43,9 +46,8 @@ import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasInnerI
 import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasLeafIO;
 import org.apache.ignite.internal.processors.query.h2.database.io.H2RowLinkIO;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
-import org.apache.ignite.internal.processors.query.h2.opt.H2Row;
 import org.apache.ignite.internal.processors.query.h2.opt.H2CacheRow;
-import org.apache.ignite.internal.metric.IoStatisticsHolder;
+import org.apache.ignite.internal.processors.query.h2.opt.H2Row;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.h2.result.SearchRow;
@@ -159,6 +161,7 @@ public class H2Tree extends BPlusTree<H2Row, H2Row> {
         String tblName,
         ReuseList reuseList,
         int grpId,
+        String grpName,
         PageMemory pageMem,
         IgniteWriteAheadLogManager wal,
         AtomicLong globalRmvId,
@@ -178,6 +181,7 @@ public class H2Tree extends BPlusTree<H2Row, H2Row> {
         super(
             name,
             grpId,
+            grpName,
             pageMem,
             wal,
             globalRmvId,
@@ -655,4 +659,21 @@ public class H2Tree extends BPlusTree<H2Row, H2Row> {
     @Override public String toString() {
         return S.toString(H2Tree.class, this, "super", super.toString());
     }
+
+    /**
+     * Construct the exception and invoke failure processor.
+     *
+     * @param msg Message.
+     * @param cause Cause.
+     * @param grpId Group id.
+     * @param pageIds Pages ids.
+     * @return New CorruptedTreeException instance.
+     */
+    @Override protected CorruptedTreeException corruptedTreeException(String msg, Throwable cause, int grpId, long... pageIds) {
+        CorruptedTreeException e = new CorruptedTreeException(msg, cause, grpId, grpName, cacheName, idxName, pageIds);
+
+        processFailure(FailureType.CRITICAL_ERROR, e);
+
+        return e;
+    }
 }
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
index 7711b42..8f61270 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
@@ -234,6 +234,7 @@ public class H2TreeIndex extends H2TreeIndexBase {
                     table.cacheName(),
                     cctx.offheap().reuseListForIndex(treeName),
                     cctx.groupId(),
+                    cctx.group().name(),
                     cctx.dataRegion().pageMemory(),
                     cctx.shared().wal(),
                     cctx.offheap().globalRemoveId(),
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2TreeCorruptedTreeExceptionTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2TreeCorruptedTreeExceptionTest.java
new file mode 100644
index 0000000..1b8fdd6
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2TreeCorruptedTreeExceptionTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.index;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.metric.IoStatisticsHolder;
+import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree;
+import org.apache.ignite.internal.processors.cache.persistence.tree.CorruptedTreeException;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandler;
+import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandlerWrapper;
+import org.apache.ignite.internal.processors.query.h2.database.H2Tree;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.testframework.ListeningTestLogger;
+import org.apache.ignite.testframework.LogListener;
+import org.apache.ignite.testframework.MessageOrderLogListener;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static java.lang.String.format;
+
+/** */
+public class H2TreeCorruptedTreeExceptionTest extends GridCommonAbstractTest {
+    /** */
+    private static final String IDX_NAME = "A_IDX";
+
+    /** */
+    private static final String GRP_NAME = "cacheGrp";
+
+    /** */
+    private final AtomicBoolean failWithCorruptTree = new AtomicBoolean(false);
+
+    /** */
+    private PageHandlerWrapper<BPlusTree.Result> regularWrapper;
+
+    /** */
+    private final LogListener logListener = new MessageOrderLogListener(
+        format(".*?Tree is corrupted.*?cacheId=65, cacheName=A, indexName=%s, groupName=%s.*", IDX_NAME, GRP_NAME)
+    );
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setConsistentId(gridName);
+
+        cfg.setCacheConfiguration(new CacheConfiguration<>()
+            .setName(DEFAULT_CACHE_NAME)
+            .setAffinity(new RendezvousAffinityFunction().setPartitions(1))
+            .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)
+        );
+
+        ListeningTestLogger listeningTestLog = new ListeningTestLogger(false, log);
+
+        listeningTestLog.registerListener(logListener);
+
+        cfg.setGridLogger(listeningTestLog);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+
+        cleanPersistenceDir();
+
+        regularWrapper = BPlusTree.pageHndWrapper;
+
+        BPlusTree.pageHndWrapper = (tree, hnd) -> {
+            if (hnd instanceof BPlusTree.Insert) {
+                PageHandler<Object, BPlusTree.Result> delegate = (PageHandler<Object, BPlusTree.Result>)hnd;
+
+                return new PageHandler<Object, BPlusTree.Result>() {
+                    @Override public BPlusTree.Result run(
+                        int cacheId,
+                        long pageId,
+                        long page,
+                        long pageAddr,
+                        PageIO io,
+                        Boolean walPlc,
+                        Object arg,
+                        int intArg,
+                        IoStatisticsHolder statHolder
+                    ) throws IgniteCheckedException {
+                        BPlusTree.Result res =
+                            delegate.run(cacheId, pageId, page, pageAddr, io, walPlc, arg, intArg, statHolder);
+
+                        if (failWithCorruptTree.get() && tree instanceof H2Tree && tree.getName().contains(IDX_NAME))
+                            throw new RuntimeException("test exception");
+
+                        return res;
+                    }
+                };
+            }
+            else
+                return hnd;
+        };
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        //restoring wrapper
+        BPlusTree.pageHndWrapper = regularWrapper;
+
+        stopAllGrids();
+
+        cleanPersistenceDir();
+
+        super.afterTest();
+    }
+
+    /** */
+    @Test
+    public void testCorruptedTree() throws Exception {
+        IgniteEx srv = startGrid(0);
+
+        srv.cluster().active(true);
+
+        IgniteCache<Integer, Integer> cache = srv.getOrCreateCache(DEFAULT_CACHE_NAME);
+
+        cache.query(new SqlFieldsQuery("create table a (id integer primary key, a integer) with \"CACHE_GROUP=" + GRP_NAME + "\""));
+        cache.query(new SqlFieldsQuery("create index " + IDX_NAME + " on a(a)"));
+
+        failWithCorruptTree.set(true);
+
+        try {
+            cache.query(new SqlFieldsQuery("insert into a(id, a) values (11, 1)"));
+
+            fail("Cache operations are expected to fail");
+        }
+        catch (Throwable e) {
+            assertTrue(X.hasCause(e, CorruptedTreeException.class));
+        }
+
+        assertTrue(logListener.check());
+    }
+}
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java
index dfcce97..0c68da9 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java
@@ -37,6 +37,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheConfigurationPrimi
 import org.apache.ignite.internal.processors.cache.IgniteCacheGroupsSqlTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheStarvationOnRebalanceTest;
 import org.apache.ignite.internal.processors.cache.IgniteClientReconnectQueriesTest;
+import org.apache.ignite.internal.processors.cache.index.H2TreeCorruptedTreeExceptionTest;
 import org.apache.ignite.internal.processors.cache.persistence.RebuildIndexLogMessageTest;
 import org.apache.ignite.internal.processors.cache.ttl.CacheTtlAtomicLocalSelfTest;
 import org.apache.ignite.internal.processors.cache.ttl.CacheTtlAtomicPartitionedSelfTest;
@@ -94,7 +95,9 @@ import org.junit.runners.Suite;
 
     CacheGroupMetricsWithIndexTest.class,
 
-    RebuildIndexLogMessageTest.class
+    RebuildIndexLogMessageTest.class,
+
+    H2TreeCorruptedTreeExceptionTest.class
 })
 public class IgniteCacheWithIndexingTestSuite {
 }