From dd892b0d8ab9604d19e2554bf487e66ed3582ce0 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 10 Jan 2024 19:17:48 +0300 Subject: [PATCH] code: Enable tablets if cluster feature is enabled If the TABLETS map is missing in the CREATE KEYSPACE statement the tablets are anyway enabled if the respective cluster feature is enabled. To opt-out keyspaces one may use TABLETS = { 'enabled': false } syntax. Signed-off-by: Pavel Emelyanov --- cql3/statements/ks_prop_defs.cc | 8 ++++---- cql3/statements/ks_prop_defs.hh | 2 +- test/topology_custom/test_tablets.py | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/cql3/statements/ks_prop_defs.cc b/cql3/statements/ks_prop_defs.cc index d8de9ee7c7..f87f86e12f 100644 --- a/cql3/statements/ks_prop_defs.cc +++ b/cql3/statements/ks_prop_defs.cc @@ -108,7 +108,7 @@ data_dictionary::storage_options ks_prop_defs::get_storage_options() const { return opts; } -std::optional ks_prop_defs::get_initial_tablets(const sstring& strategy_class) const { +std::optional ks_prop_defs::get_initial_tablets(const sstring& strategy_class, bool enabled_by_default) const { // FIXME -- this should be ignored somehow else if (locator::abstract_replication_strategy::to_qualified_class_name(strategy_class) != "org.apache.cassandra.locator.NetworkTopologyStrategy") { return std::nullopt; @@ -116,7 +116,7 @@ std::optional ks_prop_defs::get_initial_tablets(const sstring& strateg auto tablets_options = get_map(KW_TABLETS); if (!tablets_options) { - return std::nullopt; + return enabled_by_default ? std::optional(0) : std::nullopt; } std::optional ret; @@ -159,7 +159,7 @@ std::optional ks_prop_defs::get_replication_strategy_class() const { lw_shared_ptr ks_prop_defs::as_ks_metadata(sstring ks_name, const locator::token_metadata& tm, const gms::feature_service& feat) { auto sc = get_replication_strategy_class().value(); - std::optional initial_tablets = get_initial_tablets(sc); + std::optional initial_tablets = get_initial_tablets(sc, feat.tablets); auto options = prepare_options(sc, tm, get_replication_options(), initial_tablets); return data_dictionary::keyspace_metadata::new_keyspace(ks_name, sc, std::move(options), initial_tablets, get_boolean(KW_DURABLE_WRITES, true), get_storage_options()); @@ -171,7 +171,7 @@ lw_shared_ptr ks_prop_defs::as_ks_metadata_u auto sc = get_replication_strategy_class(); std::optional initial_tablets; if (sc) { - initial_tablets = get_initial_tablets(*sc); + initial_tablets = get_initial_tablets(*sc, old->initial_tablets().has_value()); options = prepare_options(*sc, tm, get_replication_options(), initial_tablets, old_options); } else { sc = old->strategy_name(); diff --git a/cql3/statements/ks_prop_defs.hh b/cql3/statements/ks_prop_defs.hh index d0882f2422..a7635dcb01 100644 --- a/cql3/statements/ks_prop_defs.hh +++ b/cql3/statements/ks_prop_defs.hh @@ -53,7 +53,7 @@ public: void validate(); std::map get_replication_options() const; std::optional get_replication_strategy_class() const; - std::optional get_initial_tablets(const sstring& strategy_class) const; + std::optional get_initial_tablets(const sstring& strategy_class, bool enabled_by_default) const; data_dictionary::storage_options get_storage_options() const; lw_shared_ptr as_ks_metadata(sstring ks_name, const locator::token_metadata&, const gms::feature_service&); lw_shared_ptr as_ks_metadata_update(lw_shared_ptr old, const locator::token_metadata&, const gms::feature_service&); diff --git a/test/topology_custom/test_tablets.py b/test/topology_custom/test_tablets.py index 27bbeaec4e..a88da5a37c 100644 --- a/test/topology_custom/test_tablets.py +++ b/test/topology_custom/test_tablets.py @@ -19,7 +19,7 @@ async def test_tablet_change_replication_vnode_to_tablets(manager: ManagerClient server = await manager.server_add(config=cfg) cql = manager.get_cql() - await cql.run_async("CREATE KEYSPACE test WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1};") + await cql.run_async("CREATE KEYSPACE test WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1} AND tablets = {'enabled': false};") with pytest.raises(InvalidRequest): await cql.run_async("ALTER KEYSPACE test WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1} AND tablets = {'initial': 1};") @@ -48,7 +48,7 @@ async def test_tablet_default_initialization(manager: ManagerClient): server = await manager.server_add(config=cfg) cql = manager.get_cql() - await cql.run_async("CREATE KEYSPACE test WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1} AND tablets = {'enabled': true};") + await cql.run_async("CREATE KEYSPACE test WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1};") res = await cql.run_async("SELECT * FROM system_schema.scylla_keyspaces WHERE keyspace_name = 'test'") assert res[0].initial_tablets == 0, "initial_tablets not configured" @@ -63,6 +63,19 @@ async def test_tablet_default_initialization(manager: ManagerClient): assert False, "tablets not allocated" +@pytest.mark.asyncio +async def test_tablet_explicit_disabling(manager: ManagerClient): + cfg = {'enable_user_defined_functions': False, + 'experimental_features': ['tablets', 'consistent-topology-changes']} + server = await manager.server_add(config=cfg) + + cql = manager.get_cql() + await cql.run_async("CREATE KEYSPACE test WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1} AND tablets = {'enabled': false};") + + res = await cql.run_async("SELECT * FROM system_schema.scylla_keyspaces WHERE keyspace_name = 'test'") + assert len(res) == 0, "tablets replication strategy turned on" + + @pytest.mark.asyncio async def test_tablet_change_initial_tablets(manager: ManagerClient): cfg = {'enable_user_defined_functions': False,