mirror of https://github.com/apache/cassandra
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:
commit
094689acf1
|
|
@ -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)
|
||||
|
|
|
|||
17
NEWS.txt
17
NEWS.txt
|
|
@ -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
|
||||
======
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue