diff --git a/src/Interpreters/Cache/FileCache.cpp b/src/Interpreters/Cache/FileCache.cpp index e9a974bd991..c0becbfbe8d 100644 --- a/src/Interpreters/Cache/FileCache.cpp +++ b/src/Interpreters/Cache/FileCache.cpp @@ -676,8 +676,9 @@ bool FileCache::tryReserveImpl( if (is_overflow()) return false; - for (auto & [_, current_locked_key] : locked) + for (auto it = locked.begin(); it != locked.end();) { + auto & current_locked_key = it->second; for (const auto & offset_to_delete : current_locked_key->delete_offsets) { auto * file_segment_metadata = current_locked_key->getKeyMetadata().getByOffset(offset_to_delete); @@ -685,6 +686,9 @@ bool FileCache::tryReserveImpl( if (query_context) query_context->remove(key, offset); } + + /// Do not hold the key lock longer than required. + it = locked.erase(it); } if (file_segment_for_reserve) diff --git a/src/Interpreters/Cache/QueryLimit.h b/src/Interpreters/Cache/QueryLimit.h index e7f2425eb61..e66c7d2af76 100644 --- a/src/Interpreters/Cache/QueryLimit.h +++ b/src/Interpreters/Cache/QueryLimit.h @@ -43,6 +43,7 @@ public: const bool recache_on_query_limit_exceeded; }; + /// CacheGuard::Lock protects all priority queues. class LockedQueryContext { public: