You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2012/07/28 16:47:14 UTC

[3/4] git commit: seed status no longer affects bootstrap setting patch by jbellis; reviewed by slebresne for CASSANDRA-4427

seed status no longer affects bootstrap setting
patch by jbellis; reviewed by slebresne for CASSANDRA-4427


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

Branch: refs/heads/trunk
Commit: 0819ad144c8e3e4c035f8254743ec9cd1f82b919
Parents: 96075b3
Author: Jonathan Ellis <jb...@apache.org>
Authored: Sat Jul 28 09:37:15 2012 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Sat Jul 28 09:37:52 2012 -0500

----------------------------------------------------------------------
 CHANGES.txt                                        |    1 +
 src/java/org/apache/cassandra/config/Schema.java   |   32 ++++-----
 .../org/apache/cassandra/gms/VersionedValue.java   |    2 +-
 .../apache/cassandra/service/MigrationManager.java |    4 +-
 .../apache/cassandra/service/StorageService.java   |   52 ++++++++++-----
 5 files changed, 53 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/0819ad14/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index fd6991c..78d7267 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -28,6 +28,7 @@ Merged from 1.0:
  * Fix LCS splitting sstable base on uncompressed size (CASSANDRA-4419)
  * Bootstraps that fail are detected upon restart and will retry safely without
    needing to delete existing data first (CASSANDRA-4427)
+ * seed status no longer disables bootstrap (CASSANDRA-4427)
  * (cqlsh) add a COPY TO command to copy a CF to a CSV file (CASSANDRA-4434)
  * Don't purge columns during upgradesstables (CASSANDRA-4462)
  * Push the validation of secondary index values to the SecondaryIndexManager (CASSANDRA-4240)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0819ad14/src/java/org/apache/cassandra/config/Schema.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/Schema.java b/src/java/org/apache/cassandra/config/Schema.java
index 9501778..95d092f 100644
--- a/src/java/org/apache/cassandra/config/Schema.java
+++ b/src/java/org/apache/cassandra/config/Schema.java
@@ -21,6 +21,7 @@ package org.apache.cassandra.config;
 import java.io.IOError;
 import java.nio.ByteBuffer;
 import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReadWriteLock;
@@ -69,8 +70,20 @@ public class Schema
     private final BiMap<Pair<String, String>, Integer> cfIdMap = HashBiMap.create();
 
     private volatile UUID version;
-    private final ReadWriteLock versionLock = new ReentrantReadWriteLock();
 
+    public static final UUID emptyVersion;
+
+    static
+    {
+        try
+        {
+            emptyVersion = UUID.nameUUIDFromBytes(MessageDigest.getInstance("MD5").digest());
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            throw new AssertionError();
+        }
+    }
 
     /**
      * Initialize empty schema object
@@ -428,16 +441,7 @@ public class Schema
      */
     public UUID getVersion()
     {
-        versionLock.readLock().lock();
-
-        try
-        {
-            return version;
-        }
-        finally
-        {
-            versionLock.readLock().unlock();
-        }
+        return version;
     }
 
     /**
@@ -446,8 +450,6 @@ public class Schema
      */
     public void updateVersion()
     {
-        versionLock.writeLock().lock();
-
         try
         {
             MessageDigest versionDigest = MessageDigest.getInstance("MD5");
@@ -466,10 +468,6 @@ public class Schema
         {
             throw new RuntimeException(e);
         }
-        finally
-        {
-            versionLock.writeLock().unlock();
-        }
     }
 
     /*

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0819ad14/src/java/org/apache/cassandra/gms/VersionedValue.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/gms/VersionedValue.java b/src/java/org/apache/cassandra/gms/VersionedValue.java
index 85c9b38..0b89c5a 100644
--- a/src/java/org/apache/cassandra/gms/VersionedValue.java
+++ b/src/java/org/apache/cassandra/gms/VersionedValue.java
@@ -113,7 +113,7 @@ public class VersionedValue implements Comparable<VersionedValue>
             return new VersionedValue(String.valueOf(load));
         }
 
-        public VersionedValue migration(UUID newVersion)
+        public VersionedValue schema(UUID newVersion)
         {
             return new VersionedValue(newVersion.toString());
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0819ad14/src/java/org/apache/cassandra/service/MigrationManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/MigrationManager.java b/src/java/org/apache/cassandra/service/MigrationManager.java
index a067de3..eedb20d 100644
--- a/src/java/org/apache/cassandra/service/MigrationManager.java
+++ b/src/java/org/apache/cassandra/service/MigrationManager.java
@@ -236,7 +236,7 @@ public class MigrationManager implements IEndpointStateChangeSubscriber
     public static void passiveAnnounce(UUID version)
     {
         assert Gossiper.instance.isEnabled();
-        Gossiper.instance.addLocalApplicationState(ApplicationState.SCHEMA, StorageService.instance.valueFactory.migration(version));
+        Gossiper.instance.addLocalApplicationState(ApplicationState.SCHEMA, StorageService.instance.valueFactory.schema(version));
         logger.debug("Gossiping my schema version " + version);
     }
 
@@ -403,7 +403,6 @@ public class MigrationManager implements IEndpointStateChangeSubscriber
 
             IAsyncCallback cb = new IAsyncCallback()
             {
-                @Override
                 public void response(Message message)
                 {
                     try
@@ -420,7 +419,6 @@ public class MigrationManager implements IEndpointStateChangeSubscriber
                     }
                 }
 
-                @Override
                 public boolean isLatencyForSnitch()
                 {
                     return false;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0819ad14/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 bfc8c81..5591488 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -557,30 +557,47 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe
 
         HintedHandOffManager.instance.start();
 
-        if (DatabaseDescriptor.isAutoBootstrap()
-                && DatabaseDescriptor.getSeeds().contains(FBUtilities.getBroadcastAddress())
-                && !SystemTable.bootstrapComplete())
-            logger_.info("This node will not auto bootstrap because it is configured to be a seed node.");
+        boolean schemaPresent = false;
+        if (DatabaseDescriptor.isAutoBootstrap() && !SystemTable.bootstrapComplete() && delay > 0)
+        {
+            // wait a couple gossip rounds so our schema check has something to go by
+            FBUtilities.sleep(2 * Gossiper.intervalInMillis);
+        }
+        for (Entry<InetAddress, EndpointState> entry : Gossiper.instance.getEndpointStates())
+        {
+            if (entry.getKey().equals(FBUtilities.getBroadcastAddress()))
+            {
+                // skip ourselves to avoid confusing the tests, which always load a schema first thing
+                continue;
+            }
 
-        InetAddress current = null;
-        // we can bootstrap at startup, or if we detect a previous attempt that failed, which is to say:
-        // DD.isAutoBootstrap must be true AND:
-        //  bootstrap is not recorded as complete, OR
-        //  DD.getSeeds does not contain our BCA, OR
-        //  we do not have non-system tables already
-        // OR:
-        //  we detect that we were previously trying to bootstrap (ST.bootstrapInProgress is true)
+            if (!entry.getValue().getApplicationState(ApplicationState.SCHEMA).value.equals(Schema.emptyVersion.toString()))
+            {
+                schemaPresent = true;
+                break;
+            }
+        }
+
+        // We can bootstrap at startup, or if we detect a previous attempt that failed.  Either way, if the user
+        // manually sets auto_bootstrap to false, we'll skip streaming data from other nodes and jump directly
+        // into the ring.
+        //
+        // The one exception is if after the above sleep we still have no schema information, we'll assume
+        // we're part of a fresh cluster start, and also skip bootstrap.  This is less confusing for new users,
+        // as well as avoiding the nonsensical state of trying to stream from cluster with no active peers.
         Token<?> token;
+        InetAddress current = null;
+        logger_.debug("Bootstrap variables: %s %s %s %s",
+                      new Object[] {DatabaseDescriptor.isAutoBootstrap(), SystemTable.bootstrapInProgress(), SystemTable.bootstrapComplete(), schemaPresent});
         if (DatabaseDescriptor.isAutoBootstrap()
-                && !(SystemTable.bootstrapComplete() || DatabaseDescriptor.getSeeds().contains(FBUtilities.getBroadcastAddress()) || !Schema.instance.getNonSystemTables().isEmpty())
-                || SystemTable.bootstrapInProgress())
+            && (SystemTable.bootstrapInProgress() || (!SystemTable.bootstrapComplete() && schemaPresent)))
         {
             if (SystemTable.bootstrapInProgress())
                 logger_.warn("Detected previous bootstrap failure; retrying");
             else
                 SystemTable.setBootstrapState(SystemTable.BootstrapState.IN_PROGRESS);
-            setMode(Mode.JOINING, "waiting for ring and schema information", true);
-            // first sleep the delay to make sure we see the schema
+            setMode(Mode.JOINING, "waiting for ring information", true);
+            // first sleep the delay to make sure we see all our peers
             try
             {
                 Thread.sleep(delay);
@@ -589,7 +606,8 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe
             {
                 throw new AssertionError(e);
             }
-            // now if our schema hasn't matched, keep sleeping until it does
+            // if our schema hasn't matched yet, keep sleeping until it does
+            // (post CASSANDRA-1391 we don't expect this to be necessary very often, but it doesn't hurt to be careful)
             while (!MigrationManager.isReadyForBootstrap())
             {
                 setMode(Mode.JOINING, "waiting for schema information to complete", true);