You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2014/12/09 21:10:00 UTC
cassandra git commit: Refuse Paxos operations with more than one
pending endpoints
Repository: cassandra
Updated Branches:
refs/heads/cassandra-2.0 71e1219de -> 77df5578a
Refuse Paxos operations with more than one pending endpoints
patch by slebresne; reviewed by kohlisankalp for CASSANDRA-8346
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/77df5578
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/77df5578
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/77df5578
Branch: refs/heads/cassandra-2.0
Commit: 77df5578a0c80f9e8b5de914fa75d1bda023a4f5
Parents: 71e1219
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Tue Dec 9 21:08:48 2014 +0100
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Tue Dec 9 21:08:48 2014 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cassandra/exceptions/UnavailableException.java | 7 ++++++-
.../org/apache/cassandra/service/StorageProxy.java | 14 +++++++++++++-
3 files changed, 20 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/77df5578/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 7c89e60..3c651ff 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.0.12:
+ * Refuse Paxos operation with more than one pending endpoint (CASSANDRA-8346)
* Throw correct exception when trying to bind a keyspace or table
name (CASSANDRA-6952)
* Make HHOM.compact synchronized (CASSANDRA-8416)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/77df5578/src/java/org/apache/cassandra/exceptions/UnavailableException.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/exceptions/UnavailableException.java b/src/java/org/apache/cassandra/exceptions/UnavailableException.java
index e557550..baee0b2 100644
--- a/src/java/org/apache/cassandra/exceptions/UnavailableException.java
+++ b/src/java/org/apache/cassandra/exceptions/UnavailableException.java
@@ -27,7 +27,12 @@ public class UnavailableException extends RequestExecutionException
public UnavailableException(ConsistencyLevel consistency, int required, int alive)
{
- super(ExceptionCode.UNAVAILABLE, "Cannot achieve consistency level " + consistency);
+ this("Cannot achieve consistency level " + consistency, consistency, required, alive);
+ }
+
+ public UnavailableException(String msg, ConsistencyLevel consistency, int required, int alive)
+ {
+ super(ExceptionCode.UNAVAILABLE, msg);
this.consistency = consistency;
this.required = required;
this.alive = alive;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/77df5578/src/java/org/apache/cassandra/service/StorageProxy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java
index d8b6619..f877aee 100644
--- a/src/java/org/apache/cassandra/service/StorageProxy.java
+++ b/src/java/org/apache/cassandra/service/StorageProxy.java
@@ -304,6 +304,7 @@ public class StorageProxy implements StorageProxyMBean
Token tk = StorageService.getPartitioner().getToken(key);
List<InetAddress> naturalEndpoints = StorageService.instance.getNaturalEndpoints(keyspaceName, tk);
Collection<InetAddress> pendingEndpoints = StorageService.instance.getTokenMetadata().pendingEndpointsFor(tk, keyspaceName);
+
if (consistencyForPaxos == ConsistencyLevel.LOCAL_SERIAL)
{
// Restrict naturalEndpoints and pendingEndpoints to node in the local DC only
@@ -312,10 +313,21 @@ public class StorageProxy implements StorageProxyMBean
naturalEndpoints = ImmutableList.copyOf(Iterables.filter(naturalEndpoints, isLocalDc));
pendingEndpoints = ImmutableList.copyOf(Iterables.filter(pendingEndpoints, isLocalDc));
}
- int requiredParticipants = pendingEndpoints.size() + 1 + naturalEndpoints.size() / 2; // See CASSANDRA-833
+ int participants = pendingEndpoints.size() + naturalEndpoints.size();
+ int requiredParticipants = participants + 1 / 2; // See CASSANDRA-833
List<InetAddress> liveEndpoints = ImmutableList.copyOf(Iterables.filter(Iterables.concat(naturalEndpoints, pendingEndpoints), IAsyncCallback.isAlive));
if (liveEndpoints.size() < requiredParticipants)
throw new UnavailableException(consistencyForPaxos, requiredParticipants, liveEndpoints.size());
+
+ // We cannot allow CAS operations with 2 or more pending endpoints, see #8346.
+ // Note that we fake an impossible number of required nodes in the unavailable exception
+ // to nail home the point that it's an impossible operation no matter how many nodes are live.
+ if (pendingEndpoints.size() > 1)
+ throw new UnavailableException(String.format("Cannot perform LWT operation as there is more than one (%d) pending range movement", pendingEndpoints.size()),
+ consistencyForPaxos,
+ participants + 1,
+ liveEndpoints.size());
+
return Pair.create(liveEndpoints, requiredParticipants);
}