Some fixups

This commit is contained in:
Robert Schulze 2024-08-20 13:21:42 +00:00
parent eee618b319
commit 129d1e387e
No known key found for this signature in database
GPG Key ID: 26703B55FB13728A
17 changed files with 105 additions and 73 deletions

View File

@ -155,6 +155,8 @@ SELECT 1 SETTINGS use_query_cache = true, query_cache_tag = 'tag 1';
SELECT 1 SETTINGS use_query_cache = true, query_cache_tag = 'tag 2';
```
To remove only entries with tag `tag` from the query cache, you can use statement `SYSTEM DROP QUERY CACHE TAG 'tag'`.
ClickHouse reads table data in blocks of [max_block_size](settings/settings.md#setting-max_block_size) rows. Due to filtering, aggregation,
etc., result blocks are typically much smaller than 'max_block_size' but there are also cases where they are much bigger. Setting
[query_cache_squash_partial_results](settings/settings.md#query-cache-squash-partial-results) (enabled by default) controls if result blocks

View File

@ -136,7 +136,13 @@ The compiled expression cache is enabled/disabled with the query/user/profile-le
## DROP QUERY CACHE
```sql
SYSTEM DROP QUERY CACHE;
SYSTEM DROP QUERY CACHE TAG '<tag>'
````
Clears the [query cache](../../operations/query-cache.md).
If a tag is specified, only query cache entries with the specified tag are deleted.
## DROP FORMAT SCHEMA CACHE {#system-drop-schema-format}

View File

@ -197,10 +197,10 @@ public:
cache_policy->remove(key);
}
void removeWithPredicate(std::function<bool(const Key&, const MappedPtr &)> predicate)
void remove(std::function<bool(const Key&, const MappedPtr &)> predicate)
{
std::lock_guard lock(mutex);
cache_policy->removeWithPredicate(predicate);
cache_policy->remove(predicate);
}
size_t sizeInBytes() const

View File

@ -55,7 +55,7 @@ public:
virtual void set(const Key & key, const MappedPtr & mapped) = 0;
virtual void remove(const Key & key) = 0;
virtual void removeWithPredicate(std::function<bool(const Key&, const MappedPtr &)> predicate) = 0;
virtual void remove(std::function<bool(const Key & key, const MappedPtr & mapped)> predicate) = 0;
virtual void clear() = 0;
virtual std::vector<KeyMapped> dump() const = 0;

View File

@ -68,23 +68,6 @@ public:
current_size_in_bytes = 0;
}
void removeWithPredicate(std::function<bool(const Key&, const MappedPtr&)> predicate) override
{
for (auto it = cells.begin(); it != cells.end();)
{
if (predicate(it->first, it->second.value))
{
auto & cell = it->second;
current_size_in_bytes -= cell.size;
queue.erase(cell.queue_iterator);
cells.erase(it);
it = cells.erase(it);
}
else
++it;
}
}
void remove(const Key & key) override
{
auto it = cells.find(key);
@ -96,6 +79,22 @@ public:
cells.erase(it);
}
void remove(std::function<bool(const Key &, const MappedPtr &)> predicate) override
{
for (auto it = cells.begin(); it != cells.end();)
{
if (predicate(it->first, it->second.value))
{
Cell & cell = it->second;
current_size_in_bytes -= cell.size;
queue.erase(cell.queue_iterator);
it = cells.erase(it);
}
else
++it;
}
}
MappedPtr get(const Key & key) override
{
auto it = cells.find(key);

View File

@ -95,7 +95,7 @@ public:
cells.erase(it);
}
void removeWithPredicate(std::function<bool(const Key&, const MappedPtr&)> predicate) override
void remove(std::function<bool(const Key &, const MappedPtr &)> predicate) override
{
for (auto it = cells.begin(); it != cells.end();)
{

View File

@ -133,7 +133,19 @@ public:
Base::user_quotas->clear();
}
void removeWithPredicate(std::function<bool(const Key&, const MappedPtr&)> predicate) override
void remove(const Key & key) override
{
auto it = cache.find(key);
if (it == cache.end())
return;
size_t sz = weight_function(*it->second);
if (it->first.user_id.has_value())
Base::user_quotas->decreaseActual(*it->first.user_id, sz);
cache.erase(it);
size_in_bytes -= sz;
}
void remove(std::function<bool(const Key &, const MappedPtr &)> predicate) override
{
for (auto it = cache.begin(); it != cache.end();)
{
@ -150,18 +162,6 @@ public:
}
}
void remove(const Key & key) override
{
auto it = cache.find(key);
if (it == cache.end())
return;
size_t sz = weight_function(*it->second);
if (it->first.user_id.has_value())
Base::user_quotas->decreaseActual(*it->first.user_id, sz);
cache.erase(it);
size_in_bytes -= sz;
}
MappedPtr get(const Key & key) override
{
auto it = cache.find(key);

View File

@ -619,19 +619,18 @@ QueryCache::Writer QueryCache::createWriter(const Key & key, std::chrono::millis
return Writer(cache, key, max_entry_size_in_bytes, max_entry_size_in_rows, min_query_runtime, squash_partial_results, max_block_size);
}
void QueryCache::clearWithTag(const String & tag)
void QueryCache::clear(const std::optional<String> & tag)
{
auto remove_with_tag = [tag](const Key & k, const Cache::MappedPtr &)
if (tag)
{
return k.tag == tag;
};
cache.removeWithPredicate(remove_with_tag);
std::lock_guard lock(mutex);
}
auto predicate = [tag](const Key & key, const Cache::MappedPtr &) { return key.tag == tag.value(); };
cache.remove(predicate);
}
else
{
cache.clear();
}
void QueryCache::clear()
{
cache.clear();
std::lock_guard lock(mutex);
times_executed.clear();
}

View File

@ -211,8 +211,7 @@ public:
Reader createReader(const Key & key);
Writer createWriter(const Key & key, std::chrono::milliseconds min_query_runtime, bool squash_partial_results, size_t max_block_size, size_t max_query_cache_size_in_bytes_quota, size_t max_query_cache_entries_quota);
void clear();
void clearWithTag(const String & tag);
void clear(const std::optional<String> & tag);
size_t sizeInBytes() const;
size_t count() const;

View File

@ -3228,20 +3228,12 @@ QueryCachePtr Context::getQueryCache() const
return shared->query_cache;
}
void Context::clearQueryCache() const
void Context::clearQueryCache(const std::optional<String> & tag) const
{
std::lock_guard lock(shared->mutex);
if (shared->query_cache)
shared->query_cache->clear();
}
void Context::clearQueryCacheWithTag(const String & tag) const
{
std::lock_guard lock(shared->mutex);
if (shared->query_cache)
shared->query_cache->clearWithTag(tag);
shared->query_cache->clear(tag);
}
void Context::clearCaches() const

View File

@ -1068,8 +1068,7 @@ public:
void setQueryCache(size_t max_size_in_bytes, size_t max_entries, size_t max_entry_size_in_bytes, size_t max_entry_size_in_rows);
void updateQueryCacheConfiguration(const Poco::Util::AbstractConfiguration & config);
std::shared_ptr<QueryCache> getQueryCache() const;
void clearQueryCache() const;
void clearQueryCacheWithTag(const String & tag) const;
void clearQueryCache(const std::optional<String> & tag) const;
/** Clear the caches of the uncompressed blocks and marks.
* This is usually done when renaming tables, changing the type of columns, deleting a table.

View File

@ -371,7 +371,7 @@ BlockIO InterpreterSystemQuery::execute()
case Type::DROP_QUERY_CACHE:
{
getContext()->checkAccess(AccessType::SYSTEM_DROP_QUERY_CACHE);
!query.query_cache_tag.empty() ? getContext()->clearQueryCacheWithTag(query.query_cache_tag): getContext()->clearQueryCache();
getContext()->clearQueryCache(query.query_cache_tag);
break;
}

View File

@ -129,9 +129,10 @@ public:
String storage_policy;
String volume;
String disk;
String query_cache_tag;
UInt64 seconds{};
std::optional<String> query_cache_tag;
String filesystem_cache_name;
std::string key_to_drop;
std::optional<size_t> offset_to_drop;

View File

@ -470,8 +470,8 @@ namespace DB
MR_MACROS(TABLE_OVERRIDE, "TABLE OVERRIDE") \
MR_MACROS(TABLE, "TABLE") \
MR_MACROS(TABLES, "TABLES") \
MR_MACROS(TAGS, "TAGS") \
MR_MACROS(TAG, "TAG") \
MR_MACROS(TAGS, "TAGS") \
MR_MACROS(TAGS_INNER_UUID, "TAGS INNER UUID") \
MR_MACROS(TEMPORARY_TABLE, "TEMPORARY TABLE") \
MR_MACROS(TEMPORARY, "TEMPORARY") \

View File

@ -471,6 +471,16 @@ bool ParserSystemQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected &
res->seconds = seconds->as<ASTLiteral>()->value.safeGet<UInt64>();
break;
}
case Type::DROP_QUERY_CACHE:
{
ParserLiteral tag_parser;
ASTPtr ast;
if (ParserKeyword{Keyword::TAG}.ignore(pos, expected) && tag_parser.parse(pos, ast, expected))
res->query_cache_tag = std::make_optional<String>(ast->as<ASTLiteral>()->value.safeGet<String>());
if (!parseQueryWithOnCluster(res, pos, expected))
return false;
break;
}
case Type::DROP_FILESYSTEM_CACHE:
{
ParserLiteral path_parser;
@ -489,16 +499,6 @@ bool ParserSystemQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected &
return false;
break;
}
case Type::DROP_QUERY_CACHE:
{
ParserLiteral tag_parser;
ASTPtr ast;
if (ParserKeyword{Keyword::TAG}.ignore(pos, expected) && tag_parser.parse(pos, ast, expected))
res->query_cache_tag = ast->as<ASTLiteral>()->value.safeGet<String>();
if (!parseQueryWithOnCluster(res, pos, expected))
return false;
break;
}
case Type::SYNC_FILESYSTEM_CACHE:
{
ParserLiteral path_parser;

View File

@ -1,3 +1,17 @@
Cache query result in query cache
1
1
DROP entries with a certain tag, no entry will match
1
After a full DROP, the cache is empty now
0
Cache query result with different or no tag in query cache
1
1
1
2
4
DROP entries with certain tags
2
1
0

View File

@ -4,10 +4,31 @@
-- (it's silly to use what will be tested below but we have to assume other tests cluttered the query cache)
SYSTEM DROP QUERY CACHE;
-- Cache query result in query cache
SELECT 'Cache query result in query cache';
SELECT 1 SETTINGS use_query_cache = true;
SELECT count(*) FROM system.query_cache;
-- No query results are cached after DROP
SELECT 'DROP entries with a certain tag, no entry will match';
SYSTEM DROP QUERY CACHE TAG 'tag';
SELECT count(*) FROM system.query_cache;
SELECT 'After a full DROP, the cache is empty now';
SYSTEM DROP QUERY CACHE;
SELECT count(*) FROM system.query_cache;
-- More tests for DROP with tags:
SELECT 'Cache query result with different or no tag in query cache';
SELECT 1 SETTINGS use_query_cache = true;
SELECT 1 SETTINGS use_query_cache = true, query_cache_tag = 'abc';
SELECT 1 SETTINGS use_query_cache = true, query_cache_tag = 'def';
SELECT 2 SETTINGS use_query_cache = true;
SELECT count(*) FROM system.query_cache;
SELECT 'DROP entries with certain tags';
SYSTEM DROP QUERY CACHE TAG '';
SELECT count(*) FROM system.query_cache;
SYSTEM DROP QUERY CACHE TAG 'def';
SELECT count(*) FROM system.query_cache;
SYSTEM DROP QUERY CACHE TAG 'abc';
SELECT count(*) FROM system.query_cache;