cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alek...@apache.org
Subject [6/6] cassandra git commit: Merge branch 'cassandra-3.0' into trunk
Date Wed, 31 Aug 2016 19:29:14 GMT
Merge branch 'cassandra-3.0' into trunk


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

Branch: refs/heads/trunk
Commit: 0cd48f76d8744d9bdabc65b6218bb82ff9014cb3
Parents: 8a3f0e1 e4a53f4
Author: Aleksey Yeschenko <aleksey@apache.org>
Authored: Wed Aug 31 20:26:39 2016 +0100
Committer: Aleksey Yeschenko <aleksey@apache.org>
Committed: Wed Aug 31 20:27:53 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 src/java/org/apache/cassandra/gms/Gossiper.java |   5 +-
 .../apache/cassandra/gms/VersionedValue.java    |   6 +
 .../apache/cassandra/locator/TokenMetadata.java |  52 +++++-
 .../cassandra/service/LoadBroadcaster.java      |   2 +-
 .../cassandra/service/StorageService.java       | 182 ++++++++++++++-----
 6 files changed, 197 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/0cd48f76/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index a0f6055,30931d3..0edfc76
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -64,50 -9,12 +64,51 @@@ Merged from 3.0
   * Disk failure policy should not be invoked on out of space (CASSANDRA-12385)
   * Calculate last compacted key on startup (CASSANDRA-6216)
   * Add schema to snapshot manifest, add USING TIMESTAMP clause to ALTER TABLE statements
(CASSANDRA-7190)
 +Merged from 2.2:
++ * Forward writes to replacement node when replace_address != broadcast_address (CASSANDRA-8523)
 + * Fail repair on non-existing table (CASSANDRA-12279)
 + * Enable repair -pr and -local together (fix regression of CASSANDRA-7450) (CASSANDRA-12522)
 +
 +
 +3.8, 3.9
 + * Fix value skipping with counter columns (CASSANDRA-11726)
 + * Fix nodetool tablestats miss SSTable count (CASSANDRA-12205)
 + * Fixed flacky SSTablesIteratedTest (CASSANDRA-12282)
 + * Fixed flacky SSTableRewriterTest: check file counts before calling validateCFS (CASSANDRA-12348)
 + * cqlsh: Fix handling of $$-escaped strings (CASSANDRA-12189)
 + * Fix SSL JMX requiring truststore containing server cert (CASSANDRA-12109)
 + * RTE from new CDC column breaks in flight queries (CASSANDRA-12236)
 + * Fix hdr logging for single operation workloads (CASSANDRA-12145)
 + * Fix SASI PREFIX search in CONTAINS mode with partial terms (CASSANDRA-12073)
 + * Increase size of flushExecutor thread pool (CASSANDRA-12071)
 + * Partial revert of CASSANDRA-11971, cannot recycle buffer in SP.sendMessagesToNonlocalDC
(CASSANDRA-11950)
 + * Upgrade netty to 4.0.39 (CASSANDRA-12032, CASSANDRA-12034)
 + * Improve details in compaction log message (CASSANDRA-12080)
 + * Allow unset values in CQLSSTableWriter (CASSANDRA-11911)
 + * Chunk cache to request compressor-compatible buffers if pool space is exhausted (CASSANDRA-11993)
 + * Remove DatabaseDescriptor dependencies from SequentialWriter (CASSANDRA-11579)
 + * Move skip_stop_words filter before stemming (CASSANDRA-12078)
 + * Support seek() in EncryptedFileSegmentInputStream (CASSANDRA-11957)
 + * SSTable tools mishandling LocalPartitioner (CASSANDRA-12002)
 + * When SEPWorker assigned work, set thread name to match pool (CASSANDRA-11966)
 + * Add cross-DC latency metrics (CASSANDRA-11596)
 + * Allow terms in selection clause (CASSANDRA-10783)
 + * Add bind variables to trace (CASSANDRA-11719)
 + * Switch counter shards' clock to timestamps (CASSANDRA-9811)
 + * Introduce HdrHistogram and response/service/wait separation to stress tool (CASSANDRA-11853)
 + * entry-weighers in QueryProcessor should respect partitionKeyBindIndexes field (CASSANDRA-11718)
 + * Support older ant versions (CASSANDRA-11807)
 + * Estimate compressed on disk size when deciding if sstable size limit reached (CASSANDRA-11623)
 + * cassandra-stress profiles should support case sensitive schemas (CASSANDRA-11546)
 + * Remove DatabaseDescriptor dependency from FileUtils (CASSANDRA-11578)
 + * Faster streaming (CASSANDRA-9766)
 + * Add prepared query parameter to trace for "Execute CQL3 prepared query" session (CASSANDRA-11425)
 + * Add repaired percentage metric (CASSANDRA-11503)
 + * Add Change-Data-Capture (CASSANDRA-8844)
 +Merged from 3.0:
   * Fix clean interval not sent to commit log for empty memtable flush (CASSANDRA-12436)
   * Fix potential resource leak in RMIServerSocketFactoryImpl (CASSANDRA-12331)
 - * Backport CASSANDRA-12002 (CASSANDRA-12177)
   * Make sure compaction stats are updated when compaction is interrupted (CASSANDRA-12100)
 - * Fix potential bad messaging service message for paged range reads
 -   within mixed-version 3.x clusters (CASSANDRA-12249)
   * Change commitlog and sstables to track dirty and clean intervals (CASSANDRA-11828)
   * NullPointerException during compaction on table with static columns (CASSANDRA-12336)
   * Fixed ConcurrentModificationException when reading metrics in GraphiteReporter (CASSANDRA-11823)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0cd48f76/src/java/org/apache/cassandra/gms/Gossiper.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/gms/Gossiper.java
index 13cc8ab,f575a34..18de598
--- a/src/java/org/apache/cassandra/gms/Gossiper.java
+++ b/src/java/org/apache/cassandra/gms/Gossiper.java
@@@ -73,10 -73,10 +73,11 @@@ public class Gossiper implements IFailu
      static final List<String> DEAD_STATES = Arrays.asList(VersionedValue.REMOVING_TOKEN,
VersionedValue.REMOVED_TOKEN,
                                                            VersionedValue.STATUS_LEFT, VersionedValue.HIBERNATE);
      static ArrayList<String> SILENT_SHUTDOWN_STATES = new ArrayList<>();
 -    static {
 +    static
 +    {
          SILENT_SHUTDOWN_STATES.addAll(DEAD_STATES);
          SILENT_SHUTDOWN_STATES.add(VersionedValue.STATUS_BOOTSTRAPPING);
+         SILENT_SHUTDOWN_STATES.add(VersionedValue.STATUS_BOOTSTRAPPING_REPLACE);
      }
  
      private volatile ScheduledFuture<?> scheduledGossipTask;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0cd48f76/src/java/org/apache/cassandra/locator/TokenMetadata.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0cd48f76/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/service/StorageService.java
index 93205fb,c06bed2..2799db2
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@@ -445,49 -436,46 +445,67 @@@ public class StorageService extends Not
          daemon.deactivate();
      }
  
-     private synchronized UUID prepareReplacementInfo(InetAddress replaceAddress) throws
ConfigurationException
 -    public synchronized Collection<Token> prepareReplacementInfo() throws ConfigurationException
++    private synchronized UUID prepareForReplacement() throws ConfigurationException
      {
--        logger.info("Gathering node replacement information for {}", DatabaseDescriptor.getReplaceAddress());
 -        if (!MessagingService.instance().isListening())
 -            MessagingService.instance().listen();
++        if (SystemKeyspace.bootstrapComplete())
++            throw new RuntimeException("Cannot replace address with a node that is already
bootstrapped");
+ 
 -        // make magic happen
++        if (!(Boolean.parseBoolean(System.getProperty("cassandra.join_ring", "true"))))
++            throw new ConfigurationException("Cannot set both join_ring=false and attempt
to replace a node");
++
++        if (!DatabaseDescriptor.isAutoBootstrap() && !Boolean.getBoolean("cassandra.allow_unsafe_replace"))
++            throw new RuntimeException("Replacing a node without bootstrapping risks invalidating
consistency " +
++                                       "guarantees as the expected data may not be present
until repair is run. " +
++                                       "To perform this operation, please restart with "
+
++                                       "-Dcassandra.allow_unsafe_replace=true");
++
++        InetAddress replaceAddress = DatabaseDescriptor.getReplaceAddress();
++        logger.info("Gathering node replacement information for {}", replaceAddress);
          Gossiper.instance.doShadowRound();
 +        // as we've completed the shadow round of gossip, we should be able to find the
node we're replacing
 +        if (Gossiper.instance.getEndpointStateForEndpoint(replaceAddress) == null)
 +            throw new RuntimeException(String.format("Cannot replace_address %s because
it doesn't exist in gossip", replaceAddress));
  
 -        // now that we've gossiped at least once, we should be able to find the node we're
replacing
 -        if (Gossiper.instance.getEndpointStateForEndpoint(DatabaseDescriptor.getReplaceAddress())==
null)
 -            throw new RuntimeException("Cannot replace_address " + DatabaseDescriptor.getReplaceAddress()
+ " because it doesn't exist in gossip");
 -        replacingId = Gossiper.instance.getHostId(DatabaseDescriptor.getReplaceAddress());
          try
          {
 -            VersionedValue tokensVersionedValue = Gossiper.instance.getEndpointStateForEndpoint(DatabaseDescriptor.getReplaceAddress()).getApplicationState(ApplicationState.TOKENS);
 +            VersionedValue tokensVersionedValue = Gossiper.instance.getEndpointStateForEndpoint(replaceAddress).getApplicationState(ApplicationState.TOKENS);
              if (tokensVersionedValue == null)
 -                throw new RuntimeException("Could not find tokens for " + DatabaseDescriptor.getReplaceAddress()
+ " to replace");
 -            Collection<Token> tokens = TokenSerializer.deserialize(tokenMetadata.partitioner,
new DataInputStream(new ByteArrayInputStream(tokensVersionedValue.toBytes())));
 +                throw new RuntimeException(String.format("Could not find tokens for %s to
replace", replaceAddress));
  
 -            if (isReplacingSameAddress())
 -            {
 -                SystemKeyspace.setLocalHostId(replacingId); // use the replacee's host Id
as our own so we receive hints, etc
 -            }
 -            Gossiper.instance.resetEndpointStateMap(); // clean up since we have what we
need
 -            return tokens;
 +            bootstrapTokens = TokenSerializer.deserialize(tokenMetadata.partitioner, new
DataInputStream(new ByteArrayInputStream(tokensVersionedValue.toBytes())));
          }
          catch (IOException e)
          {
              throw new RuntimeException(e);
          }
 +
-         // we'll use the replacee's host Id as our own so we receive hints, etc
-         UUID localHostId = Gossiper.instance.getHostId(replaceAddress);
-         SystemKeyspace.setLocalHostId(localHostId);
++        UUID localHostId = SystemKeyspace.getLocalHostId();
++
++        if (isReplacingSameAddress())
++        {
++            localHostId = Gossiper.instance.getHostId(replaceAddress);
++            SystemKeyspace.setLocalHostId(localHostId); // use the replacee's host Id as
our own so we receive hints, etc
++        }
++
 +        Gossiper.instance.resetEndpointStateMap(); // clean up since we have what we need
 +        return localHostId;
      }
  
 -    public synchronized void checkForEndpointCollision() throws ConfigurationException
 +    private synchronized void checkForEndpointCollision(UUID localHostId) throws ConfigurationException
      {
 +        if (Boolean.getBoolean("cassandra.allow_unsafe_join"))
 +        {
 +            logger.warn("Skipping endpoint collision check as cassandra.allow_unsafe_join=true");
 +            return;
 +        }
 +
          logger.debug("Starting shadow gossip round to check for endpoint collision");
 -        if (!MessagingService.instance().isListening())
 -            MessagingService.instance().listen();
          Gossiper.instance.doShadowRound();
 -        if (!Gossiper.instance.isSafeForBootstrap(FBUtilities.getBroadcastAddress()))
 +        // If bootstrapping, check whether any previously known status for the endpoint
makes it unsafe to do so.
 +        // If not bootstrapping, compare the host id for this endpoint learned from gossip
(if any) with the local
 +        // one, which was either read from system.local or generated at startup. If a learned
id is present &
 +        // doesn't match the local, then the node needs replacing
 +        if (!Gossiper.instance.isSafeForStartup(FBUtilities.getBroadcastAddress(), localHostId,
shouldBootstrap()))
          {
              throw new RuntimeException(String.format("A node with address %s already exists,
cancelling join. " +
                                                       "Use cassandra.replace_address if you
want to replace this node.",
@@@ -748,45 -717,30 +766,39 @@@
                  else
                      throw new ConfigurationException("This node was decommissioned and will
not rejoin the ring unless cassandra.override_decommission=true has been set, or all existing
data is removed and the node is bootstrapped again");
              }
 -            if (replacing && !(Boolean.parseBoolean(System.getProperty("cassandra.join_ring",
"true"))))
 -                throw new ConfigurationException("Cannot set both join_ring=false and attempt
to replace a node");
 +
              if (DatabaseDescriptor.getReplaceTokens().size() > 0 || DatabaseDescriptor.getReplaceNode()
!= null)
                  throw new RuntimeException("Replace method removed; use cassandra.replace_address
instead");
 +
 +            if (!MessagingService.instance().isListening())
 +                MessagingService.instance().listen();
 +
 +            UUID localHostId = SystemKeyspace.getLocalHostId();
 +
              if (replacing)
              {
--                if (SystemKeyspace.bootstrapComplete())
--                    throw new RuntimeException("Cannot replace address with a node that
is already bootstrapped");
- 
-                 if (!(Boolean.parseBoolean(System.getProperty("cassandra.join_ring", "true"))))
-                     throw new ConfigurationException("Cannot set both join_ring=false and
attempt to replace a node");
- 
-                 if (!DatabaseDescriptor.isAutoBootstrap() && !Boolean.getBoolean("cassandra.allow_unsafe_replace"))
-                     throw new RuntimeException("Replacing a node without bootstrapping risks
invalidating consistency " +
-                                                "guarantees as the expected data may not
be present until repair is run. " +
-                                                "To perform this operation, please restart
with " +
-                                                "-Dcassandra.allow_unsafe_replace=true");
- 
-                 InetAddress replaceAddress = DatabaseDescriptor.getReplaceAddress();
-                 localHostId = prepareReplacementInfo(replaceAddress);
++                localHostId = prepareForReplacement();
 +                appStates.put(ApplicationState.TOKENS, valueFactory.tokens(bootstrapTokens));
 +
-                 // if want to bootstrap the ranges of the node we're replacing,
-                 // go into hibernate mode while that happens. Otherwise, persist
-                 // the tokens we're taking over locally so that they don't get
-                 // clobbered with auto generated ones in joinTokenRing
-                 if (DatabaseDescriptor.isAutoBootstrap())
-                     appStates.put(ApplicationState.STATUS, valueFactory.hibernate(true));
-                 else
+                 if (!DatabaseDescriptor.isAutoBootstrap())
 -                    throw new RuntimeException("Trying to replace_address with auto_bootstrap
disabled will not work, check your configuration");
 -                bootstrapTokens = prepareReplacementInfo();
 -                if (isReplacingSameAddress())
+                 {
++                    // Will not do replace procedure, persist the tokens we're taking over
locally
++                    // so that they don't get clobbered with auto generated ones in joinTokenRing
 +                    SystemKeyspace.updateTokens(bootstrapTokens);
++                }
++                else if (isReplacingSameAddress())
++                {
++                    //only go into hibernate state if replacing the same address (CASSANDRA-8523)
+                     logger.warn("Writes will not be forwarded to this node during replacement
because it has the same address as " +
+                                 "the node to be replaced ({}). If the previous node has
been down for longer than max_hint_window_in_ms, " +
+                                 "repair must be run after the replacement process in order
to make this node consistent.",
+                                 DatabaseDescriptor.getReplaceAddress());
 -                    appStates.put(ApplicationState.TOKENS, valueFactory.tokens(bootstrapTokens));
+                     appStates.put(ApplicationState.STATUS, valueFactory.hibernate(true));
+                 }
              }
 -            else if (shouldBootstrap())
 +            else
              {
 -                checkForEndpointCollision();
 +                checkForEndpointCollision(localHostId);
              }
  
              // have to start the gossip service before we can see any info on other nodes.
 this is necessary
@@@ -1036,13 -990,9 +1050,9 @@@
          }
          else if (isSurveyMode)
          {
-             setTokens(SystemKeyspace.getSavedTokens());
-             SystemKeyspace.setBootstrapState(SystemKeyspace.BootstrapState.COMPLETED);
--            isSurveyMode = false;
              logger.info("Leaving write survey mode and joining ring at operator request");
-             assert tokenMetadata.sortedTokens().size() > 0;
- 
-             doAuthSetup();
+             finishJoiningRing();
++            isSurveyMode = false;
          }
      }
  


Mime
View raw message