You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by be...@apache.org on 2018/07/16 16:57:05 UTC

[4/6] cassandra git commit: Merge branch 'cassandra-3.0' into HEAD

Merge branch 'cassandra-3.0' into HEAD


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

Branch: refs/heads/trunk
Commit: 31d5d870f9f5b56391db46ba6cdf9e0882d8a5c0
Parents: 6bcc60a d52c7b8
Author: Benedict Elliott Smith <be...@apple.com>
Authored: Mon Jul 16 17:46:37 2018 +0100
Committer: Benedict Elliott Smith <be...@apple.com>
Committed: Mon Jul 16 17:46:37 2018 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../org/apache/cassandra/db/LegacyLayout.java   | 15 ++-
 .../cassandra/db/marshal/CompositeType.java     | 13 ++-
 .../db/partitions/PartitionUpdate.java          | 40 +++++---
 .../apache/cassandra/db/LegacyLayoutTest.java   | 99 +++++++++++++++++++-
 5 files changed, 145 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/31d5d870/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 5beccfb,47e5cd0..5e39b5e
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,24 -1,7 +1,25 @@@
 -3.0.17
 +3.11.3
 + * Validate supported column type with SASI analyzer (CASSANDRA-13669)
 + * Remove BTree.Builder Recycler to reduce memory usage (CASSANDRA-13929)
 + * Reduce nodetool GC thread count (CASSANDRA-14475)
 + * Fix New SASI view creation during Index Redistribution (CASSANDRA-14055)
 + * Remove string formatting lines from BufferPool hot path (CASSANDRA-14416)
 + * Update metrics to 3.1.5 (CASSANDRA-12924)
 + * Detect OpenJDK jvm type and architecture (CASSANDRA-12793)
 + * Don't use guava collections in the non-system keyspace jmx attributes (CASSANDRA-12271)
 + * Allow existing nodes to use all peers in shadow round (CASSANDRA-13851)
 + * Fix cqlsh to read connection.ssl cqlshrc option again (CASSANDRA-14299)
 + * Downgrade log level to trace for CommitLogSegmentManager (CASSANDRA-14370)
 + * CQL fromJson(null) throws NullPointerException (CASSANDRA-13891)
 + * Serialize empty buffer as empty string for json output format (CASSANDRA-14245)
 + * Allow logging implementation to be interchanged for embedded testing (CASSANDRA-13396)
 + * SASI tokenizer for simple delimiter based entries (CASSANDRA-14247)
 + * Fix Loss of digits when doing CAST from varint/bigint to decimal (CASSANDRA-14170)
 + * RateBasedBackPressure unnecessarily invokes a lock on the Guava RateLimiter (CASSANDRA-14163)
 + * Fix wildcard GROUP BY queries (CASSANDRA-14209)
 +Merged from 3.0:
+  * Fix corrupted static collection deletions in 3.0 -> 2.{1,2} messages (CASSANDRA-14568)
   * Fix potential IndexOutOfBoundsException with counters (CASSANDRA-14167)
 - * Restore resumable hints delivery, backport CASSANDRA-11960 (CASSANDRA-14419)
   * Always close RT markers returned by ReadCommand#executeLocally() (CASSANDRA-14515)
   * Reverse order queries with range tombstones can cause data loss (CASSANDRA-14513)
   * Fix regression of lagging commitlog flush log message (CASSANDRA-14451)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/31d5d870/src/java/org/apache/cassandra/db/LegacyLayout.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/LegacyLayout.java
index 1cfe622,e0f66e3..eed4113
--- a/src/java/org/apache/cassandra/db/LegacyLayout.java
+++ b/src/java/org/apache/cassandra/db/LegacyLayout.java
@@@ -229,14 -234,14 +234,14 @@@ public abstract class LegacyLayou
              }
          }
  
 -        Slice.Bound.Kind boundKind = Slice.Bound.boundKind(isStart, isInclusive);
 -        Slice.Bound sb = Slice.Bound.create(boundKind, components.toArray(new ByteBuffer[components.size()]));
 -        return new LegacyBound(sb, isStatic, collectionName);
 +        ClusteringPrefix.Kind boundKind = ClusteringBound.boundKind(isStart, isInclusive);
 +        ClusteringBound cb = ClusteringBound.create(boundKind, components.toArray(new ByteBuffer[components.size()]));
-         return new LegacyBound(cb, metadata.isCompound() && CompositeType.isStaticName(bound), collectionName);
++        return new LegacyBound(cb, isStatic, collectionName);
      }
  
 -    public static ByteBuffer encodeBound(CFMetaData metadata, Slice.Bound bound, boolean isStart)
 +    public static ByteBuffer encodeBound(CFMetaData metadata, ClusteringBound bound, boolean isStart)
      {
 -        if (bound == Slice.Bound.BOTTOM || bound == Slice.Bound.TOP || metadata.comparator.size() == 0)
 +        if (bound == ClusteringBound.BOTTOM || bound == ClusteringBound.TOP || metadata.comparator.size() == 0)
              return ByteBufferUtil.EMPTY_BYTE_BUFFER;
  
          ClusteringPrefix clustering = bound.clustering();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/31d5d870/src/java/org/apache/cassandra/db/marshal/CompositeType.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/31d5d870/src/java/org/apache/cassandra/db/partitions/PartitionUpdate.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/31d5d870/test/unit/org/apache/cassandra/db/LegacyLayoutTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/db/LegacyLayoutTest.java
index be695f2,44d8a70..f428073
--- a/test/unit/org/apache/cassandra/db/LegacyLayoutTest.java
+++ b/test/unit/org/apache/cassandra/db/LegacyLayoutTest.java
@@@ -23,7 -24,21 +24,22 @@@ import java.nio.file.Files
  import java.nio.file.Path;
  import java.nio.file.Paths;
  
 +import org.junit.AfterClass;
+ import org.apache.cassandra.db.filter.ColumnFilter;
+ import org.apache.cassandra.db.rows.BufferCell;
+ import org.apache.cassandra.db.rows.Cell;
+ import org.apache.cassandra.db.rows.RowIterator;
+ import org.apache.cassandra.db.rows.SerializationHelper;
+ import org.apache.cassandra.db.rows.UnfilteredRowIterator;
+ import org.apache.cassandra.db.rows.UnfilteredRowIteratorSerializer;
+ import org.apache.cassandra.db.transform.FilteredRows;
+ import org.apache.cassandra.exceptions.ConfigurationException;
+ import org.apache.cassandra.io.util.DataInputBuffer;
+ import org.apache.cassandra.io.util.DataOutputBuffer;
+ import org.apache.cassandra.net.MessagingService;
+ import org.apache.cassandra.serializers.Int32Serializer;
+ import org.apache.cassandra.serializers.UTF8Serializer;
+ import org.apache.cassandra.utils.FBUtilities;
  import org.junit.BeforeClass;
  import org.junit.Test;
  
@@@ -48,14 -62,12 +64,14 @@@ import static org.junit.Assert.*
  
  public class LegacyLayoutTest
  {
 -    static final String KEYSPACE = "Keyspace1";
 +    static Util.PartitionerSwitcher sw;
 +    static String KEYSPACE = "Keyspace1";
  
      @BeforeClass
-     public static void setupPartitioner()
+     public static void defineSchema() throws ConfigurationException
      {
 -        DatabaseDescriptor.setPartitionerUnsafe(Murmur3Partitioner.instance);
 +        DatabaseDescriptor.daemonInitialization();
 +        sw = Util.switchPartitioner(Murmur3Partitioner.instance);
          SchemaLoader.loadSchema();
          SchemaLoader.createKeyspace(KEYSPACE, KeyspaceParams.simple(1));
      }
@@@ -170,4 -172,85 +185,84 @@@
          }
  
      }
+ 
+ 
+     private static UnfilteredRowIterator roundTripVia21(UnfilteredRowIterator partition) throws IOException
+     {
+         try (DataOutputBuffer out = new DataOutputBuffer())
+         {
+             LegacyLayout.serializeAsLegacyPartition(null, partition, out, MessagingService.VERSION_21);
+             try (DataInputBuffer in = new DataInputBuffer(out.buffer(), false))
+             {
+                 return LegacyLayout.deserializeLegacyPartition(in, MessagingService.VERSION_21, SerializationHelper.Flag.LOCAL, partition.partitionKey().getKey());
+             }
+         }
+     }
+ 
+ 
+     @Test
+     public void testStaticRangeTombstoneRoundTripUnexpectedDeletion() throws Throwable
+     {
+         // this variant of the bug deletes a row with the same clustering key value as the name of the static collection
+         QueryProcessor.executeInternal(String.format("CREATE TABLE \"%s\".legacy_static_rt_rt_1 (pk int, ck1 text, ck2 text, v int, s set<text> static, primary key (pk, ck1, ck2))", KEYSPACE));
+         Keyspace keyspace = Keyspace.open(KEYSPACE);
+         CFMetaData table = keyspace.getColumnFamilyStore("legacy_static_rt_rt_1").metadata;
+         ColumnDefinition v = table.getColumnDefinition(new ColumnIdentifier("v", false));
+         ColumnDefinition bug = table.getColumnDefinition(new ColumnIdentifier("s", false));
+ 
+         Row.Builder builder;
+         builder = BTreeRow.unsortedBuilder(0);
+         builder.newRow(Clustering.STATIC_CLUSTERING);
+         builder.addComplexDeletion(bug, new DeletionTime(1L, 1));
+         Row staticRow = builder.build();
+ 
+         builder = BTreeRow.unsortedBuilder(0);
 -        builder.newRow(new Clustering(UTF8Serializer.instance.serialize("s"), UTF8Serializer.instance.serialize("anything")));
++        builder.newRow(new BufferClustering(UTF8Serializer.instance.serialize("s"), UTF8Serializer.instance.serialize("anything")));
+         builder.addCell(new BufferCell(v, 1L, Cell.NO_TTL, Cell.NO_DELETION_TIME, Int32Serializer.instance.serialize(1), null));
+         Row row = builder.build();
+ 
+         DecoratedKey pk = table.decorateKey(ByteBufferUtil.bytes(1));
+         PartitionUpdate upd = PartitionUpdate.singleRowUpdate(table, pk, row, staticRow);
+ 
+         try (RowIterator before = FilteredRows.filter(upd.unfilteredIterator(), FBUtilities.nowInSeconds());
+              RowIterator after = FilteredRows.filter(roundTripVia21(upd.unfilteredIterator()), FBUtilities.nowInSeconds()))
+         {
+             while (before.hasNext() || after.hasNext())
+                 assertEquals(before.hasNext() ? before.next() : null, after.hasNext() ? after.next() : null);
+         }
+     }
+ 
+     @Test
+     public void testStaticRangeTombstoneRoundTripCorruptRead() throws Throwable
+     {
+         // this variant of the bug corrupts the byte stream of the partition, so that a sequential read starting before
+         // this partition will fail with a CorruptSSTableException, and possible yield junk results
+         QueryProcessor.executeInternal(String.format("CREATE TABLE \"%s\".legacy_static_rt_rt_2 (pk int, ck int, nameWithLengthGreaterThan4 set<int> static, primary key (pk, ck))", KEYSPACE));
+         Keyspace keyspace = Keyspace.open(KEYSPACE);
+         CFMetaData table = keyspace.getColumnFamilyStore("legacy_static_rt_rt_2").metadata;
+ 
+         ColumnDefinition bug = table.getColumnDefinition(new ColumnIdentifier("nameWithLengthGreaterThan4", false));
+ 
+         Row.Builder builder = BTreeRow.unsortedBuilder(0);
+         builder.newRow(Clustering.STATIC_CLUSTERING);
+         builder.addComplexDeletion(bug, new DeletionTime(1L, 1));
+         Row row = builder.build();
+ 
+         DecoratedKey pk = table.decorateKey(ByteBufferUtil.bytes(1));
+         PartitionUpdate upd = PartitionUpdate.singleRowUpdate(table, pk, row);
+ 
+         UnfilteredRowIterator afterRoundTripVia32 = roundTripVia21(upd.unfilteredIterator());
+         try (DataOutputBuffer out = new DataOutputBuffer())
+         {
+             // we only encounter a corruption/serialization error after writing this to a 3.0 format and reading it back
+             UnfilteredRowIteratorSerializer.serializer.serialize(afterRoundTripVia32, ColumnFilter.all(table), out, MessagingService.current_version);
+             try (DataInputBuffer in = new DataInputBuffer(out.buffer(), false);
+                  UnfilteredRowIterator afterSerialization = UnfilteredRowIteratorSerializer.serializer.deserialize(in, MessagingService.current_version, table, ColumnFilter.all(table), SerializationHelper.Flag.LOCAL))
+             {
+                 while (afterSerialization.hasNext())
+                     afterSerialization.next();
+             }
+         }
+     }
+ 
  }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org