This is an automated email from the ASF dual-hosted git repository. samt pushed a commit to branch cep-21-tcm in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit 306afbb8ffd8798192e6ef609920c5684b905def Author: Marcus Eriksson <[email protected]> AuthorDate: Tue Mar 28 15:37:04 2023 +0200 [CEP-21] Fix (re)building MVs patch by Marcus Eriksson; reviewed by Alex Petrov and Sam Tunnicliffe for CASSANDRA-18415 --- src/java/org/apache/cassandra/db/Keyspace.java | 2 +- src/java/org/apache/cassandra/db/view/ViewManager.java | 16 +++++++++++----- .../org/apache/cassandra/schema/DistributedSchema.java | 18 +++++++++++++++++- .../apache/cassandra/tcm/listeners/SchemaListener.java | 2 ++ test/unit/org/apache/cassandra/cql3/ViewTest.java | 4 ++-- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/java/org/apache/cassandra/db/Keyspace.java b/src/java/org/apache/cassandra/db/Keyspace.java index 2e163da3d0..f3cd887ad3 100644 --- a/src/java/org/apache/cassandra/db/Keyspace.java +++ b/src/java/org/apache/cassandra/db/Keyspace.java @@ -328,7 +328,7 @@ public class Keyspace initCf(cfm, loadSSTables); } - this.viewManager.reload(false); + this.viewManager.reload(metadata); this.metadataRef.unsetInitial(); this.repairManager = new CassandraKeyspaceRepairManager(this); diff --git a/src/java/org/apache/cassandra/db/view/ViewManager.java b/src/java/org/apache/cassandra/db/view/ViewManager.java index 8d8b9b912d..608907a4eb 100644 --- a/src/java/org/apache/cassandra/db/view/ViewManager.java +++ b/src/java/org/apache/cassandra/db/view/ViewManager.java @@ -92,9 +92,9 @@ public class ViewManager return viewsByName.values(); } - public void reload(boolean buildAllViews) + public void reload(KeyspaceMetadata keyspaceMetadata) { - Views views = keyspace.getMetadata().views; + Views views = keyspaceMetadata.views; Map<String, ViewMetadata> newViewsByName = Maps.newHashMapWithExpectedSize(views.size()); for (ViewMetadata definition : views) { @@ -106,10 +106,16 @@ public class ViewManager if (!viewsByName.containsKey(entry.getKey())) addView(entry.getValue()); } + } - if (!buildAllViews) - return; - + public void buildViews() + { + Views views = keyspace.getMetadata().views; + Map<String, ViewMetadata> newViewsByName = Maps.newHashMapWithExpectedSize(views.size()); + for (ViewMetadata definition : views) + { + newViewsByName.put(definition.name(), definition); + } // Building views involves updating view build status in the system_distributed // keyspace and therefore it requires ring information. This check prevents builds // being submitted when Keyspaces are initialized during CassandraDaemon::setup as diff --git a/src/java/org/apache/cassandra/schema/DistributedSchema.java b/src/java/org/apache/cassandra/schema/DistributedSchema.java index aa628d66e8..f2e2356f9d 100644 --- a/src/java/org/apache/cassandra/schema/DistributedSchema.java +++ b/src/java/org/apache/cassandra/schema/DistributedSchema.java @@ -155,7 +155,7 @@ public class DistributedSchema implements MetadataValue<DistributedSchema> schemaChangeNotifier.notifyKeyspaceAltered(delta, loadSSTables); // deal with all added, and altered views - keyspaceInstances.get(delta.after.name).viewManager.reload(true); + keyspace.viewManager.reload(keyspaces.get(keyspace.getName()).get()); } //schemaChangeNotifier.notifyKeyspaceAltered(delta); @@ -173,6 +173,22 @@ public class DistributedSchema implements MetadataValue<DistributedSchema> QueryProcessor.clearPreparedStatementsCache(); } + public static void maybeRebuildViews(DistributedSchema prev, DistributedSchema current) + { + Keyspaces.KeyspacesDiff ksDiff = Keyspaces.diff(prev.getKeyspaces(), current.getKeyspaces()); + if (ksDiff.isEmpty() || ksDiff.altered.isEmpty()) + return; + ksDiff.altered.forEach(delta -> { + if (delta.views.isEmpty()) + return; + boolean initialized = Keyspace.isInitialized(); + Keyspace keyspace = initialized ? current.keyspaceInstances.get(delta.after.name) : null; + if (keyspace != null) + keyspace.viewManager.buildViews(); + }); + + } + private void dropView(Keyspace keyspace, ViewMetadata metadata, boolean dropData) { keyspace.viewManager.dropView(metadata.name()); diff --git a/src/java/org/apache/cassandra/tcm/listeners/SchemaListener.java b/src/java/org/apache/cassandra/tcm/listeners/SchemaListener.java index 516c7450c8..d3320b1568 100644 --- a/src/java/org/apache/cassandra/tcm/listeners/SchemaListener.java +++ b/src/java/org/apache/cassandra/tcm/listeners/SchemaListener.java @@ -21,6 +21,7 @@ package org.apache.cassandra.tcm.listeners; import org.apache.cassandra.db.SystemKeyspace; import org.apache.cassandra.gms.ApplicationState; import org.apache.cassandra.gms.Gossiper; +import org.apache.cassandra.schema.DistributedSchema; import org.apache.cassandra.schema.Schema; import org.apache.cassandra.schema.SchemaDiagnostics; import org.apache.cassandra.service.StorageService; @@ -40,6 +41,7 @@ public class SchemaListener implements ChangeListener { if (!next.schema.lastModified().equals(prev.schema.lastModified())) { + DistributedSchema.maybeRebuildViews(prev.schema, next.schema); SchemaDiagnostics.versionUpdated(Schema.instance); Gossiper.instance.addLocalApplicationState(ApplicationState.SCHEMA, StorageService.instance.valueFactory.schema(next.schema.getVersion())); SystemKeyspace.updateSchemaVersion(next.schema.getVersion()); diff --git a/test/unit/org/apache/cassandra/cql3/ViewTest.java b/test/unit/org/apache/cassandra/cql3/ViewTest.java index d82fd322e1..7a22acd084 100644 --- a/test/unit/org/apache/cassandra/cql3/ViewTest.java +++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java @@ -420,7 +420,7 @@ public class ViewTest extends ViewAbstractTest assertRowsNet(executeViewNet("SELECT * FROM %s"), row(1, 0)); } - private void testViewBuilderResume(int concurrentViewBuilders) throws Throwable + private void testViewBuilderResumeHelper(int concurrentViewBuilders) throws Throwable { createTable("CREATE TABLE %s (" + "k int, " + @@ -477,7 +477,7 @@ public class ViewTest extends ViewAbstractTest { for (int i = 1; i <= 8; i *= 2) { - testViewBuilderResume(i); + testViewBuilderResumeHelper(i); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
