This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch cassandra-6.0 in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit 7fe905b5f9b3369a9ecd88eb51f4a9145bb1b44a Merge: 35ff990127 93b5aec70d Author: Caleb Rackliffe <[email protected]> AuthorDate: Thu Oct 1 23:25:23 2026 -0500 Merge branch 'cassandra-5.0' into cassandra-6.0 * cassandra-5.0: Isolate SAI index rebuilds from ZCS CHANGES.txt | 1 + .../cassandra/db/compaction/CompactionManager.java | 8 +- .../db/streaming/CassandraOutgoingFile.java | 41 ++- .../db/streaming/CassandraStreamManager.java | 13 +- .../cassandra/db/streaming/ComponentContext.java | 9 +- .../cassandra/index/SecondaryIndexBuilder.java | 8 + .../index/sai/StorageAttachedIndexBuilder.java | 70 ++++- .../sai/StorageAttachedIndexBuildingSupport.java | 66 ++++- .../cassandra/io/sstable/format/SSTableReader.java | 10 + .../sstable/format/SSTableStreamRebuildState.java | 96 +++++++ .../apache/cassandra/streaming/OutgoingStream.java | 7 + ...ndexDeleteDuringEntireSSTableStreamingTest.java | 234 +++++++++++++++++ ...dexRebuildDuringEntireSSTableStreamingTest.java | 243 ++++++++++++++++++ .../test/sai/StreamingDuringIndexRebuildTest.java | 155 +++++++++++ .../CassandraStreamManagerDoubleReleaseTest.java | 271 ++++++++++++++++++++ .../db/streaming/ComponentContextTest.java | 121 +++++++++ .../db/streaming/TableStreamManagerTest.java | 258 +++++++++++++++++++ .../index/sai/StreamRebuildCoordinationTest.java | 190 ++++++++++++++ .../format/SSTableStreamRebuildStateTest.java | 285 +++++++++++++++++++++ 19 files changed, 2061 insertions(+), 25 deletions(-) diff --cc CHANGES.txt index e3d674a04f,5ce20dd5f0..843d928b44 --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,56 -1,7 +1,57 @@@ -5.0.10 +6.0-alpha3 + * Tighten up NoSpamLogger changes after migration to Caffeine cache (CASSANDRA-21721) + * Preserve the original exception when an in-memory local response fails to close (CASSANDRA-21710) + * Generate autocompletion scripts for the nodetool command during the build (CASSANDRA-20794) + * Implement Zstd compression level guardrail (CASSANDRA-21021) + * Fix Compression dictionary distribution silently leaving a node on a stale dictionary (CASSANDRA-21681) + * ZstdCompressionDictionary reference leak when opening dictionary-compressed SSTables concurrently (CASSANDRA-21680) + * Avoid ZstdDictionary to allocate a native zstd context per chunk (CASSANDRA-21677) + * Avoid ZstdDictionaryCompressor to allocate a native zstd context per chunk (CASSANDRA-21672) + * Don't replicate transformations to LEFT nodes (CASSANDRA-21652) + * Don't fail host specific repairs against system_cluster_metadata (CASSANDRA-21651) + * During major upgrade, if a node has replacement arguments it attempts to bootstrap even if already bootstrapped (CASSANDRA-21634) + * Node with empty data directory is allowed to rejoin the ring on the second start after the first start is correctly rejected (CASSANDRA-21633) + * Megamorphic call in ClusteringPrefix.Deserializer.deserializeOne slows down reads (CASSANDRA-21587) + * Throw InvalidRequestException instead of crashing on malformed IN marker values (CASSANDRA-21648) + * Avoid serialization and deserialization for coordinator-local single partition data read (CASSANDRA-21354) + * Allow nodetool cms reconfigure to ignore nodes via --ignore, excluding them from the new CMS (CASSANDRA-21627) + * Accord: Compute Dependencies Incrementally (CASSANDRA-21682) + * Avoid double chunk read for BTI small partitions during a select query execution (CASSANDRA-21637) + * Report the number of rows replica filtering protection cached when it warns (CASSANDRA-21623) + * Fix non-printable characters in Gossiper log for TOKENS (CASSANDRA-21417) + * Fix compression dictionary training failing with "insufficient samples" on large-chunk tables (CASSANDRA-21666) + * AccordExecutor improvements (CASSANDRA-21662) + * Upgrade async-profiler to 4.5 (CASSANDRA-21630) + * Guardrail configurations of zero are now treated as zero instead of unlimited (CASSANDRA-21517) + * Support multi-cell columns in cursor compaction (CASSANDRA-21463) + * Optimize authorization logic for BatchStatement and TransactionStatement when a single table is updated (CASSANDRA-21606) + * Upgrade lz4-java to 1.11.2 (CASSANDRA-21564) + * Encode the CQL as raw bytes to avoid utf string serialization length limitation (CASSANDRA-21599) + * Add a guardrail to disallow reconfiguring CMS below a minimum size (CASSANDRA-19195) + * Node can report DECOMMISSION_FAILED while actively leaving after a rejected decommission attempt (CASSANDRA-21583) + * Make NoSpamLogger to use Caffeine cache instead of unbounded cache that could lead to memory exhaustion (CASSANDRA-21474) + * Reduce overheads of isOrdinaryUser check performed by Guardrail.enabled (CASSANDRA-21589) + * MultiStepOperations should not encode range movements using endpoints (CASSANDRA-21582) + * Avoid "During operation execution,... at ONE the ring has changed from epoch1 to epoch2 error" with counter writes (CASSANDRA-21585) + * Reject LIKE patterns with a wildcard (%) anywhere other than the start or end (CASSANDRA-21068) + * Stabilize cursor-based compaction (CASSANDRA-21462) + * Stop using Java streams in CIDRPermissions.SubsetPermissions#canAccessFrom hot method (CASSANDRA-21588) + * Enable trickle fsync by default (CASSANDRA-21572) + * Protect uncaught_exceptions virtual table against the crash path (CASSANDRA-21578) + * Optimize ServerConnection.requests for both reads and writes (CASSANDRA-21569) + * Ensure transferred_ranges reset on decommision re-attempt when pending ranges cannot be proven continous (CASSANDRA-16290) + * Add blob type support to SAI (CASSANDRA-20012) + * Fix deserialization of column masks in cluster metadata (CASSANDRA-21549) + * Caffeine caches in CompressionDictionaryCache and ZstdDictionaryCompressor should specify an executor explicitly (CASSANDRA-21557) + * Make cqlsh prompt to reset to no keyspace set by USE after dropping that keyspace (CASSANDRA-21548) + * Implement CMS rediscovery and recovery protocol (CASSANDRA-20476) + * Apply performance optimizations for rows merging logic (CASSANDRA-21524) + * Fix operationMode reporting DECOMMISSION_FAILED instead of LEAVING when resuming a failed decommission (CASSANDRA-21493) + * Avoid megamorphic calls when serializing and deserializing fixed-length values (CASSANDRA-21536) + * Avoid megamorphic calls for Cell.timestamp/ttl/path/localDeletionTimeAsUnsignedInt methods (CASSANDRA-21526) +Merged from 5.0: + * Isolate SAI index rebuilds from ZCS (CASSANDRA-21520) * Bound and chunk the BTI partition index preload (CASSANDRA-21632) - * Restore volatile on CommitLogSegment.cdcState dropped in merge (CASSANDRA-21665) * Fix compressed scan read-ahead buffer Block leak and chunk-cache pollution by scans (CASSANDRA-21671) * A read on a replica that does not know the index yet fails with a NullPointerException (CASSANDRA-21658) * Release hints write buffer when the write executor shuts down (CASSANDRA-21657) diff --cc src/java/org/apache/cassandra/db/streaming/CassandraOutgoingFile.java index f4f79a780c,8950eddf1a..5a989445cc --- a/src/java/org/apache/cassandra/db/streaming/CassandraOutgoingFile.java +++ b/src/java/org/apache/cassandra/db/streaming/CassandraOutgoingFile.java @@@ -49,8 -52,10 +52,11 @@@ public class CassandraOutgoingFile impl private final boolean shouldStreamEntireSSTable; private final StreamOperation operation; private final CassandraStreamHeader header; + private final List<Range<Token>> ranges; + // guards against releasing the SSTable streaming status more than once + private boolean streamRebuildStatusReleased = false; + public CassandraOutgoingFile(StreamOperation operation, Ref<SSTableReader> ref, List<SSTableReader.PartitionPositionBounds> sections, List<Range<Token>> normalizedRanges, long estimatedKeys) diff --cc test/unit/org/apache/cassandra/db/streaming/ComponentContextTest.java index 0000000000,e081b1eaad..0898f72762 mode 000000,100644..100644 --- a/test/unit/org/apache/cassandra/db/streaming/ComponentContextTest.java +++ b/test/unit/org/apache/cassandra/db/streaming/ComponentContextTest.java @@@ -1,0 -1,121 +1,121 @@@ + /* + * 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.db.streaming; + + import java.io.IOException; + import java.nio.channels.FileChannel; + + import org.junit.BeforeClass; + import org.junit.Test; + + import org.apache.cassandra.SchemaLoader; + import org.apache.cassandra.Util; + import org.apache.cassandra.db.ColumnFamilyStore; + import org.apache.cassandra.db.Keyspace; + import org.apache.cassandra.db.RowUpdateBuilder; + import org.apache.cassandra.db.compaction.CompactionManager; + import org.apache.cassandra.io.sstable.Component; + import org.apache.cassandra.io.sstable.format.SSTableReader; + import org.apache.cassandra.schema.KeyspaceParams; + import org.apache.cassandra.utils.ByteBufferUtil; + + import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertTrue; + import static org.junit.Assert.fail; + + public class ComponentContextTest + { + private static final String KEYSPACE = "ComponentContextTest"; + private static final String CF_STANDARD = "Standard1"; + + private static SSTableReader sstable; + + @BeforeClass + public static void defineSchemaAndPrepareSSTable() + { + SchemaLoader.prepareServer(); + SchemaLoader.createKeyspace(KEYSPACE, + KeyspaceParams.simple(1), + SchemaLoader.standardCFMD(KEYSPACE, CF_STANDARD)); + + ColumnFamilyStore store = Keyspace.open(KEYSPACE).getColumnFamilyStore(CF_STANDARD); + CompactionManager.instance.disableAutoCompaction(); + for (int j = 0; j < 10; j++) + { + new RowUpdateBuilder(store.metadata(), j, String.valueOf(j)) + .clustering("0") + .add("val", ByteBufferUtil.EMPTY_BYTE_BUFFER) + .build() + .applyUnsafe(); + } + Util.flush(store); - CompactionManager.instance.performMaximal(store, false); ++ CompactionManager.instance.performMaximal(store); + + sstable = store.getLiveSSTables().iterator().next(); + } + + @Test + public void matchingSizeReturnsChannel() throws IOException + { + try (ComponentContext context = ComponentContext.create(sstable)) + { + Component component = firstStreamableComponent(context); + long advertised = context.manifest().sizeOf(component); + try (FileChannel channel = context.channel(sstable.descriptor, component, advertised)) + { + assertEquals("advertised size must match the streamed channel size", advertised, channel.size()); + } + } + } + + @Test + public void sizeMismatchThrowsIllegalStateExceptionNotAssertionError() throws IOException + { + try (ComponentContext context = ComponentContext.create(sstable)) + { + Component component = firstStreamableComponent(context); + long advertised = context.manifest().sizeOf(component); + long wrongSize = advertised + 1; // pretend the on-disk file no longer matches the advertised manifest + + try + { + context.channel(sstable.descriptor, component, wrongSize); + fail("Expected an IllegalStateException when the advertised size does not match the on-disk size"); + } + catch (AssertionError e) + { + // The whole point of the hardening: this must NOT be an AssertionError, since assertions are + // disabled in production and the corrupt bytes would otherwise be shipped silently. + throw new AssertionError("size mismatch must fail via IllegalStateException, not AssertionError", e); + } + catch (IllegalStateException e) + { + assertTrue("exception message should describe the size mismatch", + e.getMessage().contains("file size to be")); + assertTrue("exception message should include the actual on-disk size", + e.getMessage().contains(String.valueOf(advertised))); + } + } + } + + private static Component firstStreamableComponent(ComponentContext context) + { + return context.manifest().components().iterator().next(); + } + } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
