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 740879d5a046768be0fd6c171457dad411d05626
Author: Marcus Eriksson <[email protected]>
AuthorDate: Mon Mar 16 15:04:42 2026 +0100

    Don't clear prepared statement cache on nodetool cms initialize
    
    Patch by marcuse; reviewed by Sam Tunnicliffe for CASSANDRA-21234
---
 CHANGES.txt                                        |   1 +
 .../org/apache/cassandra/tcm/ClusterMetadata.java  |   5 -
 .../tcm/listeners/InitializationListener.java      |  36 -------
 .../org/apache/cassandra/tcm/log/LocalLog.java     |   2 -
 ...usterMetadataUpgradePreparedStatementsTest.java | 110 +++++++++++++++++++++
 5 files changed, 111 insertions(+), 43 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index ff76806971..8d1e71aec1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 6.0-alpha2
+ * Don't clear prepared statement cache on nodetool cms initialize 
(CASSANDRA-21234)
  * Improve performance when deserializing cluster metadata  (CASSANDRA-21224)
  * Minor TokenMap performance improvement (CASSANDRA-21223)
  * Handle lost response when committing PrepareMove (CASSANDRA-21222)
diff --git a/src/java/org/apache/cassandra/tcm/ClusterMetadata.java 
b/src/java/org/apache/cassandra/tcm/ClusterMetadata.java
index b99663a655..5645b439e4 100644
--- a/src/java/org/apache/cassandra/tcm/ClusterMetadata.java
+++ b/src/java/org/apache/cassandra/tcm/ClusterMetadata.java
@@ -1062,11 +1062,6 @@ public class ClusterMetadata
         return null;
     }
 
-    public boolean metadataSerializationUpgradeInProgress()
-    {
-        return 
!directory.clusterMaxVersion.serializationVersion().equals(directory.commonSerializationVersion);
-    }
-
     public static class Serializer implements 
MetadataSerializer<ClusterMetadata>
     {
         @Override
diff --git 
a/src/java/org/apache/cassandra/tcm/listeners/InitializationListener.java 
b/src/java/org/apache/cassandra/tcm/listeners/InitializationListener.java
deleted file mode 100644
index 5ce601d46e..0000000000
--- a/src/java/org/apache/cassandra/tcm/listeners/InitializationListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.tcm.listeners;
-
-import org.apache.cassandra.cql3.QueryProcessor;
-import org.apache.cassandra.tcm.Transformation;
-import org.apache.cassandra.tcm.log.Entry;
-
-public class InitializationListener implements LogListener
-{
-    @Override
-    public void notify(Entry entry, Transformation.Result result)
-    {
-        if (entry.transform.kind() == Transformation.Kind.INITIALIZE_CMS)
-        {
-            QueryProcessor.clearPreparedStatementsCache();
-            QueryProcessor.clearInternalStatementsCache();
-        }
-    }
-}
diff --git a/src/java/org/apache/cassandra/tcm/log/LocalLog.java 
b/src/java/org/apache/cassandra/tcm/log/LocalLog.java
index 4b7760e002..b3069eb029 100644
--- a/src/java/org/apache/cassandra/tcm/log/LocalLog.java
+++ b/src/java/org/apache/cassandra/tcm/log/LocalLog.java
@@ -57,7 +57,6 @@ import org.apache.cassandra.tcm.Startup;
 import org.apache.cassandra.tcm.Transformation;
 import org.apache.cassandra.tcm.listeners.ChangeListener;
 import org.apache.cassandra.tcm.listeners.ClientNotificationListener;
-import org.apache.cassandra.tcm.listeners.InitializationListener;
 import org.apache.cassandra.tcm.listeners.LegacyStateListener;
 import org.apache.cassandra.tcm.listeners.LogListener;
 import org.apache.cassandra.tcm.listeners.MetadataSnapshotListener;
@@ -905,7 +904,6 @@ public abstract class LocalLog implements Closeable
         changeListeners.clear();
 
         addListener(snapshotListener());
-        addListener(new InitializationListener());
         addListener(new SchemaListener(spec.loadSSTables));
         addListener(new LegacyStateListener());
         addListener(new PlacementsChangeListener());
diff --git 
a/test/distributed/org/apache/cassandra/distributed/upgrade/ClusterMetadataUpgradePreparedStatementsTest.java
 
b/test/distributed/org/apache/cassandra/distributed/upgrade/ClusterMetadataUpgradePreparedStatementsTest.java
new file mode 100644
index 0000000000..81b48040c5
--- /dev/null
+++ 
b/test/distributed/org/apache/cassandra/distributed/upgrade/ClusterMetadataUpgradePreparedStatementsTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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 com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Session;
+
+import org.junit.Test;
+
+import org.apache.cassandra.cql3.QueryHandler;
+import org.apache.cassandra.cql3.QueryProcessor;
+import org.apache.cassandra.cql3.statements.SelectStatement;
+import org.apache.cassandra.cql3.statements.UpdateStatement;
+import org.apache.cassandra.distributed.Constants;
+import org.apache.cassandra.distributed.api.Feature;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
+import org.apache.cassandra.distributed.api.IUpgradeableInstance;
+
+public class ClusterMetadataUpgradePreparedStatementsTest extends 
UpgradeTestBase
+{
+    @Test
+    public void simpleUpgradeTest() throws Throwable
+    {
+        new UpgradeTestBase.TestCase()
+        .nodes(3)
+        .nodesToUpgrade(1, 2, 3)
+        .withConfig((cfg) -> cfg.with(Feature.NETWORK, Feature.GOSSIP, 
Feature.NATIVE_PROTOCOL)
+                                              
.set(Constants.KEY_DTEST_FULL_STARTUP, true))
+        .upgradesToCurrentFrom(v50)
+        .setup((cluster) -> {
+            cluster.schemaChange(withKeyspace("CREATE TABLE %s.tbl (pk int, ck 
int, v int, PRIMARY KEY (pk, ck))"));
+        })
+        .runAfterClusterUpgrade((cluster) -> {
+            String node1Address = 
cluster.get(1).config().broadcastAddress().getHostString();
+            com.datastax.driver.core.Cluster.Builder builder = 
com.datastax.driver.core.Cluster.builder()
+                                                                               
                .addContactPoint(node1Address);
+            try (com.datastax.driver.core.Cluster c = builder.build();
+                 Session session = c.connect())
+            {
+                PreparedStatement ps = session.prepare(withKeyspace("insert 
into %s.tbl (pk, ck, v) values (?, ?, ?)"));
+                PreparedStatement ps2 = session.prepare(withKeyspace("select 
pk, ck, v from %s.tbl where pk = ?"));
+                for (int i = 0; i < 10; i++)
+                {
+                    session.execute(ps.bind(i, 2, 3));
+                    session.execute(ps2.bind(i));
+                }
+                assertPSCache(cluster.get(1), false, 0);
+                cluster.get(1).nodetoolResult("cms", 
"initialize").asserts().success();
+                assertPSCache(cluster.get(1), false, 0);
+                for (int i = 0; i < 10; i++)
+                {
+                    session.execute(ps.bind(i, 3, 3));
+                    session.execute(ps2.bind(i));
+                }
+                session.execute(withKeyspace("alter table %s.tbl add x int"));
+
+                assertPSCacheEmpty(cluster.get(1));
+
+                for (int i = 0; i < 10; i++)
+                {
+                    session.execute(ps.bind(i, 3, 3));
+                    session.execute(ps2.bind(i));
+                }
+                assertPSCache(cluster.get(1), false, 4);
+            }
+        }).run();
+    }
+
+    private static void assertPSCacheEmpty(IUpgradeableInstance inst)
+    {
+        assertPSCache(inst, true, -1);
+    }
+
+    private static void assertPSCache(IUpgradeableInstance inst, boolean 
shouldBeEmpty, long expectedEpoch)
+    {
+        ((IInvokableInstance)inst).runOnInstance(() -> {
+            if (shouldBeEmpty != 
QueryProcessor.instance.getPreparedStatements().isEmpty())
+                throw new AssertionError("Prepared statements should not be 
empty after `cms initialize`");
+
+            for (QueryHandler.Prepared p : 
QueryProcessor.instance.getPreparedStatements().values())
+            {
+                long statementEpoch = -1;
+                if (p.statement instanceof SelectStatement)
+                    statementEpoch = 
((SelectStatement)p.statement).table.epoch.getEpoch();
+                else if (p.statement instanceof UpdateStatement)
+                    statementEpoch = 
((UpdateStatement)p.statement).metadata.epoch.getEpoch();
+
+                if (statementEpoch != expectedEpoch)
+                    throw new AssertionError(String.format("Statement %s has 
the wrong epoch: %d != %d ", p.statement, statementEpoch, expectedEpoch));
+            }
+        });
+    }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to