mirror of https://github.com/apache/cassandra
Add flag to disable SASI indexes, and warning on creation
patch by Andres de la Peña; reviewed by Robert Stupp for CASSANDRA-14866
This commit is contained in:
parent
b9b2e8e574
commit
e6a61be8c8
|
|
@ -1,10 +1,11 @@
|
|||
3.11.5
|
||||
* Add flag to disable SASI indexes, and warnings on creation (CASSANDRA-14866)
|
||||
Merged from 3.0:
|
||||
* Improve `nodetool status -r` speed (CASSANDRA-14847)
|
||||
* Improve merkle tree size and time on heap (CASSANDRA-14096)
|
||||
* Add missing commands to nodetool_completion (CASSANDRA-14916)
|
||||
* Anti-compaction temporarily corrupts sstable state for readers (CASSANDRA-15004)
|
||||
Merged from 2.2:
|
||||
Merged from 2.2:
|
||||
* Multi-version in-JVM dtests (CASSANDRA-14937)
|
||||
|
||||
|
||||
|
|
@ -43,7 +44,7 @@ Merged from 3.0:
|
|||
* Fix static column order for SELECT * wildcard queries (CASSANDRA-14638)
|
||||
* sstableloader should use discovered broadcast address to connect intra-cluster (CASSANDRA-14522)
|
||||
* Fix reading columns with non-UTF names from schema (CASSANDRA-14468)
|
||||
Merged from 2.2:
|
||||
Merged from 2.2:
|
||||
* CircleCI docker image should bake in more dependencies (CASSANDRA-14985)
|
||||
* Don't enable client transports when bootstrap is pending (CASSANDRA-14525)
|
||||
* MigrationManager attempts to pull schema from different major version nodes (CASSANDRA-14928)
|
||||
|
|
|
|||
8
NEWS.txt
8
NEWS.txt
|
|
@ -50,6 +50,14 @@ Upgrading
|
|||
- repair_session_max_tree_depth setting has been added to cassandra.yaml to allow operators to reduce
|
||||
merkle tree size if repair is creating too much heap pressure. See CASSANDRA-14096 for details.
|
||||
|
||||
Experimental features
|
||||
---------------------
|
||||
- An 'enable_sasi_indexes' flag, true by default, has been added to cassandra.yaml to allow operators to prevent
|
||||
the creation of new SASI indexes, which are considered experimental and are not recommended for production use.
|
||||
(See https://www.mail-archive.com/dev@cassandra.apache.org/msg13582.html)
|
||||
- The flags 'enable_sasi_indexes' and 'enable_materialized_views' have been grouped under an experimental features
|
||||
section in cassandra.yaml.
|
||||
|
||||
3.11.4
|
||||
======
|
||||
|
||||
|
|
|
|||
|
|
@ -1112,10 +1112,6 @@ 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
|
||||
|
|
@ -1247,4 +1243,17 @@ back_pressure_strategy:
|
|||
# time and queue contention while iterating the backlog of messages.
|
||||
# An interval of 0 disables any wait time, which is the behavior of former Cassandra versions.
|
||||
#
|
||||
# otc_backlog_expiration_interval_ms: 200
|
||||
# otc_backlog_expiration_interval_ms: 200
|
||||
|
||||
|
||||
#########################
|
||||
# EXPERIMENTAL FEATURES #
|
||||
#########################
|
||||
|
||||
# Enables materialized view creation on this node.
|
||||
# Materialized views are considered experimental and are not recommended for production use.
|
||||
enable_materialized_views: true
|
||||
|
||||
# Enables SASI index creation on this node.
|
||||
# SASI indexes are considered experimental and are not recommended for production use.
|
||||
enable_sasi_indexes: true
|
||||
|
|
@ -348,6 +348,8 @@ public class Config
|
|||
|
||||
public boolean enable_materialized_views = true;
|
||||
|
||||
public boolean enable_sasi_indexes = true;
|
||||
|
||||
/**
|
||||
* Optionally disable asynchronous UDF execution.
|
||||
* Disabling asynchronous UDF execution also implicitly disables the security-manager!
|
||||
|
|
|
|||
|
|
@ -2407,11 +2407,26 @@ public class DatabaseDescriptor
|
|||
conf.user_defined_function_warn_timeout = userDefinedFunctionWarnTimeout;
|
||||
}
|
||||
|
||||
public static boolean enableMaterializedViews()
|
||||
public static boolean getEnableMaterializedViews()
|
||||
{
|
||||
return conf.enable_materialized_views;
|
||||
}
|
||||
|
||||
public static void setEnableMaterializedViews(boolean enableMaterializedViews)
|
||||
{
|
||||
conf.enable_materialized_views = enableMaterializedViews;
|
||||
}
|
||||
|
||||
public static boolean getEnableSASIIndexes()
|
||||
{
|
||||
return conf.enable_sasi_indexes;
|
||||
}
|
||||
|
||||
public static void setEnableSASIIndexes(boolean enableSASIIndexes)
|
||||
{
|
||||
conf.enable_sasi_indexes = enableSASIIndexes;
|
||||
}
|
||||
|
||||
public static long getUserDefinedFunctionFailTimeout()
|
||||
{
|
||||
return conf.user_defined_function_fail_timeout;
|
||||
|
|
|
|||
|
|
@ -29,18 +29,20 @@ 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.cql3.CFName;
|
||||
import org.apache.cassandra.cql3.ColumnIdentifier;
|
||||
import org.apache.cassandra.cql3.IndexName;
|
||||
import org.apache.cassandra.db.marshal.DurationType;
|
||||
import org.apache.cassandra.db.marshal.MapType;
|
||||
import org.apache.cassandra.exceptions.InvalidRequestException;
|
||||
import org.apache.cassandra.exceptions.RequestValidationException;
|
||||
import org.apache.cassandra.exceptions.UnauthorizedException;
|
||||
import org.apache.cassandra.index.sasi.SASIIndex;
|
||||
import org.apache.cassandra.schema.IndexMetadata;
|
||||
import org.apache.cassandra.schema.Indexes;
|
||||
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;
|
||||
|
|
@ -229,6 +231,17 @@ public class CreateIndexStatement extends SchemaAlteringStatement
|
|||
{
|
||||
kind = IndexMetadata.Kind.CUSTOM;
|
||||
indexOptions = properties.getOptions();
|
||||
|
||||
if (properties.customClass.equals(SASIIndex.class.getName()))
|
||||
{
|
||||
if (!DatabaseDescriptor.getEnableSASIIndexes())
|
||||
throw new InvalidRequestException("SASI indexes are disabled. Enable in cassandra.yaml to use.");
|
||||
|
||||
logger.warn("Creating SASI index {} for {}.{}. {}",
|
||||
acceptedName, cfm.ksName, cfm.cfName, SASIIndex.USAGE_WARNING);
|
||||
|
||||
ClientWarn.instance.warn(SASIIndex.USAGE_WARNING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public class CreateViewStatement extends SchemaAlteringStatement
|
|||
|
||||
public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws RequestValidationException
|
||||
{
|
||||
if (!DatabaseDescriptor.enableMaterializedViews())
|
||||
if (!DatabaseDescriptor.getEnableMaterializedViews())
|
||||
{
|
||||
throw new InvalidRequestException("Materialized views are disabled. Enable in cassandra.yaml to use.");
|
||||
}
|
||||
|
|
@ -327,13 +327,12 @@ 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);
|
||||
logger.warn("Creating materialized view {} for {}.{}. {}",
|
||||
definition.viewName, cfm.ksName, cfm.cfName, View.USAGE_WARNING);
|
||||
|
||||
try
|
||||
{
|
||||
ClientWarn.instance.warn("Materialized views are experimental and are not recommended for production use.");
|
||||
ClientWarn.instance.warn(View.USAGE_WARNING);
|
||||
MigrationManager.announceNewView(definition, isLocalOnly);
|
||||
return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import org.apache.cassandra.config.CFMetaData;
|
|||
import org.apache.cassandra.config.ColumnDefinition;
|
||||
import org.apache.cassandra.config.Schema;
|
||||
import org.apache.cassandra.config.ViewDefinition;
|
||||
import org.apache.cassandra.cql3.ColumnIdentifier;
|
||||
import org.apache.cassandra.cql3.MultiColumnRelation;
|
||||
import org.apache.cassandra.cql3.QueryOptions;
|
||||
import org.apache.cassandra.cql3.Relation;
|
||||
|
|
@ -57,6 +56,8 @@ import org.apache.cassandra.utils.FBUtilities;
|
|||
*/
|
||||
public class View
|
||||
{
|
||||
public final static String USAGE_WARNING = "Materialized views are experimental and are not recommended for production use.";
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(View.class);
|
||||
|
||||
public final String name;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ import org.apache.cassandra.utils.concurrent.OpOrder;
|
|||
|
||||
public class SASIIndex implements Index, INotificationConsumer
|
||||
{
|
||||
public final static String USAGE_WARNING = "SASI indexes are experimental and are not recommended for production use.";
|
||||
|
||||
private static class SASIIndexBuildingSupport implements IndexBuildingSupport
|
||||
{
|
||||
public SecondaryIndexBuilder getIndexBuildTask(ColumnFamilyStore cfs,
|
||||
|
|
|
|||
|
|
@ -18,12 +18,9 @@
|
|||
|
||||
package org.apache.cassandra.cql3;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import com.google.common.util.concurrent.Uninterruptibles;
|
||||
|
|
@ -43,14 +40,16 @@ import org.apache.cassandra.concurrent.Stage;
|
|||
import org.apache.cassandra.concurrent.StageManager;
|
||||
import org.apache.cassandra.config.CFMetaData;
|
||||
import org.apache.cassandra.config.ColumnDefinition;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.db.ColumnFamilyStore;
|
||||
import org.apache.cassandra.db.Keyspace;
|
||||
import org.apache.cassandra.db.SystemKeyspace;
|
||||
import org.apache.cassandra.db.compaction.CompactionManager;
|
||||
import org.apache.cassandra.db.marshal.AsciiType;
|
||||
import org.apache.cassandra.exceptions.InvalidRequestException;
|
||||
import org.apache.cassandra.db.view.View;
|
||||
import org.apache.cassandra.exceptions.SyntaxException;
|
||||
import org.apache.cassandra.schema.KeyspaceParams;
|
||||
import org.apache.cassandra.service.ClientWarn;
|
||||
import org.apache.cassandra.transport.ProtocolVersion;
|
||||
import org.apache.cassandra.utils.FBUtilities;
|
||||
|
||||
|
|
@ -1421,4 +1420,52 @@ public class ViewTest extends CQLTester
|
|||
{
|
||||
execute("CREATE MATERIALIZED VIEW myview AS SELECT a, b FROM \"\" WHERE b IS NOT NULL PRIMARY KEY (b, a)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a client warning is issued on materialized view creation.
|
||||
*/
|
||||
@Test
|
||||
public void testClientWarningOnCreate() throws Throwable
|
||||
{
|
||||
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
|
||||
|
||||
ClientWarn.instance.captureWarnings();
|
||||
String viewName = keyspace() + ".warning_view";
|
||||
execute("CREATE MATERIALIZED VIEW " + viewName +
|
||||
" AS SELECT v FROM %s WHERE k IS NOT NULL AND v IS NOT NULL PRIMARY KEY (v, k)");
|
||||
views.add(viewName);
|
||||
List<String> warnings = ClientWarn.instance.getWarnings();
|
||||
|
||||
Assert.assertNotNull(warnings);
|
||||
Assert.assertEquals(1, warnings.size());
|
||||
Assert.assertEquals(View.USAGE_WARNING, warnings.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the configuration flag to disable materialized views.
|
||||
*/
|
||||
@Test
|
||||
public void testDisableMaterializedViews() throws Throwable
|
||||
{
|
||||
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
|
||||
|
||||
executeNet(protocolVersion, "USE " + keyspace());
|
||||
|
||||
boolean enableMaterializedViews = DatabaseDescriptor.getEnableMaterializedViews();
|
||||
try
|
||||
{
|
||||
DatabaseDescriptor.setEnableMaterializedViews(false);
|
||||
createView("view1", "CREATE MATERIALIZED VIEW %s AS SELECT v FROM %%s WHERE k IS NOT NULL AND v IS NOT NULL PRIMARY KEY (v, k)");
|
||||
Assert.fail("Should not be able to create a materialized view if they are disabled");
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
Assert.assertTrue(e instanceof InvalidQueryException);
|
||||
Assert.assertTrue(e.getMessage().contains("Materialized views are disabled"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
DatabaseDescriptor.setEnableMaterializedViews(enableMaterializedViews);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,10 @@ import com.datastax.driver.core.Row;
|
|||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.SimpleStatement;
|
||||
import junit.framework.Assert;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.CQLTester;
|
||||
import org.apache.cassandra.exceptions.InvalidRequestException;
|
||||
import org.apache.cassandra.service.ClientWarn;
|
||||
|
||||
public class SASICQLTest extends CQLTester
|
||||
{
|
||||
|
|
@ -78,4 +81,49 @@ public class SASICQLTest extends CQLTester
|
|||
Assert.assertEquals(20, rs.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a client warning is issued on SASI index creation.
|
||||
*/
|
||||
@Test
|
||||
public void testClientWarningOnCreate()
|
||||
{
|
||||
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
|
||||
|
||||
ClientWarn.instance.captureWarnings();
|
||||
createIndex("CREATE CUSTOM INDEX ON %s (v) USING 'org.apache.cassandra.index.sasi.SASIIndex'");
|
||||
List<String> warnings = ClientWarn.instance.getWarnings();
|
||||
|
||||
Assert.assertNotNull(warnings);
|
||||
Assert.assertEquals(1, warnings.size());
|
||||
Assert.assertEquals(SASIIndex.USAGE_WARNING, warnings.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the configuration flag to disable SASI indexes.
|
||||
*/
|
||||
@Test
|
||||
public void testDisableSASIIndexes()
|
||||
{
|
||||
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
|
||||
|
||||
boolean enableSASIIndexes = DatabaseDescriptor.getEnableSASIIndexes();
|
||||
try
|
||||
{
|
||||
DatabaseDescriptor.setEnableSASIIndexes(false);
|
||||
createIndex("CREATE CUSTOM INDEX ON %s (v) USING 'org.apache.cassandra.index.sasi.SASIIndex'");
|
||||
Assert.fail("Should not be able to create a SASI index if they are disabled");
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
Throwable cause = e.getCause();
|
||||
Assert.assertNotNull(cause);
|
||||
Assert.assertTrue(cause instanceof InvalidRequestException);
|
||||
Assert.assertTrue(cause.getMessage().contains("SASI indexes are disabled"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
DatabaseDescriptor.setEnableSASIIndexes(enableSASIIndexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue