db/config: introduce max_memory_for_unlimited_query_soft_limit and max_memory_for_unlimited_query_hard_limit
This pair of limits replace the old max_memory_for_unlimited_query one, which remains as an alias to the hard limit. The soft limit inherits the previous value of the limit (1MB), when this limit is reached a warning will be logged allowing the users to adjust their client codes without downtime. The hard limit starts out with a more permissive default of 100MB. When this is reached queries are aborted, the same behaviour as with the previous single limit. The idea is to allow clients a grace period for fixing their code, while at the same time protecting the database from the really bad queries.
This commit is contained in:
@@ -1282,7 +1282,7 @@ void database::register_connection_drop_notifier(netw::messaging_service& ms) {
|
||||
query_class_config database::make_query_class_config() {
|
||||
// Everything running in the statement group is considered a user query
|
||||
if (current_scheduling_group() == _dbcfg.statement_scheduling_group) {
|
||||
return query_class_config{_read_concurrency_sem, _cfg.max_memory_for_unlimited_query()};
|
||||
return query_class_config{_read_concurrency_sem, _cfg.max_memory_for_unlimited_query_hard_limit()};
|
||||
// Reads done on behalf of view update generation run in the streaming group
|
||||
} else if (current_scheduling_group() == _dbcfg.streaming_scheduling_group) {
|
||||
return query_class_config{_streaming_concurrency_sem, std::numeric_limits<uint64_t>::max()};
|
||||
|
||||
@@ -722,8 +722,12 @@ db::config::config(std::shared_ptr<db::extensions> exts)
|
||||
, max_clustering_key_restrictions_per_query(this, "max_clustering_key_restrictions_per_query", liveness::LiveUpdate, value_status::Used, 100,
|
||||
"Maximum number of distinct clustering key restrictions per query. This limit places a bound on the size of IN tuples, "
|
||||
"especially when multiple clustering key columns have IN restrictions. Increasing this value can result in server instability.")
|
||||
, max_memory_for_unlimited_query(this, "max_memory_for_unlimited_query", liveness::LiveUpdate, value_status::Used, size_t(1) << 20,
|
||||
"Maximum amount of memory a query, whose memory consumption is not naturally limited, is allowed to consume, e.g. non-paged and reverse queries.")
|
||||
, max_memory_for_unlimited_query_soft_limit(this, "max_memory_for_unlimited_query_soft_limit", liveness::LiveUpdate, value_status::Used, uint64_t(1) << 20,
|
||||
"Maximum amount of memory a query, whose memory consumption is not naturally limited, is allowed to consume, e.g. non-paged and reverse queries. "
|
||||
"This is the soft limit, there will be a warning logged for queries violating this limit.")
|
||||
, max_memory_for_unlimited_query_hard_limit(this, "max_memory_for_unlimited_query_hard_limit", "max_memory_for_unlimited_query", liveness::LiveUpdate, value_status::Used, (uint64_t(100) << 20),
|
||||
"Maximum amount of memory a query, whose memory consumption is not naturally limited, is allowed to consume, e.g. non-paged and reverse queries. "
|
||||
"This is the hard limit, queries violating this limit will be aborted.")
|
||||
, initial_sstable_loading_concurrency(this, "initial_sstable_loading_concurrency", value_status::Used, 4u,
|
||||
"Maximum amount of sstables to load in parallel during initialization. A higher number can lead to more memory consumption. You should not need to touch this")
|
||||
, enable_3_1_0_compatibility_mode(this, "enable_3_1_0_compatibility_mode", value_status::Used, false,
|
||||
|
||||
@@ -303,7 +303,8 @@ public:
|
||||
named_value<bool> abort_on_internal_error;
|
||||
named_value<uint32_t> max_partition_key_restrictions_per_query;
|
||||
named_value<uint32_t> max_clustering_key_restrictions_per_query;
|
||||
named_value<uint64_t> max_memory_for_unlimited_query;
|
||||
named_value<uint64_t> max_memory_for_unlimited_query_soft_limit;
|
||||
named_value<uint64_t> max_memory_for_unlimited_query_hard_limit;
|
||||
named_value<unsigned> initial_sstable_loading_concurrency;
|
||||
named_value<bool> enable_3_1_0_compatibility_mode;
|
||||
named_value<bool> enable_user_defined_functions;
|
||||
|
||||
@@ -2765,7 +2765,8 @@ SEASTAR_TEST_CASE(test_reversed_slice_with_empty_range_before_all_rows) {
|
||||
// See #6171
|
||||
SEASTAR_TEST_CASE(test_reversed_slice_with_many_clustering_ranges) {
|
||||
cql_test_config cfg;
|
||||
cfg.db_config->max_memory_for_unlimited_query(std::numeric_limits<uint64_t>::max());
|
||||
cfg.db_config->max_memory_for_unlimited_query_soft_limit(std::numeric_limits<uint64_t>::max());
|
||||
cfg.db_config->max_memory_for_unlimited_query_hard_limit(std::numeric_limits<uint64_t>::max());
|
||||
return do_with_cql_env_thread([] (cql_test_env& e) {
|
||||
e.execute_cql("CREATE TABLE test (pk int, ck int, v text, PRIMARY KEY (pk, ck));").get();
|
||||
auto id = e.prepare("INSERT INTO test (pk, ck, v) VALUES (?, ?, ?);").get0();
|
||||
|
||||
Reference in New Issue
Block a user