Merge branch 'cassandra-3.11' into trunk

# Conflicts:
#	CHANGES.txt
#	conf/cassandra.yaml
#	src/java/org/apache/cassandra/config/Config.java
#	src/java/org/apache/cassandra/config/DatabaseDescriptor.java
#	src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
#	src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
#	src/java/org/apache/cassandra/db/view/View.java
#	test/unit/org/apache/cassandra/cql3/ViewTest.java
#	test/unit/org/apache/cassandra/index/sasi/SASICQLTest.java
This commit is contained in:
Andrés de la Peña 2019-02-19 15:08:10 +00:00
commit 094689acf1
13 changed files with 178 additions and 15 deletions

View File

@ -349,6 +349,7 @@
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)
@ -390,7 +391,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)
* MigrationManager attempts to pull schema from different major version nodes (CASSANDRA-14928)
* Returns null instead of NaN or Infinity in JSON strings (CASSANDRA-14377)

View File

@ -210,7 +210,11 @@ Upgrading
See CASSANDRA-14358 for details.
- repair_session_space_in_mb setting has been added to cassandra.yaml to allow operators to reduce
merkle tree size if repair is creating too much heap pressure. The repair_session_max_tree_depth
setting added in 3.0.19 and 3.11.5 is deprecated in favor of this setting. See CASSANDRA-14096
setting added in 3.0.19 and 3.11.5 is deprecated in favor of this setting. See CASSANDRA-14096
- The flags 'enable_materialized_views' and 'enable_sasi_indexes' in cassandra.yaml
have been set as false by default. Operators should modify them to allow the
creation of new views and SASI indexes, the existing ones will continue working.
See CASSANDRA-14866 for details.
Materialized Views
-------------------
@ -223,6 +227,17 @@ Materialized Views
to be NOT NULL, and no base primary key columns get automatically included in view definition. You have to
specify them explicitly now.
3.11.5
======
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
======

View File

@ -1075,14 +1075,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
# Enables creation of transiently replicated keyspaces on this node.
# Transient replication is experimental and is not recommended for production use.
#enable_transient_replication: 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
@ -1299,3 +1291,18 @@ repaired_data_tracking_for_partition_reads_enabled: false
# mismatches are less actionable than confirmed ones.
report_unconfirmed_repaired_data_mismatches: false
#########################
# EXPERIMENTAL FEATURES #
#########################
# Enables materialized view creation on this node.
# Materialized views are considered experimental and are not recommended for production use.
enable_materialized_views: false
# Enables SASI index creation on this node.
# SASI indexes are considered experimental and are not recommended for production use.
enable_sasi_indexes: false
# Enables creation of transiently replicated keyspaces on this node.
# Transient replication is experimental and is not recommended for production use.
enable_transient_replication: false

View File

@ -354,10 +354,12 @@ public class Config
public boolean enable_user_defined_functions = false;
public boolean enable_scripted_user_defined_functions = false;
public boolean enable_materialized_views = true;
public boolean enable_materialized_views = false;
public boolean enable_transient_replication = false;
public boolean enable_sasi_indexes = false;
/**
* Optionally disable asynchronous UDF execution.
* Disabling asynchronous UDF execution also implicitly disables the security-manager!

View File

@ -2547,11 +2547,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 boolean isTransientReplicationEnabled()
{
return conf.enable_transient_replication;

View File

@ -19,11 +19,13 @@ package org.apache.cassandra.cql3.statements.schema;
import java.util.*;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.apache.cassandra.audit.AuditLogContext;
import org.apache.cassandra.audit.AuditLogEntryType;
import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLStatement;
import org.apache.cassandra.cql3.ColumnIdentifier;
import org.apache.cassandra.cql3.QualifiedName;
@ -31,6 +33,7 @@ import org.apache.cassandra.cql3.statements.schema.IndexTarget.Type;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.marshal.MapType;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.index.sasi.SASIIndex;
import org.apache.cassandra.schema.*;
import org.apache.cassandra.schema.Keyspaces.KeyspacesDiff;
import org.apache.cassandra.service.ClientState;
@ -68,6 +71,9 @@ public final class CreateIndexStatement extends AlterSchemaStatement
{
attrs.validate();
if (attrs.isCustom && attrs.customClass.equals(SASIIndex.class.getName()) && !DatabaseDescriptor.getEnableSASIIndexes())
throw new InvalidRequestException("SASI indexes are disabled. Enable in cassandra.yaml to use.");
KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);
if (null == keyspace)
throw ire("Keyspace '%s' doesn't exist", keyspaceName);
@ -135,6 +141,15 @@ public final class CreateIndexStatement extends AlterSchemaStatement
return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.tables.withSwapped(newTable)));
}
@Override
Set<String> clientWarnings(KeyspacesDiff diff)
{
if (attrs.isCustom && attrs.customClass.equals(SASIIndex.class.getName()))
return ImmutableSet.of(SASIIndex.USAGE_WARNING);
return ImmutableSet.of();
}
private void validateIndexTarget(TableMetadata table, IndexTarget target)
{
ColumnMetadata column = table.getColumn(target.column);

View File

@ -31,9 +31,9 @@ import org.apache.cassandra.cql3.restrictions.StatementRestrictions;
import org.apache.cassandra.cql3.selection.RawSelector;
import org.apache.cassandra.cql3.selection.Selectable;
import org.apache.cassandra.cql3.statements.StatementType;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.ReversedType;
import org.apache.cassandra.db.view.View;
import org.apache.cassandra.exceptions.AlreadyExistsException;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.schema.*;
@ -98,7 +98,7 @@ public final class CreateViewStatement extends AlterSchemaStatement
public Keyspaces apply(Keyspaces schema)
{
if (!DatabaseDescriptor.enableMaterializedViews())
if (!DatabaseDescriptor.getEnableMaterializedViews())
throw ire("Materialized views are disabled. Enable in cassandra.yaml to use.");
/*
@ -337,7 +337,7 @@ public final class CreateViewStatement extends AlterSchemaStatement
@Override
Set<String> clientWarnings(KeyspacesDiff diff)
{
return ImmutableSet.of("Materialized views are experimental and are not recommended for production use.");
return ImmutableSet.of(View.USAGE_WARNING);
}
@Override

View File

@ -45,6 +45,8 @@ import org.slf4j.LoggerFactory;
*/
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;

View File

@ -62,6 +62,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,

View File

@ -40,3 +40,5 @@ row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size_in_mb: 16
enable_user_defined_functions: true
enable_scripted_user_defined_functions: true
enable_sasi_indexes: true
enable_materialized_views: true

View File

@ -48,3 +48,5 @@ prepared_statements_cache_size_mb: 1
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
stream_throughput_outbound_megabits_per_sec: 200000000
enable_sasi_indexes: true
enable_materialized_views: true

View File

@ -39,12 +39,15 @@ import com.datastax.driver.core.exceptions.InvalidQueryException;
import org.apache.cassandra.concurrent.SEPExecutor;
import org.apache.cassandra.concurrent.Stage;
import org.apache.cassandra.concurrent.StageManager;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.view.View;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.schema.ColumnMetadata;
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.service.ClientWarn;
import org.apache.cassandra.transport.ProtocolVersion;
import org.apache.cassandra.utils.FBUtilities;
@ -1392,4 +1395,52 @@ public class ViewTest extends CQLTester
testViewBuilderResume(i);
}
}
/**
* 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 * 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);
}
}
}

View File

@ -28,7 +28,11 @@ import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.SimpleStatement;
import org.junit.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 +82,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);
}
}
}