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]

Reply via email to