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]

Reply via email to