diff --git a/cql3/cql_config.hh b/cql3/cql_config.hh index e3d7f90521..69bc73b9c3 100644 --- a/cql3/cql_config.hh +++ b/cql3/cql_config.hh @@ -11,6 +11,7 @@ #pragma once #include "restrictions/restrictions_config.hh" +#include "cql3/restrictions/replication_restrictions.hh" #include "db/tri_mode_restriction.hh" #include "utils/updateable_value.hh" @@ -20,6 +21,7 @@ namespace cql3 { struct cql_config { restrictions::restrictions_config restrictions; + replication_restrictions replication_restrictions; utils::updateable_value select_internal_page_size; utils::updateable_value strict_allow_filtering; utils::updateable_value enable_parallelized_aggregation; @@ -28,6 +30,7 @@ struct cql_config { explicit cql_config(const db::config& cfg) : restrictions(cfg) + , replication_restrictions(cfg) , select_internal_page_size(cfg.select_internal_page_size) , strict_allow_filtering(cfg.strict_allow_filtering) , enable_parallelized_aggregation(cfg.enable_parallelized_aggregation) @@ -37,6 +40,7 @@ struct cql_config { struct default_tag{}; cql_config(default_tag) : restrictions(restrictions::restrictions_config::default_tag{}) + , replication_restrictions(replication_restrictions::default_tag{}) , select_internal_page_size(10000) , strict_allow_filtering(db::tri_mode_restriction(db::tri_mode_restriction_t::mode::WARN)) , enable_parallelized_aggregation(true) diff --git a/cql3/restrictions/replication_restrictions.hh b/cql3/restrictions/replication_restrictions.hh new file mode 100644 index 0000000000..52bb8afbc1 --- /dev/null +++ b/cql3/restrictions/replication_restrictions.hh @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2026-present ScyllaDB + */ + +/* + * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.1 + */ + +#pragma once + +#include "db/config.hh" +#include "utils/updateable_value.hh" + +namespace cql3 { + +struct replication_restrictions { + utils::updateable_value restrict_replication_simplestrategy; + utils::updateable_value>> replication_strategy_warn_list; + utils::updateable_value>> replication_strategy_fail_list; + utils::updateable_value minimum_replication_factor_fail_threshold; + utils::updateable_value minimum_replication_factor_warn_threshold; + utils::updateable_value maximum_replication_factor_fail_threshold; + utils::updateable_value maximum_replication_factor_warn_threshold; + + explicit replication_restrictions(const db::config& cfg) + : restrict_replication_simplestrategy(cfg.restrict_replication_simplestrategy) + , replication_strategy_warn_list(cfg.replication_strategy_warn_list) + , replication_strategy_fail_list(cfg.replication_strategy_fail_list) + , minimum_replication_factor_fail_threshold(cfg.minimum_replication_factor_fail_threshold) + , minimum_replication_factor_warn_threshold(cfg.minimum_replication_factor_warn_threshold) + , maximum_replication_factor_fail_threshold(cfg.maximum_replication_factor_fail_threshold) + , maximum_replication_factor_warn_threshold(cfg.maximum_replication_factor_warn_threshold) + {} + + struct default_tag{}; + replication_restrictions(default_tag) + : restrict_replication_simplestrategy(db::tri_mode_restriction(db::tri_mode_restriction_t::mode::FALSE)) + , replication_strategy_warn_list(std::vector>{}) + , replication_strategy_fail_list(std::vector>{}) + , minimum_replication_factor_fail_threshold(-1) + , minimum_replication_factor_warn_threshold(3) + , maximum_replication_factor_fail_threshold(-1) + , maximum_replication_factor_warn_threshold(-1) + {} +}; + +} // namespace cql3 diff --git a/cql3/statements/alter_keyspace_statement.cc b/cql3/statements/alter_keyspace_statement.cc index b149c8e6d5..030bc56520 100644 --- a/cql3/statements/alter_keyspace_statement.cc +++ b/cql3/statements/alter_keyspace_statement.cc @@ -27,6 +27,7 @@ #include "data_dictionary/data_dictionary.hh" #include "data_dictionary/keyspace_metadata.hh" #include "cql3/query_processor.hh" +#include "cql3/cql_config.hh" #include "cql3/statements/ks_prop_defs.hh" #include "create_keyspace_statement.hh" #include "gms/feature_service.hh" @@ -267,7 +268,7 @@ cql3::statements::alter_keyspace_statement::prepare(data_dictionary::database db future<::shared_ptr> cql3::statements::alter_keyspace_statement::execute(query_processor& qp, service::query_state& state, const query_options& options, std::optional guard) const { - std::vector warnings = check_against_restricted_replication_strategies(qp, keyspace(), *_attrs, qp.get_cql_stats()); + std::vector warnings = check_against_restricted_replication_strategies(qp, keyspace(), *_attrs, qp.get_cql_stats(), qp.get_cql_config().replication_restrictions); return schema_altering_statement::execute(qp, state, options, std::move(guard)).then([warnings = std::move(warnings)] (::shared_ptr msg) { for (const auto& warning : warnings) { msg->add_warning(warning); diff --git a/cql3/statements/create_keyspace_statement.cc b/cql3/statements/create_keyspace_statement.cc index e2a7b2f3f9..da710226f0 100644 --- a/cql3/statements/create_keyspace_statement.cc +++ b/cql3/statements/create_keyspace_statement.cc @@ -20,6 +20,7 @@ #include "service/migration_manager.hh" #include "service/storage_proxy.hh" #include "cql3/query_processor.hh" +#include "cql3/cql_config.hh" #include "db/config.hh" #include "gms/feature_service.hh" #include "replica/database.hh" @@ -188,7 +189,8 @@ std::vector check_against_restricted_replication_strategies( query_processor& qp, const sstring& keyspace, const ks_prop_defs& attrs, - cql_stats& stats) + cql_stats& stats, + const cql3::replication_restrictions& rr) { if (!attrs.get_replication_strategy_class()) { return {}; @@ -201,11 +203,11 @@ std::vector check_against_restricted_replication_strategies( locator::abstract_replication_strategy::to_qualified_class_name( *attrs.get_replication_strategy_class()), params, qp.db().real_database().get_token_metadata().get_topology())->get_type(); - auto rs_warn_list = qp.db().get_config().replication_strategy_warn_list(); - auto rs_fail_list = qp.db().get_config().replication_strategy_fail_list(); + auto rs_warn_list = rr.replication_strategy_warn_list(); + auto rs_fail_list = rr.replication_strategy_fail_list(); if (replication_strategy == locator::replication_strategy_type::simple) { - if (auto simple_strategy_restriction = qp.db().get_config().restrict_replication_simplestrategy(); + if (auto simple_strategy_restriction = rr.restrict_replication_simplestrategy(); simple_strategy_restriction == db::tri_mode_restriction_t::mode::TRUE) { rs_fail_list.emplace_back(locator::replication_strategy_type::simple); } else if (simple_strategy_restriction == db::tri_mode_restriction_t::mode::WARN) { @@ -251,7 +253,7 @@ std::vector check_against_restricted_replication_strategies( } if (rf > 0) { - if (auto min_fail = qp.proxy().data_dictionary().get_config().minimum_replication_factor_fail_threshold(); + if (auto min_fail = rr.minimum_replication_factor_fail_threshold(); min_fail >= 0 && rf < min_fail) { ++stats.minimum_replication_factor_fail_violations; throw exceptions::configuration_exception(format( @@ -259,9 +261,9 @@ std::vector check_against_restricted_replication_strategies( "configuration setting of minimum_replication_factor_fail_threshold={}. Please " "increase replication factor, or lower minimum_replication_factor_fail_threshold " "set in the configuration.", opt.first, rf, - qp.proxy().data_dictionary().get_config().minimum_replication_factor_fail_threshold())); + rr.minimum_replication_factor_fail_threshold())); } - else if (auto max_fail = qp.proxy().data_dictionary().get_config().maximum_replication_factor_fail_threshold(); + else if (auto max_fail = rr.maximum_replication_factor_fail_threshold(); max_fail >= 0 && rf > max_fail) { ++stats.maximum_replication_factor_fail_violations; throw exceptions::configuration_exception(format( @@ -269,23 +271,23 @@ std::vector check_against_restricted_replication_strategies( "configuration setting of maximum_replication_factor_fail_threshold={}. Please " "decrease replication factor, or increase maximum_replication_factor_fail_threshold " "set in the configuration.", opt.first, rf, - qp.proxy().data_dictionary().get_config().maximum_replication_factor_fail_threshold())); + rr.maximum_replication_factor_fail_threshold())); } - else if (auto min_warn = qp.proxy().data_dictionary().get_config().minimum_replication_factor_warn_threshold(); + else if (auto min_warn = rr.minimum_replication_factor_warn_threshold(); min_warn >= 0 && rf < min_warn) { ++stats.minimum_replication_factor_warn_violations; warnings.push_back(format("Using Replication Factor {}={} lower than the " "minimum_replication_factor_warn_threshold={} is not recommended.", opt.first, rf, - qp.proxy().data_dictionary().get_config().minimum_replication_factor_warn_threshold())); + rr.minimum_replication_factor_warn_threshold())); } - else if (auto max_warn = qp.proxy().data_dictionary().get_config().maximum_replication_factor_warn_threshold(); + else if (auto max_warn = rr.maximum_replication_factor_warn_threshold(); max_warn >= 0 && rf > max_warn) { ++stats.maximum_replication_factor_warn_violations; warnings.push_back(format("Using Replication Factor {}={} greater than the " "maximum_replication_factor_warn_threshold={} is not recommended.", opt.first, rf, - qp.proxy().data_dictionary().get_config().maximum_replication_factor_warn_threshold())); + rr.maximum_replication_factor_warn_threshold())); } } } catch (std::invalid_argument&) { @@ -297,7 +299,7 @@ std::vector check_against_restricted_replication_strategies( future<::shared_ptr> create_keyspace_statement::execute(query_processor& qp, service::query_state& state, const query_options& options, std::optional guard) const { - std::vector warnings = check_against_restricted_replication_strategies(qp, keyspace(), *_attrs, qp.get_cql_stats()); + std::vector warnings = check_against_restricted_replication_strategies(qp, keyspace(), *_attrs, qp.get_cql_stats(), qp.get_cql_config().replication_restrictions); return schema_altering_statement::execute(qp, state, options, std::move(guard)).then([warnings = std::move(warnings)] (::shared_ptr msg) { for (const auto& warning : warnings) { msg->add_warning(warning); diff --git a/cql3/statements/create_keyspace_statement.hh b/cql3/statements/create_keyspace_statement.hh index 746e4e4c4b..b5b5e31529 100644 --- a/cql3/statements/create_keyspace_statement.hh +++ b/cql3/statements/create_keyspace_statement.hh @@ -30,6 +30,7 @@ class keyspace_metadata; namespace cql3 { class query_processor; +struct replication_restrictions; namespace statements { @@ -88,7 +89,8 @@ std::vector check_against_restricted_replication_strategies( query_processor& qp, const sstring& keyspace, const ks_prop_defs& attrs, - cql_stats& stats); + cql_stats& stats, + const cql3::replication_restrictions& rr); }