You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/07/27 11:31:34 UTC

[12/21] ignite git commit: IGNITE-5761 Add correct message when entries are not mapped to at least one node and avoid hang on rollback

IGNITE-5761 Add correct message when entries are not mapped to at least one node and avoid hang on rollback


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/bcbb10d4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bcbb10d4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bcbb10d4

Branch: refs/heads/ignite-5816
Commit: bcbb10d4ed72c3ac2cd8149bb5cd148f63e95725
Parents: 995258f
Author: Igor Seliverstov <gv...@gmail.com>
Authored: Thu Jul 27 09:44:34 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Jul 27 09:44:34 2017 +0300

----------------------------------------------------------------------
 ...arOptimisticSerializableTxPrepareFuture.java |   9 +
 .../near/GridNearOptimisticTxPrepareFuture.java |  15 ++
 .../GridNearPessimisticTxPrepareFuture.java     |   9 +-
 .../dht/NotMappedPartitionInTxTest.java         | 247 +++++++++++++++++++
 .../testsuites/IgniteCacheTestSuite5.java       |   2 +
 5 files changed, 281 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bcbb10d4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
index 72ddc67..561c4f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -29,6 +29,7 @@ import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.cluster.ClusterTopologyException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -611,6 +612,14 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
             cacheCtx.affinity().nodesByKey(entry.key(), topVer) :
             cacheCtx.topology().nodes(cacheCtx.affinity().partition(entry.key()), topVer);
 
+        if (F.isEmpty(nodes)) {
+            onDone(new ClusterTopologyServerNotFoundException("Failed to map keys to nodes " +
+                "(partition is not mapped to any node) [key=" + entry.key() +
+                ", partition=" + cacheCtx.affinity().partition(entry.key()) + ", topVer=" + topVer + ']'));
+
+            return;
+        }
+
         txMapping.addMapping(nodes);
 
         ClusterNode primary = F.first(nodes);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bcbb10d4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index edddf7d..1e7a567 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -32,6 +32,7 @@ import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.cluster.ClusterTopologyException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -430,6 +431,10 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
 
             GridDistributedTxMapping updated = map(write, topVer, cur, topLocked, remap);
 
+            if(updated == null)
+                // an exception occurred while transaction mapping, stop further processing
+                break;
+
             if (write.context().isNear())
                 hasNearCache = true;
 
@@ -640,6 +645,16 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
                 cacheCtx.affinity().nodesByKey(entry.key(), topVer) :
                 cacheCtx.topology().nodes(cacheCtx.affinity().partition(entry.key()), topVer);
 
+        if (F.isEmpty(nodes)) {
+            ClusterTopologyServerNotFoundException e = new ClusterTopologyServerNotFoundException("Failed to map " +
+                "keys to nodes (partition is not mapped to any node) [key=" + entry.key() +
+                ", partition=" + cacheCtx.affinity().partition(entry.key()) + ", topVer=" + topVer + ']');
+
+            onDone(e);
+
+            return null;
+        }
+
         txMapping.addMapping(nodes);
 
         ClusterNode primary = F.first(nodes);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bcbb10d4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
index e934319..11cd9f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
@@ -27,6 +27,7 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -282,7 +283,13 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
             else
                 nodes = cacheCtx.affinity().nodesByKey(txEntry.key(), topVer);
 
-            assert !nodes.isEmpty();
+            if (F.isEmpty(nodes)) {
+                onDone(new ClusterTopologyServerNotFoundException("Failed to map keys to nodes (partition " +
+                    "is not mapped to any node) [key=" + txEntry.key() +
+                    ", partition=" + cacheCtx.affinity().partition(txEntry.key()) + ", topVer=" + topVer + ']'));
+
+                return;
+            }
 
             ClusterNode primary = nodes.get(0);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bcbb10d4/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/NotMappedPartitionInTxTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/NotMappedPartitionInTxTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/NotMappedPartitionInTxTest.java
new file mode 100644
index 0000000..4059660
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/NotMappedPartitionInTxTest.java
@@ -0,0 +1,247 @@
+package org.apache.ignite.internal.processors.cache.distributed.dht;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.READ_COMMITTED;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ */
+@SuppressWarnings({"unchecked", "ThrowableNotThrown"})
+public class NotMappedPartitionInTxTest extends GridCommonAbstractTest {
+    /** Cache. */
+    private static final String CACHE = "testCache";
+
+    /** Cache 2. */
+    public static final String CACHE2 = CACHE + 1;
+
+    /** Test key. */
+    private static final String TEST_KEY = "key";
+
+    /** Is client. */
+    private boolean isClient;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        return super.getConfiguration(gridName)
+            .setClientMode(isClient)
+            .setCacheConfiguration(
+                new CacheConfiguration(CACHE)
+                    .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)
+                    .setCacheMode(CacheMode.REPLICATED)
+                    .setAffinity(new TestAffinity()),
+                new CacheConfiguration(CACHE2)
+                    .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
+    }
+
+    /**
+     *
+     */
+    public void testOneServerOptimistic() throws Exception {
+        try {
+            isClient = false;
+            startGrid(0);
+
+            isClient = true;
+            final IgniteEx client = startGrid(1);
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    testNotMapped(client, OPTIMISTIC, REPEATABLE_READ);
+
+                    return null;
+                }
+            }, ClusterTopologyServerNotFoundException.class, "Failed to map keys to nodes (partition is not mapped to any node)");
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     *
+     */
+    public void testOneServerOptimisticSerializable() throws Exception {
+        try {
+            isClient = false;
+            startGrid(0);
+
+            isClient = true;
+            final IgniteEx client = startGrid(1);
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    testNotMapped(client, OPTIMISTIC, SERIALIZABLE);
+
+                    return null;
+                }
+            }, ClusterTopologyServerNotFoundException.class, "Failed to map keys to nodes (partition is not mapped to any node)");
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     *
+     */
+    public void testOneServerPessimistic() throws Exception {
+        try {
+            isClient = false;
+            startGrid(0);
+
+            isClient = true;
+            final IgniteEx client = startGrid(1);
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    testNotMapped(client, PESSIMISTIC, READ_COMMITTED);
+
+                    return null;
+                }
+            }, ClusterTopologyServerNotFoundException.class, "Failed to lock keys (all partition nodes left the grid)");
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     *
+     */
+    public void testFourServersOptimistic() throws Exception {
+        try {
+            isClient = false;
+            startGrids(4);
+
+            isClient = true;
+            final IgniteEx client = startGrid(4);
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    testNotMapped(client, OPTIMISTIC, REPEATABLE_READ);
+
+                    return null;
+                }
+            }, ClusterTopologyServerNotFoundException.class, "Failed to map keys to nodes (partition is not mapped to any node)");
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     *
+     */
+    public void testFourServersOptimisticSerializable() throws Exception {
+        try {
+            isClient = false;
+            startGrids(4);
+
+            isClient = true;
+            final IgniteEx client = startGrid(4);
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    testNotMapped(client, OPTIMISTIC, SERIALIZABLE);
+
+                    return null;
+                }
+            }, ClusterTopologyServerNotFoundException.class, "Failed to map keys to nodes (partition is not mapped to any node)");
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     *
+     */
+    public void testFourServersPessimistic() throws Exception {
+        try {
+            isClient = false;
+            startGrids(4);
+
+            isClient = true;
+            final IgniteEx client = startGrid(4);
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    testNotMapped(client, PESSIMISTIC, READ_COMMITTED);
+
+                    return null;
+                }
+            }, ClusterTopologyServerNotFoundException.class, "Failed to lock keys (all partition nodes left the grid)");
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @param client Ignite client.
+     */
+    private void testNotMapped(IgniteEx client, TransactionConcurrency concurrency, TransactionIsolation isolation) {
+        IgniteCache cache2 = client.cache(CACHE2);
+        IgniteCache cache1 = client.cache(CACHE).withKeepBinary();
+
+        try(Transaction tx = client.transactions().txStart(concurrency, isolation)) {
+
+            Map<String, Integer> param = new TreeMap<>();
+            param.put(TEST_KEY + 1, 1);
+            param.put(TEST_KEY + 1, 3);
+            param.put(TEST_KEY, 3);
+
+            cache1.put(TEST_KEY, 3);
+
+            cache1.putAll(param);
+            cache2.putAll(param);
+
+            tx.commit();
+        }
+    }
+
+    /** */
+    private static class TestAffinity extends RendezvousAffinityFunction {
+        /** {@inheritDoc} */
+        @Override public int partition(Object key) {
+            if (TEST_KEY.equals(key))
+                return 1;
+
+            return super.partition(key);
+        }
+
+        /** {@inheritDoc} */
+        @Override public List<ClusterNode> assignPartition(int part, List<ClusterNode> nodes, int backups,
+            @Nullable Map<UUID, Collection<ClusterNode>> neighborhoodCache) {
+            if (part == 1)
+                return Collections.emptyList();
+
+            return super.assignPartition(part, nodes, backups, neighborhoodCache);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bcbb10d4/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
index 1395b95..dab2b19 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
@@ -41,6 +41,7 @@ import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitio
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheGroupsPartitionLossPolicySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCachePartitionLossPolicySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheTxIteratorSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.dht.NotMappedPartitionInTxTest;
 import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.IgniteCacheAtomicProtocolTest;
 import org.apache.ignite.internal.processors.cache.distributed.rebalancing.CacheManualRebalancingTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheSyncRebalanceModeSelfTest;
@@ -94,6 +95,7 @@ public class IgniteCacheTestSuite5 extends TestSuite {
         suite.addTestSuite(GridCachePartitionExchangeManagerHistSizeTest.class);
 
         suite.addTestSuite(GridCachePartitionEvictionDuringReadThroughSelfTest.class);
+        suite.addTestSuite(NotMappedPartitionInTxTest.class);
 
         return suite;
     }