This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new a205a3620de [fix](filecache) reset_range dose not update shadow queue
causing lar… (#60554)
a205a3620de is described below
commit a205a3620ded3a05c6920438add9d3a6e1b38e7c
Author: zhengyu <[email protected]>
AuthorDate: Tue Mar 3 18:02:32 2026 +0800
[fix](filecache) reset_range dose not update shadow queue causing lar…
(#60554)
…ge cache size pick#59314
pick apache/doris#59314
shadown queue is copying the actual LRU queue and provide lockless
acess. but the copying loses updating size wh en actual LRU queue is
reseting range (when load data, we first allocate 1MB block for the data
and reset the size t o the real size when finalizing).
This commit does the following to fix this problem:
1. update the corresponding shadow queue element when resetting
2. calibrate size during initial loading into memory process
### What problem does this PR solve?
Issue Number: close #xxx
Related PR: #xxx
Problem Summary:
### Release note
None
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [ ] Regression test
- [ ] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason <!-- Add your reason? -->
- Behavior changed:
- [ ] No.
- [ ] Yes. <!-- Explain the behavior change -->
- Does this need documentation?
- [ ] No.
- [ ] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR
should merge into -->
Signed-off-by: zhengyu <[email protected]>
---
be/src/io/cache/block_file_cache.cpp | 25 +++++++++++++++++++++----
be/src/io/cache/file_cache_common.h | 2 ++
be/src/io/cache/fs_file_cache_storage.cpp | 23 +++++++++++++++++++++--
be/src/io/cache/fs_file_cache_storage.h | 4 ++++
be/src/io/cache/lru_queue_recorder.cpp | 13 +++++++++++--
be/src/io/cache/lru_queue_recorder.h | 3 ++-
6 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/be/src/io/cache/block_file_cache.cpp
b/be/src/io/cache/block_file_cache.cpp
index bd55a2b76d0..fb8de34b153 100644
--- a/be/src/io/cache/block_file_cache.cpp
+++ b/be/src/io/cache/block_file_cache.cpp
@@ -939,6 +939,16 @@ FileBlockCell* BlockFileCache::add_cell(const
UInt128Wrapper& hash, const CacheC
return nullptr; /// Empty files are not cached.
}
+ VLOG_DEBUG << "Adding file block to cache. size=" << size << " hash=" <<
hash.to_string()
+ << " offset=" << offset << " cache_type=" <<
cache_type_to_string(context.cache_type)
+ << " expiration_time=" << context.expiration_time;
+
+ if (size > 1024 * 1024 * 1024) {
+ LOG(WARNING) << "File block size is too large for a block. size=" <<
size
+ << " hash=" << hash.to_string() << " offset=" << offset
+ << " stack:" << get_stack_trace();
+ }
+
auto& offsets = _files[hash];
auto itr = offsets.find(offset);
if (itr != offsets.end()) {
@@ -1393,10 +1403,10 @@ void BlockFileCache::reset_range(const UInt128Wrapper&
hash, size_t offset, size
if (cell->queue_iterator) {
auto& queue = get_queue(cell->file_block->cache_type());
DCHECK(queue.contains(hash, offset, cache_lock));
- auto iter = queue.get(hash, offset, cache_lock);
- iter->size = new_size;
- queue.cache_size -= old_size;
- queue.cache_size += new_size;
+ queue.resize(*cell->queue_iterator, new_size, cache_lock);
+ _lru_recorder->record_queue_event(cell->file_block->cache_type(),
CacheLRULogType::RESIZE,
+ cell->file_block->get_hash_value(),
+ cell->file_block->offset(),
new_size);
}
_cur_cache_size -= old_size;
_cur_cache_size += new_size;
@@ -1691,6 +1701,13 @@ void LRUQueue::remove_all(std::lock_guard<std::mutex>&
/* cache_lock */) {
void LRUQueue::move_to_end(Iterator queue_it, std::lock_guard<std::mutex>& /*
cache_lock */) {
queue.splice(queue.end(), queue, queue_it);
}
+
+void LRUQueue::resize(Iterator queue_it, size_t new_size,
+ std::lock_guard<std::mutex>& /* cache_lock */) {
+ cache_size -= queue_it->size;
+ queue_it->size = new_size;
+ cache_size += new_size;
+}
bool LRUQueue::contains(const UInt128Wrapper& hash, size_t offset,
std::lock_guard<std::mutex>& /* cache_lock */) const {
return map.find(std::make_pair(hash, offset)) != map.end();
diff --git a/be/src/io/cache/file_cache_common.h
b/be/src/io/cache/file_cache_common.h
index 090c219236b..417f68ecc97 100644
--- a/be/src/io/cache/file_cache_common.h
+++ b/be/src/io/cache/file_cache_common.h
@@ -224,6 +224,8 @@ public:
void move_to_end(Iterator queue_it, std::lock_guard<std::mutex>&
cache_lock);
+ void resize(Iterator queue_it, size_t new_size,
std::lock_guard<std::mutex>& cache_lock);
+
std::string to_string(std::lock_guard<std::mutex>& cache_lock) const;
bool contains(const UInt128Wrapper& hash, size_t offset,
diff --git a/be/src/io/cache/fs_file_cache_storage.cpp
b/be/src/io/cache/fs_file_cache_storage.cpp
index 3df56973af7..f5c87185d32 100644
--- a/be/src/io/cache/fs_file_cache_storage.cpp
+++ b/be/src/io/cache/fs_file_cache_storage.cpp
@@ -653,6 +653,26 @@ Status
FSFileCacheStorage::parse_filename_suffix_to_cache_type(
return Status::OK();
}
+bool FSFileCacheStorage::handle_already_loaded_block(
+ BlockFileCache* mgr, const UInt128Wrapper& hash, size_t offset, size_t
new_size,
+ std::lock_guard<std::mutex>& cache_lock) const {
+ auto file_it = mgr->_files.find(hash);
+ if (file_it == mgr->_files.end()) {
+ return false;
+ }
+
+ auto cell_it = file_it->second.find(offset);
+ if (cell_it == file_it->second.end()) {
+ return false;
+ }
+ auto block = cell_it->second.file_block;
+ size_t old_size = block->range().size();
+ if (old_size != new_size) {
+ mgr->reset_range(hash, offset, old_size, new_size, cache_lock);
+ }
+ return true;
+}
+
void FSFileCacheStorage::load_cache_info_into_memory(BlockFileCache* _mgr)
const {
int scan_length = 10000;
std::vector<BatchLoadArgs> batch_load_buffer;
@@ -662,8 +682,7 @@ void
FSFileCacheStorage::load_cache_info_into_memory(BlockFileCache* _mgr) const
auto f = [&](const BatchLoadArgs& args) {
// in async load mode, a cell may be added twice.
- if (_mgr->_files.contains(args.hash) &&
_mgr->_files[args.hash].contains(args.offset)) {
- // TODO(zhengyu): update type&expiration if need
+ if (handle_already_loaded_block(_mgr, args.hash, args.offset,
args.size, cache_lock)) {
return;
}
// if the file is tmp, it means it is the old file and it should
be removed
diff --git a/be/src/io/cache/fs_file_cache_storage.h
b/be/src/io/cache/fs_file_cache_storage.h
index 114517bdf72..fafada1eee2 100644
--- a/be/src/io/cache/fs_file_cache_storage.h
+++ b/be/src/io/cache/fs_file_cache_storage.h
@@ -88,6 +88,10 @@ public:
FileCacheStorageType get_type() override { return DISK; }
+ bool handle_already_loaded_block(BlockFileCache* mgr, const
UInt128Wrapper& hash, size_t offset,
+ size_t new_size,
+ std::lock_guard<std::mutex>& cache_lock)
const;
+
private:
void remove_old_version_directories();
diff --git a/be/src/io/cache/lru_queue_recorder.cpp
b/be/src/io/cache/lru_queue_recorder.cpp
index 8308a2a73ad..c7fda90b877 100644
--- a/be/src/io/cache/lru_queue_recorder.cpp
+++ b/be/src/io/cache/lru_queue_recorder.cpp
@@ -49,7 +49,7 @@ void LRUQueueRecorder::replay_queue_event(FileCacheType type)
{
if (it != std::list<LRUQueue::FileKeyAndOffset>::iterator()) {
shadow_queue.remove(it, lru_log_lock);
} else {
- LOG(WARNING) << "REMOVE failed, doesn't exist in shadow
queue";
+ VLOG_DEBUG << "REMOVE failed, doesn't exist in shadow
queue";
}
break;
}
@@ -58,7 +58,16 @@ void LRUQueueRecorder::replay_queue_event(FileCacheType
type) {
if (it != std::list<LRUQueue::FileKeyAndOffset>::iterator()) {
shadow_queue.move_to_end(it, lru_log_lock);
} else {
- LOG(WARNING) << "MOVETOBACK failed, doesn't exist in
shadow queue";
+ VLOG_DEBUG << "MOVETOBACK failed, doesn't exist in shadow
queue";
+ }
+ break;
+ }
+ case CacheLRULogType::RESIZE: {
+ auto it = shadow_queue.get(log->hash, log->offset,
lru_log_lock);
+ if (it != std::list<LRUQueue::FileKeyAndOffset>::iterator()) {
+ shadow_queue.resize(it, log->size, lru_log_lock);
+ } else {
+ VLOG_DEBUG << "RESIZE failed, doesn't exist in shadow
queue";
}
break;
}
diff --git a/be/src/io/cache/lru_queue_recorder.h
b/be/src/io/cache/lru_queue_recorder.h
index 1f6d69493cf..5bd68b70d55 100644
--- a/be/src/io/cache/lru_queue_recorder.h
+++ b/be/src/io/cache/lru_queue_recorder.h
@@ -31,7 +31,8 @@ enum class CacheLRULogType {
ADD = 0, // all of the integer types
REMOVE = 1,
MOVETOBACK = 2,
- INVALID = 3,
+ RESIZE = 3,
+ INVALID = 4,
};
struct CacheLRULog {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]