mirror of https://github.com/apache/cassandra
Disable the deprecated keyspace/table thresholds and convert them to guardrails
patch by Daniel Jatnieks; reviewed by Andrés de la Peña and Brandon Williams for CASSANDRA-18617
This commit is contained in:
parent
903857b4ef
commit
aac070681b
|
|
@ -1,4 +1,5 @@
|
|||
5.0
|
||||
* Disable the deprecated keyspace/table thresholds and convert them to guardrails (CASSANDRA-18617)
|
||||
* Deprecate CloudstackSnitch and remove duplicate code in snitches (CASSANDRA-18438)
|
||||
* Add support for vectors in UDFs (CASSANDRA-18613)
|
||||
* Improve vector value validation errors (CASSANDRA-18652)
|
||||
|
|
|
|||
2
NEWS.txt
2
NEWS.txt
|
|
@ -439,7 +439,7 @@ Deprecation
|
|||
No change of functionality in the new one, only name change for clarity in regards to units and to follow naming
|
||||
standartization.
|
||||
- The properties `keyspace_count_warn_threshold` and `table_count_warn_threshold` in cassandra.yaml have been
|
||||
deprecated in favour of the new `guardrails.keyspaces` and `guardrails.tables` properties and will be removed
|
||||
deprecated in favour of the new `keyspaces_warn_threshold` and `tables_warn_threshold` properties and will be removed
|
||||
in a subsequent major version. This also affects the setters and getters for those properties in the JMX MBean
|
||||
`org.apache.cassandra.db:type=StorageService`, which are equally deprecated in favour of the analogous methods
|
||||
in the JMX MBean `org.apache.cassandra.db:type=Guardrails`. See CASSANDRA-17195 for further details.
|
||||
|
|
|
|||
|
|
@ -1685,13 +1685,6 @@ repaired_data_tracking_for_partition_reads_enabled: false
|
|||
# mismatches are less actionable than confirmed ones.
|
||||
report_unconfirmed_repaired_data_mismatches: false
|
||||
|
||||
# Having many tables and/or keyspaces negatively affects performance of many operations in the
|
||||
# cluster. When the number of tables/keyspaces in the cluster exceeds the following thresholds
|
||||
# a client warning will be sent back to the user when creating a table or keyspace.
|
||||
# As of cassandra 4.1, these properties are deprecated in favor of keyspaces_warn_threshold and tables_warn_threshold
|
||||
# table_count_warn_threshold: 150
|
||||
# keyspace_count_warn_threshold: 40
|
||||
|
||||
# configure the read and write consistency levels for modifications to auth tables
|
||||
# auth_read_consistency_level: LOCAL_QUORUM
|
||||
# auth_write_consistency_level: EACH_QUORUM
|
||||
|
|
|
|||
|
|
@ -17,8 +17,11 @@
|
|||
*/
|
||||
package org.apache.cassandra.auth;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import org.apache.cassandra.config.CassandraRelevantProperties;
|
||||
import org.apache.cassandra.cql3.statements.schema.CreateTableStatement;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
|
|
@ -55,6 +58,7 @@ public final class AuthKeyspace
|
|||
public static final String ROLE_PERMISSIONS = "role_permissions";
|
||||
public static final String RESOURCE_ROLE_INDEX = "resource_role_permissons_index";
|
||||
public static final String NETWORK_PERMISSIONS = "network_permissions";
|
||||
public static final Set<String> TABLE_NAMES = ImmutableSet.of(ROLES, ROLE_MEMBERS, ROLE_PERMISSIONS, RESOURCE_ROLE_INDEX, NETWORK_PERMISSIONS);
|
||||
|
||||
public static final long SUPERUSER_SETUP_DELAY = SUPERUSER_SETUP_DELAY_MS.getLong();
|
||||
|
||||
|
|
|
|||
|
|
@ -826,18 +826,15 @@ public class Config
|
|||
isClientMode = clientMode;
|
||||
}
|
||||
|
||||
@Deprecated // this warning threshold will be replaced by an equivalent guardrail
|
||||
public volatile int table_count_warn_threshold = 150;
|
||||
@Deprecated // this warning threshold will be replaced by an equivalent guardrail
|
||||
public volatile int keyspace_count_warn_threshold = 40;
|
||||
|
||||
public volatile int consecutive_message_errors_threshold = 1;
|
||||
|
||||
public volatile SubnetGroups client_error_reporting_exclusions = new SubnetGroups();
|
||||
public volatile SubnetGroups internode_error_reporting_exclusions = new SubnetGroups();
|
||||
|
||||
@Replaces(oldName = "keyspace_count_warn_threshold", converter = Converters.KEYSPACE_COUNT_THRESHOLD_TO_GUARDRAIL, deprecated = true)
|
||||
public volatile int keyspaces_warn_threshold = -1;
|
||||
public volatile int keyspaces_fail_threshold = -1;
|
||||
@Replaces(oldName = "table_count_warn_threshold", converter = Converters.TABLE_COUNT_THRESHOLD_TO_GUARDRAIL, deprecated = true)
|
||||
public volatile int tables_warn_threshold = -1;
|
||||
public volatile int tables_fail_threshold = -1;
|
||||
public volatile int columns_per_table_warn_threshold = -1;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ package org.apache.cassandra.config;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.cassandra.schema.SchemaConstants;
|
||||
|
||||
import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.MEBIBYTES_PER_SECOND;
|
||||
|
||||
/**
|
||||
|
|
@ -117,7 +119,13 @@ public enum Converters
|
|||
*/
|
||||
MEGABITS_TO_BYTES_PER_SECOND_DATA_RATE(Integer.class, DataRateSpec.LongBytesPerSecondBound.class,
|
||||
i -> DataRateSpec.LongBytesPerSecondBound.megabitsPerSecondInBytesPerSecond(i),
|
||||
o -> o == null ? null : o.toMegabitsPerSecondAsInt());
|
||||
o -> o == null ? null : o.toMegabitsPerSecondAsInt()),
|
||||
KEYSPACE_COUNT_THRESHOLD_TO_GUARDRAIL(int.class, int.class,
|
||||
i -> i - SchemaConstants.getLocalAndReplicatedSystemKeyspaceNames().size(),
|
||||
o -> o == null ? null : o + SchemaConstants.getLocalAndReplicatedSystemKeyspaceNames().size()),
|
||||
TABLE_COUNT_THRESHOLD_TO_GUARDRAIL(int.class, int.class,
|
||||
i -> i - SchemaConstants.getLocalAndReplicatedSystemTableNames().size(),
|
||||
o -> o == null ? null : o + SchemaConstants.getLocalAndReplicatedSystemTableNames().size());
|
||||
private final Class<?> oldType;
|
||||
private final Class<?> newType;
|
||||
private final Function<Object, Object> convert;
|
||||
|
|
|
|||
|
|
@ -4195,30 +4195,6 @@ public class DatabaseDescriptor
|
|||
conf.auto_optimise_preview_repair_streams = enabled;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int tableCountWarnThreshold()
|
||||
{
|
||||
return conf.table_count_warn_threshold;
|
||||
}
|
||||
|
||||
@Deprecated // this warning threshold will be replaced by an equivalent guardrail
|
||||
public static void setTableCountWarnThreshold(int value)
|
||||
{
|
||||
conf.table_count_warn_threshold = value;
|
||||
}
|
||||
|
||||
@Deprecated // this warning threshold will be replaced by an equivalent guardrail
|
||||
public static int keyspaceCountWarnThreshold()
|
||||
{
|
||||
return conf.keyspace_count_warn_threshold;
|
||||
}
|
||||
|
||||
@Deprecated // this warning threshold will be replaced by an equivalent guardrail
|
||||
public static void setKeyspaceCountWarnThreshold(int value)
|
||||
{
|
||||
conf.keyspace_count_warn_threshold = value;
|
||||
}
|
||||
|
||||
@Deprecated // this warning threshold will be replaced by an equivalent guardrail
|
||||
public static ConsistencyLevel getAuthWriteConsistencyLevel()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import org.apache.cassandra.auth.DataResource;
|
|||
import org.apache.cassandra.auth.FunctionResource;
|
||||
import org.apache.cassandra.auth.IResource;
|
||||
import org.apache.cassandra.auth.Permission;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.CQLStatement;
|
||||
import org.apache.cassandra.db.guardrails.Guardrails;
|
||||
import org.apache.cassandra.exceptions.AlreadyExistsException;
|
||||
|
|
@ -124,22 +123,6 @@ public final class CreateKeyspaceStatement extends AlterSchemaStatement
|
|||
Guardrails.keyspaces.guard(Schema.instance.getUserKeyspaces().size() + 1, keyspaceName, false, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
Set<String> clientWarnings(KeyspacesDiff diff)
|
||||
{
|
||||
// this threshold is deprecated, it will be replaced by the guardrail used in #validate(ClientState)
|
||||
int keyspaceCount = Schema.instance.getKeyspaces().size();
|
||||
if (keyspaceCount > DatabaseDescriptor.keyspaceCountWarnThreshold())
|
||||
{
|
||||
String msg = String.format("Cluster already contains %d keyspaces. Having a large number of keyspaces will significantly slow down schema dependent cluster operations.",
|
||||
keyspaceCount);
|
||||
logger.warn(msg);
|
||||
clientWarnings.add(msg);
|
||||
}
|
||||
|
||||
return clientWarnings;
|
||||
}
|
||||
|
||||
public static final class Raw extends CQLStatement.Raw
|
||||
{
|
||||
public final String keyspaceName;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import org.apache.cassandra.audit.AuditLogEntryType;
|
|||
import org.apache.cassandra.auth.DataResource;
|
||||
import org.apache.cassandra.auth.IResource;
|
||||
import org.apache.cassandra.auth.Permission;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.*;
|
||||
import org.apache.cassandra.cql3.functions.masking.ColumnMask;
|
||||
import org.apache.cassandra.db.Keyspace;
|
||||
|
|
@ -426,22 +425,6 @@ public final class CreateTableStatement extends AlterSchemaStatement
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> clientWarnings(KeyspacesDiff diff)
|
||||
{
|
||||
// this threshold is deprecated, it will be replaced by the guardrail used in #validate(ClientState)
|
||||
int tableCount = Schema.instance.getNumberOfTables();
|
||||
if (tableCount > DatabaseDescriptor.tableCountWarnThreshold())
|
||||
{
|
||||
String msg = String.format("Cluster already contains %d tables in %d keyspaces. Having a large number of tables will significantly slow down schema dependent cluster operations.",
|
||||
tableCount,
|
||||
Schema.instance.getKeyspaces().size());
|
||||
logger.warn(msg);
|
||||
return ImmutableSet.of(msg);
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
private static class DefaultNames
|
||||
{
|
||||
private static final String DEFAULT_CLUSTERING_NAME = "column";
|
||||
|
|
|
|||
|
|
@ -191,6 +191,12 @@ public final class SystemKeyspace
|
|||
BUILT_VIEWS, PREPARED_STATEMENTS, REPAIRS, TOP_PARTITIONS, LEGACY_PEERS, LEGACY_PEER_EVENTS,
|
||||
LEGACY_TRANSFERRED_RANGES, LEGACY_AVAILABLE_RANGES, LEGACY_SIZE_ESTIMATES, LEGACY_SSTABLE_ACTIVITY);
|
||||
|
||||
public static final Set<String> TABLE_NAMES = ImmutableSet.of(
|
||||
BATCHES, PAXOS, PAXOS_REPAIR_HISTORY, BUILT_INDEXES, LOCAL, PEERS_V2, PEER_EVENTS_V2,
|
||||
COMPACTION_HISTORY, SSTABLE_ACTIVITY_V2, TABLE_ESTIMATES, AVAILABLE_RANGES_V2, TRANSFERRED_RANGES_V2, VIEW_BUILDS_IN_PROGRESS,
|
||||
BUILT_VIEWS, PREPARED_STATEMENTS, REPAIRS, TOP_PARTITIONS, LEGACY_PEERS, LEGACY_PEER_EVENTS,
|
||||
LEGACY_TRANSFERRED_RANGES, LEGACY_AVAILABLE_RANGES, LEGACY_SIZE_ESTIMATES, LEGACY_SSTABLE_ACTIVITY);
|
||||
|
||||
public static final TableMetadata Batches =
|
||||
parse(BATCHES,
|
||||
"batches awaiting replay",
|
||||
|
|
|
|||
|
|
@ -27,7 +27,10 @@ import java.util.regex.Pattern;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import org.apache.cassandra.auth.AuthKeyspace;
|
||||
import org.apache.cassandra.db.Digest;
|
||||
import org.apache.cassandra.db.SystemKeyspace;
|
||||
import org.apache.cassandra.tracing.TraceKeyspace;
|
||||
|
||||
/**
|
||||
* When adding new String keyspace names here, double check if it needs to be added to PartitionDenylist.canDenylistKeyspace
|
||||
|
|
@ -126,4 +129,28 @@ public final class SchemaConstants
|
|||
{
|
||||
return Sets.union(Sets.union(LOCAL_SYSTEM_KEYSPACE_NAMES, REPLICATED_SYSTEM_KEYSPACE_NAMES), VIRTUAL_SYSTEM_KEYSPACE_NAMES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of local and replicated system keyspace names
|
||||
* @return all local and replicated system keyspace names
|
||||
*/
|
||||
public static Set<String> getLocalAndReplicatedSystemKeyspaceNames()
|
||||
{
|
||||
return Sets.union(LOCAL_SYSTEM_KEYSPACE_NAMES, REPLICATED_SYSTEM_KEYSPACE_NAMES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of all local and replicated system table names
|
||||
* @return all local and replicated system table names
|
||||
*/
|
||||
public static Set<String> getLocalAndReplicatedSystemTableNames()
|
||||
{
|
||||
return ImmutableSet.<String>builder()
|
||||
.addAll(SystemKeyspace.TABLE_NAMES)
|
||||
.addAll(SchemaKeyspaceTables.ALL)
|
||||
.addAll(TraceKeyspace.TABLE_NAMES)
|
||||
.addAll(AuthKeyspace.TABLE_NAMES)
|
||||
.addAll(SystemDistributedKeyspace.TABLE_NAMES)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import java.util.UUID;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
|
@ -93,6 +94,8 @@ public final class SystemDistributedKeyspace
|
|||
|
||||
public static final String PARTITION_DENYLIST_TABLE = "partition_denylist";
|
||||
|
||||
public static final Set<String> TABLE_NAMES = ImmutableSet.of(REPAIR_HISTORY, PARENT_REPAIR_HISTORY, VIEW_BUILD_STATUS, PARTITION_DENYLIST_TABLE);
|
||||
|
||||
private static final TableMetadata RepairHistory =
|
||||
parse(REPAIR_HISTORY,
|
||||
"Repair history",
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ import org.apache.cassandra.concurrent.Stage;
|
|||
import org.apache.cassandra.config.CassandraRelevantProperties;
|
||||
import org.apache.cassandra.config.Config;
|
||||
import org.apache.cassandra.config.Config.PaxosStatePurging;
|
||||
import org.apache.cassandra.config.Converters;
|
||||
import org.apache.cassandra.config.DataStorageSpec;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.config.DurationSpec;
|
||||
|
|
@ -6970,7 +6971,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
@Deprecated
|
||||
public int getTableCountWarnThreshold()
|
||||
{
|
||||
return DatabaseDescriptor.tableCountWarnThreshold();
|
||||
return (int) Converters.TABLE_COUNT_THRESHOLD_TO_GUARDRAIL.unconvert(Guardrails.instance.getTablesWarnThreshold());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
|
@ -6979,13 +6980,14 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
if (value < 0)
|
||||
throw new IllegalStateException("Table count warn threshold should be positive, not "+value);
|
||||
logger.info("Changing table count warn threshold from {} to {}", getTableCountWarnThreshold(), value);
|
||||
DatabaseDescriptor.setTableCountWarnThreshold(value);
|
||||
Guardrails.instance.setTablesThreshold((int) Converters.TABLE_COUNT_THRESHOLD_TO_GUARDRAIL.convert(value),
|
||||
Guardrails.instance.getTablesFailThreshold());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getKeyspaceCountWarnThreshold()
|
||||
{
|
||||
return DatabaseDescriptor.keyspaceCountWarnThreshold();
|
||||
return (int) Converters.KEYSPACE_COUNT_THRESHOLD_TO_GUARDRAIL.unconvert(Guardrails.instance.getKeyspacesWarnThreshold());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
|
@ -6994,7 +6996,8 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
if (value < 0)
|
||||
throw new IllegalStateException("Keyspace count warn threshold should be positive, not "+value);
|
||||
logger.info("Changing keyspace count warn threshold from {} to {}", getKeyspaceCountWarnThreshold(), value);
|
||||
DatabaseDescriptor.setKeyspaceCountWarnThreshold(value);
|
||||
Guardrails.instance.setKeyspacesThreshold((int) Converters.KEYSPACE_COUNT_THRESHOLD_TO_GUARDRAIL.convert(value),
|
||||
Guardrails.instance.getKeyspacesFailThreshold());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import java.net.InetAddress;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import org.apache.cassandra.config.CassandraRelevantProperties;
|
||||
import org.apache.cassandra.cql3.statements.schema.CreateTableStatement;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
|
|
@ -66,6 +68,7 @@ public final class TraceKeyspace
|
|||
|
||||
public static final String SESSIONS = "sessions";
|
||||
public static final String EVENTS = "events";
|
||||
public static final Set<String> TABLE_NAMES = ImmutableSet.of(SESSIONS, EVENTS);
|
||||
|
||||
private static final TableMetadata Sessions =
|
||||
parse(SESSIONS,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.cassandra.auth.AuthKeyspace;
|
||||
import org.apache.cassandra.db.SystemKeyspace;
|
||||
import org.apache.cassandra.schema.KeyspaceMetadata;
|
||||
import org.apache.cassandra.schema.Schema;
|
||||
import org.apache.cassandra.schema.SchemaConstants;
|
||||
import org.apache.cassandra.schema.SchemaKeyspaceTables;
|
||||
import org.apache.cassandra.schema.SystemDistributedKeyspace;
|
||||
import org.apache.cassandra.tracing.TraceKeyspace;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class SystemKeyspaceTablesNamesTest extends CQLTester
|
||||
{
|
||||
@BeforeClass
|
||||
public static void setUp()
|
||||
{
|
||||
// Needed for distributed keyspaces
|
||||
requireNetwork();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemKeyspaceTableNames()
|
||||
{
|
||||
assertExpectedTablesInKeyspace(SchemaConstants.SYSTEM_KEYSPACE_NAME,
|
||||
"SystemKeyspace.TABLE_NAMES",
|
||||
SystemKeyspace.TABLE_NAMES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemSchemaKeyspaceTableNames()
|
||||
{
|
||||
assertExpectedTablesInKeyspace(SchemaConstants.SCHEMA_KEYSPACE_NAME,
|
||||
"SchemaKeyspaceTables.ALL",
|
||||
ImmutableSet.copyOf(SchemaKeyspaceTables.ALL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemTraceKeyspaceTableNames()
|
||||
{
|
||||
assertExpectedTablesInKeyspace(SchemaConstants.TRACE_KEYSPACE_NAME,
|
||||
"TraceKeyspace.TABLE_NAMES",
|
||||
TraceKeyspace.TABLE_NAMES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemAuthKeyspaceTableNames()
|
||||
{
|
||||
assertExpectedTablesInKeyspace(SchemaConstants.AUTH_KEYSPACE_NAME,
|
||||
"AuthKeyspace.TABLE_NAMES",
|
||||
AuthKeyspace.TABLE_NAMES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemDistributedKeyspaceTableNames()
|
||||
{
|
||||
assertExpectedTablesInKeyspace(SchemaConstants.DISTRIBUTED_KEYSPACE_NAME,
|
||||
"SystemDistributedKeyspace.TABLE_NAMES",
|
||||
SystemDistributedKeyspace.TABLE_NAMES);
|
||||
}
|
||||
|
||||
private static void assertExpectedTablesInKeyspace(String keyspaceName, String expectedTableSource, Set<String> expectedTables)
|
||||
{
|
||||
KeyspaceMetadata keyspace = Schema.instance.getKeyspaceMetadata(keyspaceName);
|
||||
assertNotNull(keyspace);
|
||||
Set<String> actualKeyspaceTables = keyspace.tables.stream().map(t -> t.name).collect(Collectors.toSet());
|
||||
|
||||
Sets.SetView<String> diff = Sets.difference(actualKeyspaceTables, expectedTables);
|
||||
assertTrue(format("The following tables are missing from %s: %s", expectedTableSource, diff), diff.isEmpty());
|
||||
|
||||
diff = Sets.difference(expectedTables, actualKeyspaceTables);
|
||||
assertTrue(format("The following tables are in %s but should not be: %s", expectedTableSource, diff), diff.isEmpty());
|
||||
}
|
||||
}
|
||||
|
|
@ -18,9 +18,15 @@
|
|||
|
||||
package org.apache.cassandra.db.guardrails;
|
||||
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.cassandra.config.Converters;
|
||||
import org.apache.cassandra.schema.Schema;
|
||||
import org.awaitility.Awaitility;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
|
|
@ -48,8 +54,37 @@ public class GuardrailKeyspacesTest extends ThresholdTester
|
|||
return Schema.instance.getUserKeyspaces().size();
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterTest() throws Throwable
|
||||
{
|
||||
// CQLTester deletes keyspaces after tests, but does so asynchronously
|
||||
super.afterTest();
|
||||
|
||||
// Wait until only cql_test_keyspace remains
|
||||
Awaitility.await()
|
||||
.atMost(10, TimeUnit.MINUTES)
|
||||
.pollDelay(0, TimeUnit.MILLISECONDS)
|
||||
.pollInterval(10, TimeUnit.MILLISECONDS)
|
||||
.until(() -> Schema.instance.getUserKeyspaces().size() == 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateKeyspace() throws Throwable
|
||||
{
|
||||
assertCreateKeyspace();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateKeyspaceWithDeprecatedKeyspaceCountThreshold() throws Throwable
|
||||
{
|
||||
// Convert and set a deprecated threshold value based on the total number of keyspaces, not just user keyspaces
|
||||
int convertedValue = (int) Converters.KEYSPACE_COUNT_THRESHOLD_TO_GUARDRAIL.convert(Schema.instance.getKeyspaces().size());
|
||||
Guardrails.instance.setKeyspacesThreshold(convertedValue + 1, convertedValue + 2);
|
||||
|
||||
assertCreateKeyspace();
|
||||
}
|
||||
|
||||
private void assertCreateKeyspace() throws Throwable
|
||||
{
|
||||
// create keyspaces until hitting the two warn/fail thresholds
|
||||
String k1 = assertCreateKeyspaceValid();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ package org.apache.cassandra.db.guardrails;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.cassandra.config.Converters;
|
||||
import org.apache.cassandra.db.Keyspace;
|
||||
import org.apache.cassandra.schema.Schema;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
|
|
@ -45,11 +47,26 @@ public class GuardrailTablesTest extends ThresholdTester
|
|||
@Override
|
||||
protected long currentValue()
|
||||
{
|
||||
return Keyspace.open(keyspace()).getColumnFamilyStores().size();
|
||||
return Keyspace.open(KEYSPACE_PER_TEST).getColumnFamilyStores().size();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTable() throws Throwable
|
||||
public void testCreateTableWithGuardrailThreshold() throws Throwable
|
||||
{
|
||||
assertCreateTable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTableWithDeprecatedTableCountThreshold() throws Throwable
|
||||
{
|
||||
// Convert and set a deprecated threshold value based on the total number of tables, not just user tables
|
||||
int convertedValue = (int) Converters.TABLE_COUNT_THRESHOLD_TO_GUARDRAIL.convert(Schema.instance.getNumberOfTables());
|
||||
Guardrails.instance.setTablesThreshold(convertedValue + 1, TABLES_LIMIT_FAIL_THRESHOLD);
|
||||
|
||||
assertCreateTable();
|
||||
}
|
||||
|
||||
private void assertCreateTable() throws Throwable
|
||||
{
|
||||
// create tables until hitting the two warn/fail thresholds
|
||||
String t1 = assertCreateTableValid();
|
||||
|
|
@ -77,7 +94,7 @@ public class GuardrailTablesTest extends ThresholdTester
|
|||
@Override
|
||||
protected void dropTable(String tableName)
|
||||
{
|
||||
dropFormattedTable(format("DROP TABLE %s.%s", keyspace(), tableName));
|
||||
dropFormattedTable(format("DROP TABLE %s.%s", KEYSPACE_PER_TEST, tableName));
|
||||
}
|
||||
|
||||
private String assertCreateTableValid() throws Throwable
|
||||
|
|
@ -111,6 +128,6 @@ public class GuardrailTablesTest extends ThresholdTester
|
|||
|
||||
private String createTableQuery(String tableName)
|
||||
{
|
||||
return format("CREATE TABLE %s.%s (k1 int, v int, PRIMARY KEY((k1)))", keyspace(), tableName);
|
||||
return format("CREATE TABLE %s.%s (k1 int, v int, PRIMARY KEY((k1)))", KEYSPACE_PER_TEST, tableName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,23 +18,13 @@
|
|||
*/
|
||||
package org.apache.cassandra.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.CQLTester;
|
||||
import org.apache.cassandra.cql3.QueryOptions;
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.cassandra.exceptions.InvalidRequestException;
|
||||
import org.apache.cassandra.transport.Message;
|
||||
import org.apache.cassandra.transport.ProtocolVersion;
|
||||
import org.apache.cassandra.transport.SimpleClient;
|
||||
import org.apache.cassandra.transport.messages.QueryMessage;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class CreateTableValidationTest extends CQLTester
|
||||
|
|
@ -60,53 +50,6 @@ public class CreateTableValidationTest extends CQLTester
|
|||
createTable("CREATE TABLE %s (a int PRIMARY KEY, b int) WITH bloom_filter_fp_chance = 0.1");
|
||||
}
|
||||
|
||||
@Deprecated // these warning thresholds will be replaced by equivalent guardrails
|
||||
@Test
|
||||
public void testCreateKeyspaceTableWarning() throws IOException
|
||||
{
|
||||
requireNetwork();
|
||||
int tableCountWarn = DatabaseDescriptor.tableCountWarnThreshold();
|
||||
int keyspaceCountWarn = DatabaseDescriptor.keyspaceCountWarnThreshold();
|
||||
DatabaseDescriptor.setTableCountWarnThreshold(Schema.instance.getNumberOfTables());
|
||||
DatabaseDescriptor.setKeyspaceCountWarnThreshold(Schema.instance.getKeyspaces().size());
|
||||
|
||||
try (SimpleClient client = newSimpleClient(ProtocolVersion.CURRENT).connect(false))
|
||||
{
|
||||
String createKeyspace = "CREATE KEYSPACE createkswarning%d WITH REPLICATION={'class':'org.apache.cassandra.locator.NetworkTopologyStrategy','datacenter1':'2'}";
|
||||
QueryMessage query = new QueryMessage(String.format(createKeyspace, 1), QueryOptions.DEFAULT);
|
||||
Message.Response resp = client.execute(query);
|
||||
List<String> warns = resp.getWarnings();
|
||||
warns.removeIf(w -> w.contains("is higher than the number of nodes"));
|
||||
assertTrue(warns.size() > 0);
|
||||
assertTrue(warns.get(0).contains("Having a large number of keyspaces will significantly"));
|
||||
|
||||
DatabaseDescriptor.setKeyspaceCountWarnThreshold(Schema.instance.getKeyspaces().size() + 2);
|
||||
query = new QueryMessage(String.format(createKeyspace, 2), QueryOptions.DEFAULT);
|
||||
resp = client.execute(query);
|
||||
warns = resp.getWarnings();
|
||||
if (warns != null)
|
||||
warns.removeIf(w -> w.contains("is higher than the number of nodes"));
|
||||
assertTrue(warns == null || warns.isEmpty());
|
||||
|
||||
query = new QueryMessage(String.format("CREATE TABLE %s.%s (id int primary key, x int)", KEYSPACE, "test1"), QueryOptions.DEFAULT);
|
||||
resp = client.execute(query);
|
||||
warns = resp.getWarnings();
|
||||
warns.removeIf(w -> w.contains("is higher than the number of nodes"));
|
||||
assertTrue(warns.size() > 0);
|
||||
assertTrue(warns.get(0).contains("Having a large number of tables"));
|
||||
|
||||
DatabaseDescriptor.setTableCountWarnThreshold(Schema.instance.getNumberOfTables() + 1);
|
||||
query = new QueryMessage(String.format("CREATE TABLE %s.%s (id int primary key, x int)", KEYSPACE, "test2"), QueryOptions.DEFAULT);
|
||||
resp = client.execute(query);
|
||||
assertTrue(resp.getWarnings() == null || resp.getWarnings().isEmpty());
|
||||
}
|
||||
finally
|
||||
{
|
||||
DatabaseDescriptor.setTableCountWarnThreshold(tableCountWarn);
|
||||
DatabaseDescriptor.setKeyspaceCountWarnThreshold(keyspaceCountWarn);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTableOnSelectedClusteringColumn()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue