diff --git a/CHANGES.txt b/CHANGES.txt index 532c958a33..275294f168 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,6 +3,7 @@ * Update jackson JSON jars (CASSANDRA-13949) * Avoid locks when checking LCS fanout and if we should defrag (CASSANDRA-13930) Merged from 3.0: + * Add flag to disable materialized views, and warnings on creation (CASSANDRA-13959) * Don't let user drop or generally break tables in system_distributed (CASSANDRA-13813) * Provide a JMX call to sync schema with local storage (CASSANDRA-13954) * Mishandling of cells for removed/dropped columns when reading legacy files (CASSANDRA-13939) diff --git a/NEWS.txt b/NEWS.txt index 96285c74c3..f8dd93b330 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -20,6 +20,14 @@ Upgrading --------- - Nothing specific to this release, but please see previous upgrading sections. +Materialized Views +------------------- + - Following a discussion regarding concerns about the design and safety of Materialized Views, the C* development + community no longer recommends them for production use, and considers them experimental. Warnings messages will + now be logged when they are created. (See https://www.mail-archive.com/dev@cassandra.apache.org/msg11511.html) + - An 'enable_materialized_views' flag has been added to cassandra.yaml to allow operators to prevent creation of + views + 3.11.1 ====== diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml index e847e54b9e..ccebaaf252 100644 --- a/conf/cassandra.yaml +++ b/conf/cassandra.yaml @@ -1099,6 +1099,10 @@ enable_user_defined_functions: false # This option has no effect, if enable_user_defined_functions is false. enable_scripted_user_defined_functions: false +# Enables materialized view creation on this node. +# Materialized views are considered experimental and are not recommended for production use. +enable_materialized_views: true + # The default Windows kernel timer and scheduling resolution is 15.6ms for power conservation. # Lowering this value on Windows can provide much tighter latency and better throughput, however # some virtualized environments may see a negative performance impact from changing this setting diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java index 9489af93ad..a01203c8f6 100644 --- a/src/java/org/apache/cassandra/config/Config.java +++ b/src/java/org/apache/cassandra/config/Config.java @@ -339,6 +339,9 @@ public class Config public boolean enable_user_defined_functions = false; public boolean enable_scripted_user_defined_functions = false; + + public boolean enable_materialized_views = true; + /** * Optionally disable asynchronous UDF execution. * Disabling asynchronous UDF execution also implicitly disables the security-manager! diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 27b8b95b5b..51fbb59fb6 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -2372,6 +2372,11 @@ public class DatabaseDescriptor conf.user_defined_function_warn_timeout = userDefinedFunctionWarnTimeout; } + public static boolean enableMaterializedViews() + { + return conf.enable_materialized_views; + } + public static long getUserDefinedFunctionFailTimeout() { return conf.user_defined_function_fail_timeout; diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java index c503bf91bb..3d53ac4649 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java @@ -24,9 +24,13 @@ import java.util.stream.Collectors; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.apache.cassandra.auth.Permission; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.config.ViewDefinition; import org.apache.cassandra.cql3.*; @@ -43,6 +47,7 @@ import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.exceptions.UnauthorizedException; import org.apache.cassandra.schema.TableParams; import org.apache.cassandra.service.ClientState; +import org.apache.cassandra.service.ClientWarn; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.service.QueryState; import org.apache.cassandra.thrift.ThriftValidation; @@ -50,6 +55,8 @@ import org.apache.cassandra.transport.Event; public class CreateViewStatement extends SchemaAlteringStatement { + private static final Logger logger = LoggerFactory.getLogger(CreateViewStatement.class); + private final CFName baseName; private final List selectClause; private final WhereClause whereClause; @@ -116,6 +123,11 @@ public class CreateViewStatement extends SchemaAlteringStatement public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws RequestValidationException { + if (!DatabaseDescriptor.enableMaterializedViews()) + { + throw new InvalidRequestException("Materialized views are disabled. Enable in cassandra.yaml to use."); + } + // We need to make sure that: // - primary key includes all columns in base table's primary key // - make sure that the select statement does not have anything other than columns @@ -315,8 +327,13 @@ public class CreateViewStatement extends SchemaAlteringStatement whereClauseText, viewCfm); + logger.warn("Creating materialized view {} for {}.{}. " + + "Materialized views are experimental and are not recommended for production use.", + definition.viewName, cfm.ksName, cfm.cfName); + try { + ClientWarn.instance.warn("Materialized views are experimental and are not recommended for production use."); MigrationManager.announceNewView(definition, isLocalOnly); return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily()); }