This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch cassandra-5.0
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/cassandra-5.0 by this push:
new f000bddd36 Avoid rebuilding per-SSTable SAI components unless missing
or corrupted
f000bddd36 is described below
commit f000bddd36e4cdf0d294b16ca9642f77964b24db
Author: Caleb Rackliffe <[email protected]>
AuthorDate: Tue Aug 11 16:42:18 2026 -0500
Avoid rebuilding per-SSTable SAI components unless missing or corrupted
patch by Sunil Ramchandra Pawar; reviewed by Caleb Rackliffe and David
Capwell for CASSANDRA-21515
---
CHANGES.txt | 1 +
.../index/sai/StorageAttachedIndexBuilder.java | 2 -
.../index/sai/cql/StorageAttachedIndexDDLTest.java | 66 ++++++++++++++++++++++
.../index/sai/functional/SnapshotTest.java | 3 +-
4 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index edc51e1203..35a6124889 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
5.0.10
+ * Avoid rebuilding per-SSTable SAI components unless missing or corrupted
(CASSANDRA-21515)
* Propagate trickle_fsync settings to compressed SSTable writers
(CASSANDRA-21487)
* Allow DatabaseDescriptor.setCompressedReadAheadBufferSizeInKb(0) to disable
read-ahead buffer (CASSANDRA-21522)
* Return CorruptSSTableException if chunk metadata and file size are out of
sync (CASSANDRA-21519)
diff --git
a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexBuilder.java
b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexBuilder.java
index fe856059f8..dd94272700 100644
--- a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexBuilder.java
+++ b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexBuilder.java
@@ -262,9 +262,7 @@ public class StorageAttachedIndexBuilder extends
SecondaryIndexBuilder
{
IndexDescriptor indexDescriptor = IndexDescriptor.create(sstable);
- // if per-table files are incomplete, full rebuild is requested, or
checksum fails
if (!indexDescriptor.isPerSSTableIndexBuildComplete()
- || isFullRebuild
||
!indexDescriptor.validatePerSSTableComponents(IndexValidation.CHECKSUM, true,
false))
{
CountDownLatch latch = CountDownLatch.newCountDownLatch(1);
diff --git
a/test/unit/org/apache/cassandra/index/sai/cql/StorageAttachedIndexDDLTest.java
b/test/unit/org/apache/cassandra/index/sai/cql/StorageAttachedIndexDDLTest.java
index d21331c1ab..90bc1c1a71 100644
---
a/test/unit/org/apache/cassandra/index/sai/cql/StorageAttachedIndexDDLTest.java
+++
b/test/unit/org/apache/cassandra/index/sai/cql/StorageAttachedIndexDDLTest.java
@@ -60,6 +60,7 @@ import
org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.index.Index;
import org.apache.cassandra.index.SecondaryIndexManager;
import org.apache.cassandra.index.sai.SAITester;
+import org.apache.cassandra.index.sai.SSTableContext;
import org.apache.cassandra.index.sai.StorageAttachedIndex;
import org.apache.cassandra.index.sai.StorageAttachedIndexBuilder;
import org.apache.cassandra.index.sai.analyzer.NonTokenizingOptions;
@@ -1003,6 +1004,71 @@ public class StorageAttachedIndexDDLTest extends
SAITester
assertEquals(rowCount, rows.all().size());
}
+ @Test
+ public void rebuildingOneIndexNotRewriteSharedPerSSTableComponents()
throws Throwable
+ {
+ Injections.Counter sharedContextBuilds =
Injections.newCounter("SharedPerSSTableContextBuilds")
+
.add(InvokePointBuilder.newInvokePoint().onClass(SSTableContext.class).onMethod("create"))
+ .build();
+
+ Injections.inject(sharedContextBuilds);
+
+ createTable(CREATE_TABLE_TEMPLATE);
+ String v1Index = createIndex(String.format(CREATE_INDEX_TEMPLATE,
"v1"));
+ createIndex(String.format(CREATE_INDEX_TEMPLATE, "v2"));
+
+ execute("INSERT INTO %s (id1, v1, v2) VALUES ('0', 0, '100')");
+ execute("INSERT INTO %s (id1, v1, v2) VALUES ('1', 1, '101')");
+ flush();
+
+ assertEquals(1, sharedContextBuilds.get());
+
+ assertEquals(1, execute("SELECT id1 FROM %s WHERE v1 = 0").size());
+ assertEquals(1, execute("SELECT id1 FROM %s WHERE v2 = '101'").size());
+
+ sharedContextBuilds.reset();
+
+ rebuildIndexes(v1Index);
+
+ // CASSANDRA-21515: rebuilding one index must NOT rewrite the shared
per-SSTable components.
+ assertEquals("Rebuilding of a single SAI index must not rebuild the
shared per-SSTable components",
+ 0, sharedContextBuilds.get());
+
+ assertEquals(1, execute("SELECT id1 FROM %s WHERE v2 = '101'").size());
+ assertEquals(1, execute("SELECT id1 FROM %s WHERE v1 = 0").size());
+ }
+
+ @Test
+ public void rebuildRegeneratesCorruptSharedPerSSTableComponents() throws
Throwable
+ {
+ Injections.Counter sharedContextBuilds =
Injections.newCounter("SharedPerSSTableContextBuilds")
+
.add(InvokePointBuilder.newInvokePoint().onClass(SSTableContext.class).onMethod("create"))
+ .build();
+ Injections.inject(sharedContextBuilds);
+
+ createTable(CREATE_TABLE_TEMPLATE);
+ String v1Index = createIndex(String.format(CREATE_INDEX_TEMPLATE,
"v1"));
+ String v2Index = createIndex(String.format(CREATE_INDEX_TEMPLATE,
"v2"));
+
+ execute("INSERT INTO %s (id1, v1, v2) VALUES ('0', 0, '100')");
+ execute("INSERT INTO %s (id1, v1, v2) VALUES ('1', 1, '101')");
+ flush();
+
+ assertEquals(1, sharedContextBuilds.get());
+
+ corruptIndexComponent(IndexComponent.ROW_TO_PARTITION,
CorruptionType.EMPTY_FILE);
+ sharedContextBuilds.reset();
+ assertEquals(0, sharedContextBuilds.get());
+
+ rebuildIndexes(v1Index, v2Index);
+
+ assertEquals("corrupt shared per-SSTable components must be
regenerated on rebuild",
+ 1, sharedContextBuilds.get());
+
+ assertEquals(1, execute("SELECT id1 FROM %s WHERE v1 = 0").size());
+ assertEquals(1, execute("SELECT id1 FROM %s WHERE v2 = '101'").size());
+ }
+
@Test
public void verifyCleanupFailedPerIndexFiles() throws Throwable
{
diff --git
a/test/unit/org/apache/cassandra/index/sai/functional/SnapshotTest.java
b/test/unit/org/apache/cassandra/index/sai/functional/SnapshotTest.java
index fd38bc6006..83365cf987 100644
--- a/test/unit/org/apache/cassandra/index/sai/functional/SnapshotTest.java
+++ b/test/unit/org/apache/cassandra/index/sai/functional/SnapshotTest.java
@@ -106,7 +106,8 @@ public class SnapshotTest extends SAITester
verifyIndexFiles(indexTermType, indexIdentifier, 2);
assertNotEquals(snapshotLastModified, indexFilesLastModified());
assertNumRows(2, "SELECT * FROM %%s WHERE v1 >= 0");
- assertValidationCount(2, 2); // compaction should not validate
+ // CASSANDRA-21515: a single-index rebuild no longer rewrites the
shared per-SSTable components
+ assertValidationCount(4, 2);
// index components are included after rebuild
verifyIndexComponentsIncludedInSSTable();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]