This is an automated email from the ASF dual-hosted git repository. jwest pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit c6ef4762eeee78ec783b77faa367e82d9b1ffabc Merge: d4eba9f cf27558 Author: Jordan West <jw...@apache.org> AuthorDate: Mon Sep 28 08:15:26 2020 -0700 Merge branch 'cassandra-3.11' into trunk CHANGES.txt | 1 + .../apache/cassandra/db/filter/ColumnFilter.java | 9 +++ src/java/org/apache/cassandra/gms/Gossiper.java | 4 +- .../distributed/upgrade/MixedModeReadTest.java | 92 ++++++++++++++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) diff --cc CHANGES.txt index 0215a71,3b47c33..190eebc --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,23 -1,6 +1,24 @@@ -3.11.9 - * Don't attempt value skipping with mixed version cluster (CASSANDRA-15833) +4.0-beta3 + * Abort repairs when getting a truncation request (CASSANDRA-15854) + * Remove bad assert when getting active compactions for an sstable (CASSANDRA-15457) * Avoid failing compactions with very large partitions (CASSANDRA-15164) + * Prevent NPE in StreamMessage in type lookup (CASSANDRA-16131) + * Avoid invalid state transition exception during incremental repair (CASSANDRA-16067) + * Allow zero padding in timestamp serialization (CASSANDRA-16105) + * Add byte array backed cells (CASSANDRA-15393) + * Correctly handle pending ranges with adjacent range movements (CASSANDRA-14801) + * Avoid adding locahost when streaming trivial ranges (CASSANDRA-16099) + * Add nodetool getfullquerylog (CASSANDRA-15988) + * Fix yaml format and alignment in tpstats (CASSANDRA-11402) + * Avoid trying to keep track of RTs for endpoints we won't write to during read repair (CASSANDRA-16084) + * When compaction gets interrupted, the exception should include the compactionId (CASSANDRA-15954) + * Make Table/Keyspace Metric Names Consistent With Each Other (CASSANDRA-15909) + * Mutating sstable component may race with entire-sstable-streaming(ZCS) causing checksum validation failure (CASSANDRA-15861) + * NPE thrown while updating speculative execution time if keyspace is removed during task execution (CASSANDRA-15949) + * Show the progress of data streaming and index build (CASSANDRA-15406) +Merged from 3.11: ++ * Don't attempt value skipping with mixed version cluster (CASSANDRA-15833) + * Use IF NOT EXISTS for index and UDT create statements in snapshot schema files (CASSANDRA-13935) * Make sure LCS handles duplicate sstable added/removed notifications correctly (CASSANDRA-14103) Merged from 3.0: * Add flag to ignore unreplicated keyspaces during repair (CASSANDRA-15160) diff --cc src/java/org/apache/cassandra/db/filter/ColumnFilter.java index 30c3ed7,57ff729..c9d0a70 --- a/src/java/org/apache/cassandra/db/filter/ColumnFilter.java +++ b/src/java/org/apache/cassandra/db/filter/ColumnFilter.java @@@ -26,10 -23,12 +26,11 @@@ import com.google.common.collect.Iterat import com.google.common.collect.SortedSetMultimap; import com.google.common.collect.TreeMultimap; -import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.cql3.ColumnIdentifier; import org.apache.cassandra.db.*; +import org.apache.cassandra.db.rows.Cell; import org.apache.cassandra.db.rows.CellPath; -import org.apache.cassandra.config.ColumnDefinition; + import org.apache.cassandra.gms.Gossiper; import org.apache.cassandra.io.util.DataInputPlus; import org.apache.cassandra.io.util.DataOutputPlus; import org.apache.cassandra.net.MessagingService; @@@ -443,13 -349,14 +444,17 @@@ public class ColumnFilte { s = TreeMultimap.create(Comparator.<ColumnIdentifier>naturalOrder(), Comparator.<ColumnSubselection>naturalOrder()); for (ColumnSubselection subSelection : subSelections) - s.put(subSelection.column().name, subSelection); + { + if (fullySelectedComplexColumns == null || !fullySelectedComplexColumns.contains(subSelection.column())) + s.put(subSelection.column().name, subSelection); + } } + // see CASSANDRA-15833 - if (isFetchAll && Gossiper.instance.isAnyNodeOn30()) ++ if (isFetchAll && Gossiper.instance.haveMajorVersion3Nodes()) + queried = null; + - return new ColumnFilter(isFetchAll, isFetchAll ? metadata.partitionColumns() : null, queried, s); + return new ColumnFilter(isFetchAll, metadata, queried, s); } } @@@ -616,15 -500,10 +621,19 @@@ } } + // See CASSANDRA-15833 + if (version <= MessagingService.VERSION_3014 && isFetchAll) + queried = null; + + // Same concern than in serialize/serializedSize: we should be wary of the change in meaning for isFetchAll. + // If we get a filter with isFetchAll from 3.0/3.x, it actually expects all static columns to be fetched, + // make sure we do that (note that if queried == null, that's already what we do). + // Note that here again this will make us do a bit more work that necessary, namely we'll _query_ all + // statics even though we only care about _fetching_ them all, but that's a minor inefficiency, so fine + // during upgrade. + if (version <= MessagingService.VERSION_30 && isFetchAll && queried != null) + queried = new RegularAndStaticColumns(metadata.staticColumns(), queried.regulars); + return new ColumnFilter(isFetchAll, fetched, queried, subSelections); } diff --cc src/java/org/apache/cassandra/gms/Gossiper.java index 9e1082a,b201763..0029521 --- a/src/java/org/apache/cassandra/gms/Gossiper.java +++ b/src/java/org/apache/cassandra/gms/Gossiper.java @@@ -155,38 -156,7 +155,38 @@@ public class Gossiper implements IFailu private volatile long lastProcessedMessageAt = System.currentTimeMillis(); - private static FastThreadLocal<Boolean> isGossipStage = new FastThreadLocal<>(); + //This property and anything that checks it should be removed in 5.0 + private boolean haveMajorVersion3Nodes = true; + + final com.google.common.base.Supplier<Boolean> haveMajorVersion3NodesSupplier = () -> + { + //Once there are no prior version nodes we don't need to keep rechecking + if (!haveMajorVersion3Nodes) + return false; + + Iterable<InetAddressAndPort> allHosts = Iterables.concat(Gossiper.instance.getLiveMembers(), Gossiper.instance.getUnreachableMembers()); + CassandraVersion referenceVersion = null; + + for (InetAddressAndPort host : allHosts) + { + CassandraVersion version = getReleaseVersion(host); + - //Raced with changes to gossip state ++ //Raced with changes to gossip state, wait until next iteration + if (version == null) - continue; ++ return true; + + if (referenceVersion == null) + referenceVersion = version; + + if (version.major < 4) + return true; + } + + haveMajorVersion3Nodes = false; + return false; + }; + + private final Supplier<Boolean> haveMajorVersion3NodesMemoized = Suppliers.memoizeWithExpiration(haveMajorVersion3NodesSupplier, 1, TimeUnit.MINUTES); private static final boolean disableThreadValidation = Boolean.getBoolean(Props.DISABLE_THREAD_VALIDATION); diff --cc test/distributed/org/apache/cassandra/distributed/upgrade/MixedModeReadTest.java index 0000000,249e1b8..6ee9b0a mode 000000,100644..100644 --- a/test/distributed/org/apache/cassandra/distributed/upgrade/MixedModeReadTest.java +++ b/test/distributed/org/apache/cassandra/distributed/upgrade/MixedModeReadTest.java @@@ -1,0 -1,102 +1,92 @@@ + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package org.apache.cassandra.distributed.upgrade; + + import java.util.UUID; + + import org.junit.Assert; + import org.junit.Test; + + import org.apache.cassandra.distributed.UpgradeableCluster; + import org.apache.cassandra.distributed.api.ConsistencyLevel; -import org.apache.cassandra.distributed.api.Feature; -import org.apache.cassandra.distributed.impl.DelegatingInvokableInstance; + import org.apache.cassandra.distributed.shared.DistributedTestBase; + import org.apache.cassandra.distributed.shared.Versions; -import org.apache.cassandra.gms.Gossiper; + + public class MixedModeReadTest extends UpgradeTestBase + { + public static final String TABLE_NAME = "tbl"; + public static final String CREATE_TABLE = String.format( - "CREATE TABLE %s.%s (key int, c1 text, c2 text, c3 text, PRIMARY KEY (key))", ++ "CREATE TABLE %s.%s (key int, s1 text static, c1 text, c2 text, c3 text, PRIMARY KEY (key, c1))", + DistributedTestBase.KEYSPACE, TABLE_NAME); + + public static final String INSERT = String.format( - "INSERT INTO %s.%s (key, c1, c2, c3) VALUES (?, ?, ?, ?)", ++ "INSERT INTO %s.%s (key, s1, c1, c2, c3) VALUES (?, ?, ?, ?, ?)", + DistributedTestBase.KEYSPACE, TABLE_NAME); + + public static final String SELECT_C1 = String.format("SELECT key, c1 FROM %s.%s WHERE key = ?", + DistributedTestBase.KEYSPACE, TABLE_NAME); ++ public static final String SELECT_C1_S1_ROW = String.format("SELECT key, c1, s1 FROM %s.%s WHERE key = ? and c1 = ? ", ++ DistributedTestBase.KEYSPACE, TABLE_NAME); + public static final String SELECT_TRACE = "SELECT activity FROM system_traces.events where session_id = ? and source = ? ALLOW FILTERING;"; + + @Test + public void mixedModeReadColumnSubsetDigestCheck() throws Throwable + { + new TestCase() + .nodes(2) + .nodesToUpgrade(1) - .upgrade(Versions.Major.v30, Versions.Major.v3X) - .withConfig(config -> config.with(Feature.GOSSIP, Feature.NETWORK)) ++ .upgrade(Versions.Major.v30, Versions.Major.v4) ++ .upgrade(Versions.Major.v3X, Versions.Major.v4) + .setup(cluster -> { + cluster.schemaChange(CREATE_TABLE); - cluster.coordinator(1).execute(INSERT, ConsistencyLevel.ALL, 1, "foo", "bar", "baz"); - cluster.coordinator(1).execute(INSERT, ConsistencyLevel.ALL, 2, "foo", "bar", "baz"); ++ cluster.coordinator(1).execute(INSERT, ConsistencyLevel.ALL, 1, "static", "foo", "bar", "baz"); ++ cluster.coordinator(1).execute(INSERT, ConsistencyLevel.ALL, 1, "static", "fi", "biz", "baz"); ++ cluster.coordinator(1).execute(INSERT, ConsistencyLevel.ALL, 1, "static", "fo", "boz", "baz"); + + // baseline to show no digest mismatches before upgrade - checkTraceForDigestMismatch(cluster, 1); - checkTraceForDigestMismatch(cluster, 2); ++ checkTraceForDigestMismatch(cluster, 1, SELECT_C1, 1); ++ checkTraceForDigestMismatch(cluster, 2, SELECT_C1, 1); + }) + .runAfterNodeUpgrade((cluster, node) -> { + if (node != 1) + return; // shouldn't happen but guard for future test changes + - - // we need to let gossip settle or the test will fail - int attempts = 1; - while (!((DelegatingInvokableInstance) (cluster.get(1))).delegate().callOnInstance(() -> Gossiper.instance.isAnyNodeOn30())) - { - if (attempts > 30) - throw new RuntimeException("Gossiper.instance.isAnyNodeOn30() continually returns false despite expecting to be true"); - Thread.sleep(1000); - } - + // should not cause a disgest mismatch in mixed mode - checkTraceForDigestMismatch(cluster, 1); - checkTraceForDigestMismatch(cluster, 2); ++ checkTraceForDigestMismatch(cluster, 1, SELECT_C1, 1); ++ checkTraceForDigestMismatch(cluster, 2, SELECT_C1, 1); ++ checkTraceForDigestMismatch(cluster, 1, SELECT_C1_S1_ROW, 1, "foo"); ++ checkTraceForDigestMismatch(cluster, 2, SELECT_C1_S1_ROW, 1, "fi"); + }) + .run(); + } + - private void checkTraceForDigestMismatch(UpgradeableCluster cluster, int coordinatorNode) ++ private void checkTraceForDigestMismatch(UpgradeableCluster cluster, int coordinatorNode, String query, Object... boundValues) + { + UUID sessionId = UUID.randomUUID(); - cluster.coordinator(coordinatorNode).executeWithTracing(sessionId, SELECT_C1, ConsistencyLevel.ALL, 1); ++ cluster.coordinator(coordinatorNode).executeWithTracing(sessionId, query, ConsistencyLevel.ALL, boundValues); + Object[][] results = cluster.coordinator(coordinatorNode) + .execute(SELECT_TRACE, ConsistencyLevel.ALL, + sessionId, cluster.get(coordinatorNode).broadcastAddress().getAddress()); + for (Object[] result : results) + { + String activity = (String) result[0]; + Assert.assertFalse("Found Digest Mismatch", activity.toLowerCase().contains("mismatch for key")); + } + } - - + } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org