You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by il...@apache.org on 2020/12/25 13:16:08 UTC

[ignite] branch master updated: IGNITE-13507 Fix NullPointerException on tx recovery - Fixes #8547.

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

ilyak 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 732268e  IGNITE-13507 Fix NullPointerException on tx recovery - Fixes #8547.
732268e is described below

commit 732268ee040921333701bdc87fa5b77e1067d9fc
Author: pvinokurov <vi...@gmail.com>
AuthorDate: Fri Dec 25 16:15:13 2020 +0300

    IGNITE-13507 Fix NullPointerException on tx recovery - Fixes #8547.
    
    Signed-off-by: Ilya Kasnacheev <il...@gmail.com>
---
 .../cache/transactions/IgniteTxManager.java        |   9 +-
 .../TxRecoveryOnCoordniatorFailTest.java           | 116 +++++++++++++++++++++
 .../ignite/testsuites/IgniteCacheTestSuite9.java   |   2 +
 3 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index 34834ba..a561b9b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -3375,9 +3375,12 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
          * @return True if message required, false otherwise.
          */
         private boolean isMvccRecoveryMessageRequired() {
-            return node.isClient() && mvccCrd != null && mvccCrd.nodeId() != null &&
-                (cctx.kernalContext().coordinators().mvccEnabled() ||
-                    !IgniteFeatures.nodeSupports(cctx.node(mvccCrd.nodeId()), IgniteFeatures.MVCC_TX_RECOVERY_PROTOCOL_V2));
+            ClusterNode mvccCrdNode = null;
+
+            if (mvccCrd != null && mvccCrd.nodeId() != null)
+                mvccCrdNode = cctx.node(mvccCrd.nodeId());
+
+            return node.isClient() && mvccCrdNode != null && cctx.kernalContext().coordinators().mvccEnabled();
         }
 
         /**
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxRecoveryOnCoordniatorFailTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxRecoveryOnCoordniatorFailTest.java
new file mode 100644
index 0000000..d45c434
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxRecoveryOnCoordniatorFailTest.java
@@ -0,0 +1,116 @@
+/*
+ *  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.transactions;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.failure.AbstractFailureHandler;
+import org.apache.ignite.failure.FailureContext;
+import org.apache.ignite.internal.managers.communication.GridIoPolicy;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests failure handler is not triggered after client node and coordinator left cluster.
+ */
+public class TxRecoveryOnCoordniatorFailTest extends GridCommonAbstractTest {
+    /**  */
+    private AtomicReference<Throwable> err;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        return super.getConfiguration(igniteInstanceName)
+            .setSystemThreadPoolSize(1)
+            .setFailureHandler(new AbstractFailureHandler() {
+                @Override protected boolean handle(Ignite ignite, FailureContext failureCtx) {
+                    err.compareAndSet(null, failureCtx.error());
+
+                    return false;
+                }
+            });
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+
+        err = new AtomicReference<>();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+    }
+
+    /**
+     * Checks for the absence of critical failures caused by tx recovery after client and coordinator left the cluster.
+     * <p>Test scenario:</p>
+     * <ul>
+     *  <li>Start 2 server nodes and client node.</li>
+     *  <li>Execute long runing task in the single threaded system pool on the second server node. It delays execution of tx recovery.</li>
+     *  <li>Stop client and coordinator nodes.</li>
+     *  <li>Check triggering of failure handler.</li>
+     * </ul>
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testCoordinatorLeftCluster() throws Exception {
+        startGrids(2);
+
+        Ignite client = startClientGrid(2);
+
+        Executor sysPool = grid(1).context().pools().poolForPolicy(GridIoPolicy.SYSTEM_POOL);
+
+        sysPool.execute(new Runnable() {
+            @Override public void run() {
+                try {
+                    waitForTopology(1);
+                }
+                catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+                catch (Exception ignored) {
+                }
+            }
+        });
+
+        client.close();
+
+        grid(0).close();
+
+        // Make sure that tx recovery is already executed in the system thread pool.
+        CountDownLatch latch = new CountDownLatch(1);
+        sysPool.execute(latch::countDown);
+
+        latch.await();
+
+        Throwable error = err.get();
+
+        if (error != null)
+            Assert.fail("Critical failure occurred '" + error + "'");
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
index 3a7dc5b..1923e5f 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
@@ -61,6 +61,7 @@ import org.apache.ignite.internal.processors.cache.transactions.TxPartitionCount
 import org.apache.ignite.internal.processors.cache.transactions.TxPartitionCounterStatePutTest;
 import org.apache.ignite.internal.processors.cache.transactions.TxPartitionCounterStateTwoPrimaryTwoBackupsTest;
 import org.apache.ignite.internal.processors.cache.transactions.TxPartitionCounterStateWithFilterTest;
+import org.apache.ignite.internal.processors.cache.transactions.TxRecoveryOnCoordniatorFailTest;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.DynamicSuite;
 import org.junit.runner.RunWith;
@@ -140,6 +141,7 @@ public class IgniteCacheTestSuite9 {
         GridTestUtils.addTestIfNeeded(suite, GridCacheDataTypesCoverageTest.class, ignoredTests);
 
         GridTestUtils.addTestIfNeeded(suite, RebalanceStatisticsTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, TxRecoveryOnCoordniatorFailTest.class, ignoredTests);
 
         return suite;
     }