Handle host id conflicts properly.
Patch by brandonwilliams, reviewed by Tyler Hobbs for CASSANDRA-6615


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

Branch: refs/heads/trunk
Commit: 6c4333e3d47dfe3fad9781e3c36a5c84476af1d3
Parents: 1d81765
Author: Brandon Williams <brandonwilli...@apache.org>
Authored: Wed Jan 29 17:30:42 2014 -0600
Committer: Brandon Williams <brandonwilli...@apache.org>
Committed: Wed Jan 29 17:31:45 2014 -0600

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 src/java/org/apache/cassandra/gms/Gossiper.java |  2 +-
 .../cassandra/service/StorageService.java       | 40 +++++++++++++++++---
 3 files changed, 36 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c4333e3/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 2920c15..d88bb26 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -19,6 +19,7 @@
  * Add properties to adjust FD initial value and max interval (CASSANDRA-4375)
  * Fix preparing with batch and delete from collection (CASSANDRA-6607)
  * Fix ABSC reverse iterator's remove() method (CASSANDRA-6629)
+ * Handle host ID conflicts properly (CASSANDRA-6615)
 
 
 1.2.13

http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c4333e3/src/java/org/apache/cassandra/gms/Gossiper.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/gms/Gossiper.java 
b/src/java/org/apache/cassandra/gms/Gossiper.java
index 3ed6cba..b51bbd3 100644
--- a/src/java/org/apache/cassandra/gms/Gossiper.java
+++ b/src/java/org/apache/cassandra/gms/Gossiper.java
@@ -596,7 +596,7 @@ public class Gossiper implements 
IFailureDetectionEventListener, GossiperMBean
         {
             return false;
         }
-        return !isDeadState(epState) && !epState.isAlive() && 
!StorageService.instance.getTokenMetadata().isMember(endpoint);
+        return !isDeadState(epState) && 
!StorageService.instance.getTokenMetadata().isMember(endpoint);
     }
 
     private void doStatusCheck()

http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c4333e3/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java 
b/src/java/org/apache/cassandra/service/StorageService.java
index ab266d8..c93ea5b 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -1453,6 +1453,12 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
 
         tokens = getTokensFor(endpoint, pieces[1]);
 
+        Set<Token> tokensToUpdateInMetadata = new HashSet<Token>();
+        Set<Token> tokensToUpdateInSystemTable = new HashSet<Token>();
+        Set<Token> localTokensToRemove = new HashSet<Token>();
+        Set<InetAddress> endpointsToRemove = new HashSet<InetAddress>();
+
+
         if (logger.isDebugEnabled())
             logger.debug("Node " + endpoint + " state normal, token " + 
tokens);
 
@@ -1463,16 +1469,38 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
         if (Gossiper.instance.usesHostId(endpoint))
         {
             UUID hostId = Gossiper.instance.getHostId(endpoint);
+            InetAddress existing = tokenMetadata.getEndpointForHostId(hostId);
             if (DatabaseDescriptor.isReplacing() && 
Gossiper.instance.getEndpointStateForEndpoint(DatabaseDescriptor.getReplaceAddress())
 != null && 
(hostId.equals(Gossiper.instance.getHostId(DatabaseDescriptor.getReplaceAddress()))))
                 logger.warn("Not updating token metadata for {} because I am 
replacing it", endpoint);
             else
-                tokenMetadata.updateHostId(hostId, endpoint);
-        }
+            {
+                if (existing != null && !existing.equals(endpoint))
+                {
+                    if (existing.equals(FBUtilities.getBroadcastAddress()))
+                    {
+                        logger.warn("Not updating host ID {} for {} because 
it's mine", hostId, endpoint);
+                        tokenMetadata.removeEndpoint(endpoint);
+                        endpointsToRemove.add(endpoint);
+                    }
+                    else if 
(Gossiper.instance.compareEndpointStartup(endpoint, existing) > 0)
+                    {
+                        logger.warn("Host ID collision for {} between {} and 
{}; {} is the new owner", hostId, existing, endpoint, endpoint);
+                        tokenMetadata.removeEndpoint(existing);
+                        endpointsToRemove.add(existing);
+                        tokenMetadata.updateHostId(hostId, endpoint);
+                    }
+                    else
+                    {
+                        logger.warn("Host ID Collision for {} between {} and 
{}; ignored {}", hostId, existing, endpoint, endpoint);
+                        tokenMetadata.removeEndpoint(endpoint);
+                        endpointsToRemove.add(endpoint);
+                    }
+                }
+                else
+                    tokenMetadata.updateHostId(hostId, endpoint);
+            }
 
-        Set<Token> tokensToUpdateInMetadata = new HashSet<Token>();
-        Set<Token> tokensToUpdateInSystemTable = new HashSet<Token>();
-        Set<Token> localTokensToRemove = new HashSet<Token>();
-        Set<InetAddress> endpointsToRemove = new HashSet<InetAddress>();
+        }
 
         for (final Token token : tokens)
         {

Reply via email to