mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Merge pull request #58731 from rschu1ze/qc-quota
Query cache: Fix per-user quota
This commit is contained in:
commit
9146391e48
@ -25,6 +25,9 @@ public:
|
|||||||
/// Is the user allowed to write a new entry into the cache?
|
/// Is the user allowed to write a new entry into the cache?
|
||||||
virtual bool approveWrite(const UUID & user_id, size_t entry_size_in_bytes) const = 0;
|
virtual bool approveWrite(const UUID & user_id, size_t entry_size_in_bytes) const = 0;
|
||||||
|
|
||||||
|
/// Clears the policy contents
|
||||||
|
virtual void clear() = 0;
|
||||||
|
|
||||||
virtual ~ICachePolicyUserQuota() = default;
|
virtual ~ICachePolicyUserQuota() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,6 +41,7 @@ public:
|
|||||||
void increaseActual(const UUID & /*user_id*/, size_t /*entry_size_in_bytes*/) override {}
|
void increaseActual(const UUID & /*user_id*/, size_t /*entry_size_in_bytes*/) override {}
|
||||||
void decreaseActual(const UUID & /*user_id*/, size_t /*entry_size_in_bytes*/) override {}
|
void decreaseActual(const UUID & /*user_id*/, size_t /*entry_size_in_bytes*/) override {}
|
||||||
bool approveWrite(const UUID & /*user_id*/, size_t /*entry_size_in_bytes*/) const override { return true; }
|
bool approveWrite(const UUID & /*user_id*/, size_t /*entry_size_in_bytes*/) const override { return true; }
|
||||||
|
void clear() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,12 +38,12 @@ public:
|
|||||||
bool approveWrite(const UUID & user_id, size_t entry_size_in_bytes) const override
|
bool approveWrite(const UUID & user_id, size_t entry_size_in_bytes) const override
|
||||||
{
|
{
|
||||||
auto it_actual = actual.find(user_id);
|
auto it_actual = actual.find(user_id);
|
||||||
Resources actual_for_user{.size_in_bytes = 0, .num_items = 0}; /// assume zero actual resource consumption is user isn't found
|
Resources actual_for_user{.size_in_bytes = 0, .num_items = 0}; /// if no user is found, the default is no resource consumption
|
||||||
if (it_actual != actual.end())
|
if (it_actual != actual.end())
|
||||||
actual_for_user = it_actual->second;
|
actual_for_user = it_actual->second;
|
||||||
|
|
||||||
auto it_quota = quotas.find(user_id);
|
auto it_quota = quotas.find(user_id);
|
||||||
Resources quota_for_user{.size_in_bytes = std::numeric_limits<size_t>::max(), .num_items = std::numeric_limits<size_t>::max()}; /// assume no threshold if no quota is found
|
Resources quota_for_user{.size_in_bytes = std::numeric_limits<size_t>::max(), .num_items = std::numeric_limits<size_t>::max()}; /// if no user is found, the default is no threshold
|
||||||
if (it_quota != quotas.end())
|
if (it_quota != quotas.end())
|
||||||
quota_for_user = it_quota->second;
|
quota_for_user = it_quota->second;
|
||||||
|
|
||||||
@ -54,16 +54,21 @@ public:
|
|||||||
quota_for_user.num_items = std::numeric_limits<UInt64>::max();
|
quota_for_user.num_items = std::numeric_limits<UInt64>::max();
|
||||||
|
|
||||||
/// Check size quota
|
/// Check size quota
|
||||||
if (actual_for_user.size_in_bytes + entry_size_in_bytes >= quota_for_user.size_in_bytes)
|
if (actual_for_user.size_in_bytes + entry_size_in_bytes > quota_for_user.size_in_bytes)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/// Check items quota
|
/// Check items quota
|
||||||
if (quota_for_user.num_items + 1 >= quota_for_user.num_items)
|
if (actual_for_user.num_items + 1 > quota_for_user.num_items)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear() override
|
||||||
|
{
|
||||||
|
actual.clear();
|
||||||
|
}
|
||||||
|
|
||||||
struct Resources
|
struct Resources
|
||||||
{
|
{
|
||||||
size_t size_in_bytes = 0;
|
size_t size_in_bytes = 0;
|
||||||
@ -125,6 +130,7 @@ public:
|
|||||||
void clear() override
|
void clear() override
|
||||||
{
|
{
|
||||||
cache.clear();
|
cache.clear();
|
||||||
|
Base::user_quotas->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(const Key & key) override
|
void remove(const Key & key) override
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
a
|
||||||
|
b
|
||||||
|
1
|
||||||
|
c
|
||||||
|
d
|
||||||
|
3
|
||||||
|
--
|
||||||
|
a
|
||||||
|
b
|
||||||
|
1
|
||||||
|
c
|
||||||
|
d
|
||||||
|
3
|
@ -0,0 +1,41 @@
|
|||||||
|
-- Tags: no-parallel
|
||||||
|
-- Tag no-parallel: Messes with internal cache
|
||||||
|
|
||||||
|
-- Tests per-user quotas of the query cache. Settings 'query_cache_max_size_in_bytes' and 'query_cache_max_entries' are actually supposed to
|
||||||
|
-- be used in a settings profile, together with a readonly constraint. For simplicity, test both settings stand-alone in a stateless test
|
||||||
|
-- instead of an integration test - the relevant logic will still be covered by that.
|
||||||
|
|
||||||
|
SYSTEM DROP QUERY CACHE;
|
||||||
|
|
||||||
|
-- Run SELECT with quota that current user may write only 1 entry in the query cache
|
||||||
|
SET query_cache_max_entries = 1;
|
||||||
|
SELECT 'a' SETTINGS use_query_cache = true;
|
||||||
|
SELECT 'b' SETTINGS use_query_cache = true;
|
||||||
|
SELECT count(*) FROM system.query_cache; -- expect 1 entry
|
||||||
|
|
||||||
|
-- Run SELECTs again but w/o quota
|
||||||
|
SET query_cache_max_entries = DEFAULT;
|
||||||
|
SELECT 'c' SETTINGS use_query_cache = true;
|
||||||
|
SELECT 'd' SETTINGS use_query_cache = true;
|
||||||
|
SELECT count(*) FROM system.query_cache; -- expect 3 entries
|
||||||
|
|
||||||
|
SYSTEM DROP QUERY CACHE;
|
||||||
|
|
||||||
|
-- Run the same as above after a DROP QUERY CACHE.
|
||||||
|
SELECT '--';
|
||||||
|
|
||||||
|
SET query_cache_max_entries = 1;
|
||||||
|
SELECT 'a' SETTINGS use_query_cache = true;
|
||||||
|
SELECT 'b' SETTINGS use_query_cache = true;
|
||||||
|
SELECT count(*) FROM system.query_cache; -- expect 1 entry
|
||||||
|
|
||||||
|
-- Run SELECTs again but w/o quota
|
||||||
|
SET query_cache_max_entries = DEFAULT;
|
||||||
|
SELECT 'c' SETTINGS use_query_cache = true;
|
||||||
|
SELECT 'd' SETTINGS use_query_cache = true;
|
||||||
|
SELECT count(*) FROM system.query_cache; -- expect 3 entries
|
||||||
|
|
||||||
|
SYSTEM DROP QUERY CACHE;
|
||||||
|
|
||||||
|
-- SELECT '---';
|
||||||
|
|
Loading…
Reference in New Issue
Block a user