This is an automated email from the ASF dual-hosted git repository.

zouxinyi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 1a3a5b60cd1 [fix](memory) Refactor LRU cache policy memory tracking 
(#36235)
1a3a5b60cd1 is described below

commit 1a3a5b60cd1cfd424f9ce749536b170a5d155827
Author: Xinyi Zou <zouxiny...@gmail.com>
AuthorDate: Mon Jun 24 14:05:23 2024 +0800

    [fix](memory) Refactor LRU cache policy memory tracking (#36235)
    
    Fix #35590, CacheManager get CachePolicy should be used lock.
    
    Add LRUCachePolicyTrackingAllocator and LRUCachePolicyTrackingManual.
    tracking memory in LRUCachePolicy::insert, LRUCacheValueBase not need init 
mem_tracker, so not need to get CachePolicy under lock.
---
 be/src/cloud/cloud_tablet_mgr.cpp                  |   6 +-
 be/src/cloud/cloud_txn_delete_bitmap_cache.cpp     |   4 +-
 be/src/cloud/cloud_txn_delete_bitmap_cache.h       |   6 +-
 be/src/olap/page_cache.cpp                         |  35 +++++-
 be/src/olap/page_cache.h                           |  54 +++-----
 .../segment_v2/bitshuffle_page_pre_decoder.h       |   4 +-
 be/src/olap/rowset/segment_v2/encoding_info.h      |   2 +-
 .../rowset/segment_v2/inverted_index_cache.cpp     |  10 +-
 .../olap/rowset/segment_v2/inverted_index_cache.h  |  42 +++----
 be/src/olap/rowset/segment_v2/page_io.cpp          |  14 +--
 be/src/olap/schema_cache.h                         |   9 +-
 be/src/olap/segment_loader.cpp                     |   6 +-
 be/src/olap/segment_loader.h                       |   9 +-
 be/src/olap/storage_engine.h                       |  10 +-
 be/src/olap/tablet_meta.h                          |  11 +-
 be/src/olap/tablet_schema_cache.cpp                |   4 +-
 be/src/olap/tablet_schema_cache.h                  |  10 +-
 be/src/olap/txn_manager.h                          |  11 +-
 be/src/runtime/load_channel_mgr.h                  |   9 +-
 be/src/runtime/memory/cache_manager.h              |   2 -
 be/src/runtime/memory/cache_policy.h               |  28 -----
 be/src/runtime/memory/lru_cache_policy.h           | 140 +++++++++++++++++----
 be/src/runtime/memory/lru_cache_value_base.h       |  12 +-
 be/src/service/point_query_executor.cpp            |  10 +-
 be/src/service/point_query_executor.h              |  15 ++-
 be/src/util/obj_lru_cache.cpp                      |   6 +-
 be/src/util/obj_lru_cache.h                        |  11 +-
 be/test/olap/lru_cache_test.cpp                    |  12 +-
 be/test/olap/page_cache_test.cpp                   |  30 +++--
 29 files changed, 288 insertions(+), 234 deletions(-)

diff --git a/be/src/cloud/cloud_tablet_mgr.cpp 
b/be/src/cloud/cloud_tablet_mgr.cpp
index 06bea6db126..0fe050d02db 100644
--- a/be/src/cloud/cloud_tablet_mgr.cpp
+++ b/be/src/cloud/cloud_tablet_mgr.cpp
@@ -136,7 +136,7 @@ private:
 CloudTabletMgr::CloudTabletMgr(CloudStorageEngine& engine)
         : _engine(engine),
           _tablet_map(std::make_unique<TabletMap>()),
-          _cache(std::make_unique<LRUCachePolicy>(
+          _cache(std::make_unique<LRUCachePolicyTrackingManual>(
                   CachePolicy::CacheType::CLOUD_TABLET_CACHE, 
config::tablet_cache_capacity,
                   LRUCacheType::NUMBER, 0, config::tablet_cache_shards)) {}
 
@@ -148,9 +148,7 @@ Result<std::shared_ptr<CloudTablet>> 
CloudTabletMgr::get_tablet(int64_t tablet_i
     class Value : public LRUCacheValueBase {
     public:
         Value(const std::shared_ptr<CloudTablet>& tablet, TabletMap& 
tablet_map)
-                : 
LRUCacheValueBase(CachePolicy::CacheType::CLOUD_TABLET_CACHE),
-                  tablet(tablet),
-                  tablet_map(tablet_map) {}
+                : tablet(tablet), tablet_map(tablet_map) {}
         ~Value() override { tablet_map.erase(tablet.get()); }
 
         // FIXME(plat1ko): The ownership of tablet seems to belong to 
'TabletMap', while `Value`
diff --git a/be/src/cloud/cloud_txn_delete_bitmap_cache.cpp 
b/be/src/cloud/cloud_txn_delete_bitmap_cache.cpp
index 64faf915e61..3f664306f60 100644
--- a/be/src/cloud/cloud_txn_delete_bitmap_cache.cpp
+++ b/be/src/cloud/cloud_txn_delete_bitmap_cache.cpp
@@ -31,8 +31,8 @@
 namespace doris {
 
 CloudTxnDeleteBitmapCache::CloudTxnDeleteBitmapCache(size_t size_in_bytes)
-        : 
LRUCachePolicy(CachePolicy::CacheType::CLOUD_TXN_DELETE_BITMAP_CACHE, 
size_in_bytes,
-                         LRUCacheType::SIZE, 86400, 4),
+        : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::CLOUD_TXN_DELETE_BITMAP_CACHE,
+                                       size_in_bytes, LRUCacheType::SIZE, 
86400, 4),
           _stop_latch(1) {}
 
 CloudTxnDeleteBitmapCache::~CloudTxnDeleteBitmapCache() {
diff --git a/be/src/cloud/cloud_txn_delete_bitmap_cache.h 
b/be/src/cloud/cloud_txn_delete_bitmap_cache.h
index 71d5123f34d..5012db6b8e5 100644
--- a/be/src/cloud/cloud_txn_delete_bitmap_cache.h
+++ b/be/src/cloud/cloud_txn_delete_bitmap_cache.h
@@ -30,7 +30,7 @@
 namespace doris {
 
 // Record transaction related delete bitmaps using a lru cache.
-class CloudTxnDeleteBitmapCache : public LRUCachePolicy {
+class CloudTxnDeleteBitmapCache : public LRUCachePolicyTrackingManual {
 public:
     CloudTxnDeleteBitmapCache(size_t size_in_bytes);
 
@@ -72,9 +72,7 @@ private:
         RowsetIdUnorderedSet rowset_ids;
 
         DeleteBitmapCacheValue(DeleteBitmapPtr delete_bitmap_, const 
RowsetIdUnorderedSet& ids_)
-                : 
LRUCacheValueBase(CachePolicy::CacheType::CLOUD_TXN_DELETE_BITMAP_CACHE),
-                  delete_bitmap(std::move(delete_bitmap_)),
-                  rowset_ids(ids_) {}
+                : delete_bitmap(std::move(delete_bitmap_)), rowset_ids(ids_) {}
     };
 
     struct TxnKey {
diff --git a/be/src/olap/page_cache.cpp b/be/src/olap/page_cache.cpp
index 3476ddb2a34..fe0a99af34f 100644
--- a/be/src/olap/page_cache.cpp
+++ b/be/src/olap/page_cache.cpp
@@ -24,6 +24,39 @@
 #include "runtime/exec_env.h"
 
 namespace doris {
+template <typename TAllocator>
+PageBase<TAllocator>::PageBase(size_t b, bool use_cache, 
segment_v2::PageTypePB page_type)
+        : LRUCacheValueBase(),
+          _size(b),
+          _capacity(b),
+          _use_cache(use_cache),
+          _page_type(page_type) {
+    if (_use_cache) {
+        SCOPED_SWITCH_THREAD_MEM_TRACKER_LIMITER(
+                StoragePageCache::instance()->mem_tracker(_page_type));
+        _data = reinterpret_cast<char*>(TAllocator::alloc(_capacity, 
ALLOCATOR_ALIGNMENT_16));
+    } else {
+        _data = reinterpret_cast<char*>(TAllocator::alloc(_capacity, 
ALLOCATOR_ALIGNMENT_16));
+    }
+}
+
+template <typename TAllocator>
+PageBase<TAllocator>::~PageBase() {
+    if (_data != nullptr) {
+        DCHECK(_capacity != 0 && _size != 0);
+        if (_use_cache) {
+            SCOPED_SWITCH_THREAD_MEM_TRACKER_LIMITER(
+                    StoragePageCache::instance()->mem_tracker(_page_type));
+            TAllocator::free(_data, _capacity);
+        } else {
+            TAllocator::free(_data, _capacity);
+        }
+    }
+}
+
+template class PageBase<Allocator<true>>;
+template class PageBase<Allocator<false>>;
+
 StoragePageCache* StoragePageCache::create_global_cache(size_t capacity,
                                                         int32_t 
index_cache_percentage,
                                                         int64_t 
pk_index_cache_capacity,
@@ -70,7 +103,7 @@ void StoragePageCache::insert(const CacheKey& key, DataPage* 
data, PageCacheHand
     }
 
     auto* cache = _get_page_cache(page_type);
-    auto* lru_handle = cache->insert_no_tracking(key.encode(), data, 
data->capacity(), priority);
+    auto* lru_handle = cache->insert(key.encode(), data, data->capacity(), 0, 
priority);
     *handle = PageCacheHandle(cache, lru_handle);
 }
 
diff --git a/be/src/olap/page_cache.h b/be/src/olap/page_cache.h
index e1bb8be8d6f..23b3574a10a 100644
--- a/be/src/olap/page_cache.h
+++ b/be/src/olap/page_cache.h
@@ -41,23 +41,10 @@ template <typename TAllocator>
 class PageBase : private TAllocator, public LRUCacheValueBase {
 public:
     PageBase() = default;
-
-    PageBase(size_t b, const std::shared_ptr<MemTrackerLimiter>& mem_tracker)
-            : LRUCacheValueBase(), _size(b), _capacity(b), 
_mem_tracker_by_allocator(mem_tracker) {
-        SCOPED_SWITCH_THREAD_MEM_TRACKER_LIMITER(_mem_tracker_by_allocator);
-        _data = reinterpret_cast<char*>(TAllocator::alloc(_capacity, 
ALLOCATOR_ALIGNMENT_16));
-    }
-
+    PageBase(size_t b, bool use_cache, segment_v2::PageTypePB page_type);
     PageBase(const PageBase&) = delete;
     PageBase& operator=(const PageBase&) = delete;
-
-    ~PageBase() override {
-        if (_data != nullptr) {
-            DCHECK(_capacity != 0 && _size != 0);
-            
SCOPED_SWITCH_THREAD_MEM_TRACKER_LIMITER(_mem_tracker_by_allocator);
-            TAllocator::free(_data, _capacity);
-        }
-    }
+    ~PageBase() override;
 
     char* data() { return _data; }
     size_t size() { return _size; }
@@ -73,7 +60,8 @@ private:
     // Effective size, smaller than capacity, such as data page remove 
checksum suffix.
     size_t _size = 0;
     size_t _capacity = 0;
-    std::shared_ptr<MemTrackerLimiter> _mem_tracker_by_allocator;
+    bool _use_cache;
+    segment_v2::PageTypePB _page_type;
 };
 
 using DataPage = PageBase<Allocator<false>>;
@@ -105,34 +93,28 @@ public:
         }
     };
 
-    class DataPageCache : public LRUCachePolicy {
+    class DataPageCache : public LRUCachePolicyTrackingAllocator {
     public:
         DataPageCache(size_t capacity, uint32_t num_shards)
-                : LRUCachePolicy(CachePolicy::CacheType::DATA_PAGE_CACHE, 
capacity,
-                                 LRUCacheType::SIZE, 
config::data_page_cache_stale_sweep_time_sec,
-                                 num_shards) {
-            
init_mem_tracker_by_allocator(lru_cache_type_string(LRUCacheType::SIZE));
-        }
+                : LRUCachePolicyTrackingAllocator(
+                          CachePolicy::CacheType::DATA_PAGE_CACHE, capacity, 
LRUCacheType::SIZE,
+                          config::data_page_cache_stale_sweep_time_sec, 
num_shards) {}
     };
 
-    class IndexPageCache : public LRUCachePolicy {
+    class IndexPageCache : public LRUCachePolicyTrackingAllocator {
     public:
         IndexPageCache(size_t capacity, uint32_t num_shards)
-                : LRUCachePolicy(CachePolicy::CacheType::INDEXPAGE_CACHE, 
capacity,
-                                 LRUCacheType::SIZE, 
config::index_page_cache_stale_sweep_time_sec,
-                                 num_shards) {
-            
init_mem_tracker_by_allocator(lru_cache_type_string(LRUCacheType::SIZE));
-        }
+                : LRUCachePolicyTrackingAllocator(
+                          CachePolicy::CacheType::INDEXPAGE_CACHE, capacity, 
LRUCacheType::SIZE,
+                          config::index_page_cache_stale_sweep_time_sec, 
num_shards) {}
     };
 
-    class PKIndexPageCache : public LRUCachePolicy {
+    class PKIndexPageCache : public LRUCachePolicyTrackingAllocator {
     public:
         PKIndexPageCache(size_t capacity, uint32_t num_shards)
-                : LRUCachePolicy(CachePolicy::CacheType::PK_INDEX_PAGE_CACHE, 
capacity,
-                                 LRUCacheType::SIZE,
-                                 
config::pk_index_page_cache_stale_sweep_time_sec, num_shards) {
-            
init_mem_tracker_by_allocator(lru_cache_type_string(LRUCacheType::SIZE));
-        }
+                : LRUCachePolicyTrackingAllocator(
+                          CachePolicy::CacheType::PK_INDEX_PAGE_CACHE, 
capacity, LRUCacheType::SIZE,
+                          config::pk_index_page_cache_stale_sweep_time_sec, 
num_shards) {}
     };
 
     static constexpr uint32_t kDefaultNumShards = 16;
@@ -169,7 +151,7 @@ public:
                 segment_v2::PageTypePB page_type, bool in_memory = false);
 
     std::shared_ptr<MemTrackerLimiter> mem_tracker(segment_v2::PageTypePB 
page_type) {
-        return _get_page_cache(page_type)->mem_tracker_by_allocator();
+        return _get_page_cache(page_type)->mem_tracker();
     }
 
 private:
@@ -183,7 +165,7 @@ private:
     // delete bitmap in unique key with mow
     std::unique_ptr<PKIndexPageCache> _pk_index_page_cache;
 
-    LRUCachePolicy* _get_page_cache(segment_v2::PageTypePB page_type) {
+    LRUCachePolicyTrackingAllocator* _get_page_cache(segment_v2::PageTypePB 
page_type) {
         switch (page_type) {
         case segment_v2::DATA_PAGE: {
             return _data_page_cache.get();
diff --git a/be/src/olap/rowset/segment_v2/bitshuffle_page_pre_decoder.h 
b/be/src/olap/rowset/segment_v2/bitshuffle_page_pre_decoder.h
index 2ab1b278c53..e060ffd35b4 100644
--- a/be/src/olap/rowset/segment_v2/bitshuffle_page_pre_decoder.h
+++ b/be/src/olap/rowset/segment_v2/bitshuffle_page_pre_decoder.h
@@ -39,7 +39,7 @@ struct BitShufflePagePreDecoder : public DataPagePreDecoder {
      * @return Status
      */
     Status decode(std::unique_ptr<DataPage>* page, Slice* page_slice, size_t 
size_of_tail,
-                  const std::shared_ptr<MemTrackerLimiter>& mem_tracker) 
override {
+                  bool _use_cache, segment_v2::PageTypePB page_type) override {
         size_t num_elements, compressed_size, num_element_after_padding;
         int size_of_element;
 
@@ -67,7 +67,7 @@ struct BitShufflePagePreDecoder : public DataPagePreDecoder {
         decoded_slice.size = size_of_dict_header + BITSHUFFLE_PAGE_HEADER_SIZE 
+
                              num_element_after_padding * size_of_element + 
size_of_tail;
         std::unique_ptr<DataPage> decoded_page =
-                std::make_unique<DataPage>(decoded_slice.size, mem_tracker);
+                std::make_unique<DataPage>(decoded_slice.size, _use_cache, 
page_type);
         decoded_slice.data = decoded_page->data();
 
         if constexpr (USED_IN_DICT_ENCODING) {
diff --git a/be/src/olap/rowset/segment_v2/encoding_info.h 
b/be/src/olap/rowset/segment_v2/encoding_info.h
index d9207baa25e..3305ecf08d4 100644
--- a/be/src/olap/rowset/segment_v2/encoding_info.h
+++ b/be/src/olap/rowset/segment_v2/encoding_info.h
@@ -43,7 +43,7 @@ enum EncodingTypePB : int;
 class DataPagePreDecoder {
 public:
     virtual Status decode(std::unique_ptr<DataPage>* page, Slice* page_slice, 
size_t size_of_tail,
-                          const std::shared_ptr<MemTrackerLimiter>& 
mem_tracker) = 0;
+                          bool _use_cache, segment_v2::PageTypePB page_type) = 
0;
     virtual ~DataPagePreDecoder() = default;
 };
 
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_cache.cpp 
b/be/src/olap/rowset/segment_v2/inverted_index_cache.cpp
index f6a0951b44c..b2930d2867b 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_cache.cpp
+++ b/be/src/olap/rowset/segment_v2/inverted_index_cache.cpp
@@ -135,14 +135,10 @@ void InvertedIndexQueryCache::insert(const CacheKey& key, 
std::shared_ptr<roarin
         return;
     }
 
-    auto* lru_handle = LRUCachePolicy::insert(key.encode(), 
(void*)cache_value_ptr.release(),
-                                              bitmap->getSizeInBytes(), 
bitmap->getSizeInBytes(),
-                                              CachePriority::NORMAL);
+    auto* lru_handle = LRUCachePolicyTrackingManual::insert(
+            key.encode(), (void*)cache_value_ptr.release(), 
bitmap->getSizeInBytes(),
+            bitmap->getSizeInBytes(), CachePriority::NORMAL);
     *handle = InvertedIndexQueryCacheHandle(this, lru_handle);
 }
 
-int64_t InvertedIndexQueryCache::mem_consumption() {
-    return LRUCachePolicy::mem_consumption();
-}
-
 } // namespace doris::segment_v2
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_cache.h 
b/be/src/olap/rowset/segment_v2/inverted_index_cache.h
index 1386ee7fab2..5423ea044a2 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_cache.h
+++ b/be/src/olap/rowset/segment_v2/inverted_index_cache.h
@@ -59,10 +59,9 @@ public:
         size_t size = 0;
         int64_t last_visit_time;
 
-        CacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::INVERTEDINDEX_SEARCHER_CACHE) {}
+        CacheValue() = default;
         explicit CacheValue(IndexSearcherPtr searcher, size_t mem_size, 
int64_t visit_time)
-                : 
LRUCacheValueBase(CachePolicy::CacheType::INVERTEDINDEX_SEARCHER_CACHE),
-                  index_searcher(std::move(searcher)) {
+                : index_searcher(std::move(searcher)) {
             size = mem_size;
             last_visit_time = visit_time;
         }
@@ -100,23 +99,23 @@ public:
 private:
     InvertedIndexSearcherCache() = default;
 
-    class InvertedIndexSearcherCachePolicy : public LRUCachePolicy {
+    class InvertedIndexSearcherCachePolicy : public 
LRUCachePolicyTrackingManual {
     public:
         InvertedIndexSearcherCachePolicy(size_t capacity, uint32_t num_shards,
                                          uint32_t element_count_capacity)
-                : 
LRUCachePolicy(CachePolicy::CacheType::INVERTEDINDEX_SEARCHER_CACHE, capacity,
-                                 LRUCacheType::SIZE,
-                                 
config::inverted_index_cache_stale_sweep_time_sec, num_shards,
-                                 element_count_capacity, true) {}
+                : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::INVERTEDINDEX_SEARCHER_CACHE,
+                                               capacity, LRUCacheType::SIZE,
+                                               
config::inverted_index_cache_stale_sweep_time_sec,
+                                               num_shards, 
element_count_capacity, true) {}
         InvertedIndexSearcherCachePolicy(size_t capacity, uint32_t num_shards,
                                          uint32_t element_count_capacity,
                                          CacheValueTimeExtractor 
cache_value_time_extractor,
                                          bool cache_value_check_timestamp)
-                : 
LRUCachePolicy(CachePolicy::CacheType::INVERTEDINDEX_SEARCHER_CACHE, capacity,
-                                 LRUCacheType::SIZE,
-                                 
config::inverted_index_cache_stale_sweep_time_sec, num_shards,
-                                 element_count_capacity, 
cache_value_time_extractor,
-                                 cache_value_check_timestamp, true) {}
+                : LRUCachePolicyTrackingManual(
+                          
CachePolicy::CacheType::INVERTEDINDEX_SEARCHER_CACHE, capacity,
+                          LRUCacheType::SIZE, 
config::inverted_index_cache_stale_sweep_time_sec,
+                          num_shards, element_count_capacity, 
cache_value_time_extractor,
+                          cache_value_check_timestamp, true) {}
     };
     // Insert a cache entry by key.
     // And the cache entry will be returned in handle.
@@ -180,8 +179,10 @@ private:
 
 class InvertedIndexQueryCacheHandle;
 
-class InvertedIndexQueryCache : public LRUCachePolicy {
+class InvertedIndexQueryCache : public LRUCachePolicyTrackingManual {
 public:
+    using LRUCachePolicyTrackingManual::insert;
+
     // cache key
     struct CacheKey {
         io::Path index_path;               // index file path
@@ -208,14 +209,12 @@ public:
 
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::INVERTEDINDEX_QUERY_CACHE) {}
-
         std::shared_ptr<roaring::Roaring> bitmap;
     };
 
     // Create global instance of this class
     static InvertedIndexQueryCache* create_global_cache(size_t capacity, 
uint32_t num_shards = 16) {
-        InvertedIndexQueryCache* res = new InvertedIndexQueryCache(capacity, 
num_shards);
+        auto* res = new InvertedIndexQueryCache(capacity, num_shards);
         return res;
     }
 
@@ -228,16 +227,15 @@ public:
     InvertedIndexQueryCache() = delete;
 
     InvertedIndexQueryCache(size_t capacity, uint32_t num_shards)
-            : 
LRUCachePolicy(CachePolicy::CacheType::INVERTEDINDEX_QUERY_CACHE, capacity,
-                             LRUCacheType::SIZE, 
config::inverted_index_cache_stale_sweep_time_sec,
-                             num_shards) {}
+            : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::INVERTEDINDEX_QUERY_CACHE,
+                                           capacity, LRUCacheType::SIZE,
+                                           
config::inverted_index_cache_stale_sweep_time_sec,
+                                           num_shards) {}
 
     bool lookup(const CacheKey& key, InvertedIndexQueryCacheHandle* handle);
 
     void insert(const CacheKey& key, std::shared_ptr<roaring::Roaring> bitmap,
                 InvertedIndexQueryCacheHandle* handle);
-
-    int64_t mem_consumption();
 };
 
 class InvertedIndexQueryCacheHandle {
diff --git a/be/src/olap/rowset/segment_v2/page_io.cpp 
b/be/src/olap/rowset/segment_v2/page_io.cpp
index cf6e0541612..cea4a23f742 100644
--- a/be/src/olap/rowset/segment_v2/page_io.cpp
+++ b/be/src/olap/rowset/segment_v2/page_io.cpp
@@ -143,15 +143,9 @@ Status PageIO::read_and_decompress_page(const 
PageReadOptions& opts, PageHandle*
                                   opts.file_reader->path().native());
     }
 
-    std::shared_ptr<MemTrackerLimiter> page_mem_tracker;
-    if (opts.use_page_cache && cache) {
-        page_mem_tracker = cache->mem_tracker(opts.type);
-    } else {
-        page_mem_tracker = 
thread_context()->thread_mem_tracker_mgr->limiter_mem_tracker();
-    }
-
     // hold compressed page at first, reset to decompressed page later
-    std::unique_ptr<DataPage> page = std::make_unique<DataPage>(page_size, 
page_mem_tracker);
+    std::unique_ptr<DataPage> page =
+            std::make_unique<DataPage>(page_size, opts.use_page_cache, 
opts.type);
     Slice page_slice(page->data(), page_size);
     {
         SCOPED_RAW_TIMER(&opts.stats->io_ns);
@@ -190,7 +184,7 @@ Status PageIO::read_and_decompress_page(const 
PageReadOptions& opts, PageHandle*
         }
         SCOPED_RAW_TIMER(&opts.stats->decompress_ns);
         std::unique_ptr<DataPage> decompressed_page = 
std::make_unique<DataPage>(
-                footer->uncompressed_size() + footer_size + 4, 
page_mem_tracker);
+                footer->uncompressed_size() + footer_size + 4, 
opts.use_page_cache, opts.type);
 
         // decompress page body
         Slice compressed_body(page_slice.data, body_size);
@@ -218,7 +212,7 @@ Status PageIO::read_and_decompress_page(const 
PageReadOptions& opts, PageHandle*
         if (pre_decoder) {
             RETURN_IF_ERROR(pre_decoder->decode(
                     &page, &page_slice, 
footer->data_page_footer().nullmap_size() + footer_size + 4,
-                    page_mem_tracker));
+                    opts.use_page_cache, opts.type));
         }
     }
 
diff --git a/be/src/olap/schema_cache.h b/be/src/olap/schema_cache.h
index 047132e6568..233d40ede77 100644
--- a/be/src/olap/schema_cache.h
+++ b/be/src/olap/schema_cache.h
@@ -44,7 +44,7 @@ using SegmentIteratorUPtr = std::unique_ptr<SegmentIterator>;
 // eliminating the need for frequent allocation and deallocation during usage.
 // This caching mechanism proves immensely advantageous, particularly in 
scenarios
 // with high concurrency, where queries are executed simultaneously.
-class SchemaCache : public LRUCachePolicy {
+class SchemaCache : public LRUCachePolicyTrackingManual {
 public:
     enum class Type { TABLET_SCHEMA = 0, SCHEMA = 1 };
 
@@ -104,8 +104,6 @@ public:
 
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue() : LRUCacheValueBase(CachePolicy::CacheType::SCHEMA_CACHE) 
{}
-
         Type type;
         // either tablet_schema or schema
         TabletSchemaSPtr tablet_schema = nullptr;
@@ -113,8 +111,9 @@ public:
     };
 
     SchemaCache(size_t capacity)
-            : LRUCachePolicy(CachePolicy::CacheType::SCHEMA_CACHE, capacity, 
LRUCacheType::NUMBER,
-                             config::schema_cache_sweep_time_sec) {}
+            : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::SCHEMA_CACHE, capacity,
+                                           LRUCacheType::NUMBER,
+                                           
config::schema_cache_sweep_time_sec) {}
 
 private:
     static constexpr char SCHEMA_DELIMITER = '-';
diff --git a/be/src/olap/segment_loader.cpp b/be/src/olap/segment_loader.cpp
index fd7e3f476ad..12ab89af0be 100644
--- a/be/src/olap/segment_loader.cpp
+++ b/be/src/olap/segment_loader.cpp
@@ -40,9 +40,9 @@ bool SegmentCache::lookup(const SegmentCache::CacheKey& key, 
SegmentCacheHandle*
 
 void SegmentCache::insert(const SegmentCache::CacheKey& key, 
SegmentCache::CacheValue& value,
                           SegmentCacheHandle* handle) {
-    auto* lru_handle =
-            LRUCachePolicy::insert(key.encode(), &value, 
value.segment->meta_mem_usage(),
-                                   value.segment->meta_mem_usage(), 
CachePriority::NORMAL);
+    auto* lru_handle = LRUCachePolicyTrackingManual::insert(
+            key.encode(), &value, value.segment->meta_mem_usage(), 
value.segment->meta_mem_usage(),
+            CachePriority::NORMAL);
     handle->push_segment(this, lru_handle);
 }
 
diff --git a/be/src/olap/segment_loader.h b/be/src/olap/segment_loader.h
index cd0f7799abe..4d1f3f7a910 100644
--- a/be/src/olap/segment_loader.h
+++ b/be/src/olap/segment_loader.h
@@ -55,8 +55,9 @@ class BetaRowset;
 // Make sure that cache_handle is valid during the segment usage period.
 using BetaRowsetSharedPtr = std::shared_ptr<BetaRowset>;
 
-class SegmentCache : public LRUCachePolicy {
+class SegmentCache : public LRUCachePolicyTrackingManual {
 public:
+    using LRUCachePolicyTrackingManual::insert;
     // The cache key or segment lru cache
     struct CacheKey {
         CacheKey(RowsetId rowset_id_, int64_t segment_id_)
@@ -74,15 +75,15 @@ public:
     // Holding all opened segments of a rowset.
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::SEGMENT_CACHE) {}
         ~CacheValue() override { segment.reset(); }
 
         segment_v2::SegmentSharedPtr segment;
     };
 
     SegmentCache(size_t capacity)
-            : LRUCachePolicy(CachePolicy::CacheType::SEGMENT_CACHE, capacity, 
LRUCacheType::SIZE,
-                             config::tablet_rowset_stale_sweep_time_sec) {}
+            : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::SEGMENT_CACHE, capacity,
+                                           LRUCacheType::SIZE,
+                                           
config::tablet_rowset_stale_sweep_time_sec) {}
 
     // Lookup the given segment in the cache.
     // If the segment is found, the cache entry will be written into handle.
diff --git a/be/src/olap/storage_engine.h b/be/src/olap/storage_engine.h
index 2907c4b7a9b..94cf142a8c1 100644
--- a/be/src/olap/storage_engine.h
+++ b/be/src/olap/storage_engine.h
@@ -506,7 +506,7 @@ private:
 // lru cache for create tabelt round robin in disks
 // key: partitionId_medium
 // value: index
-class CreateTabletIdxCache : public LRUCachePolicy {
+class CreateTabletIdxCache : public LRUCachePolicyTrackingManual {
 public:
     // get key, delimiter with DELIMITER '-'
     static std::string get_key(int64_t partition_id, TStorageMedium::type 
medium) {
@@ -520,15 +520,13 @@ public:
 
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::CREATE_TABLET_RR_IDX_CACHE) {}
-
         int idx = 0;
     };
 
     CreateTabletIdxCache(size_t capacity)
-            : 
LRUCachePolicy(CachePolicy::CacheType::CREATE_TABLET_RR_IDX_CACHE, capacity,
-                             LRUCacheType::NUMBER,
-                             /*stale_sweep_time_s*/ 30 * 60) {}
+            : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::CREATE_TABLET_RR_IDX_CACHE,
+                                           capacity, LRUCacheType::NUMBER,
+                                           /*stale_sweep_time_s*/ 30 * 60) {}
 };
 
 struct DirInfo {
diff --git a/be/src/olap/tablet_meta.h b/be/src/olap/tablet_meta.h
index e9ae4314b13..b13bf2f0853 100644
--- a/be/src/olap/tablet_meta.h
+++ b/be/src/olap/tablet_meta.h
@@ -516,20 +516,19 @@ public:
      */
     std::shared_ptr<roaring::Roaring> get_agg(const BitmapKey& bmk) const;
 
-    class AggCachePolicy : public LRUCachePolicy {
+    class AggCachePolicy : public LRUCachePolicyTrackingManual {
     public:
         AggCachePolicy(size_t capacity)
-                : 
LRUCachePolicy(CachePolicy::CacheType::DELETE_BITMAP_AGG_CACHE, capacity,
-                                 LRUCacheType::SIZE,
-                                 
config::delete_bitmap_agg_cache_stale_sweep_time_sec, 256) {}
+                : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::DELETE_BITMAP_AGG_CACHE,
+                                               capacity, LRUCacheType::SIZE,
+                                               
config::delete_bitmap_agg_cache_stale_sweep_time_sec,
+                                               256) {}
     };
 
     class AggCache {
     public:
         class Value : public LRUCacheValueBase {
         public:
-            Value() : 
LRUCacheValueBase(CachePolicy::CacheType::DELETE_BITMAP_AGG_CACHE) {}
-
             roaring::Roaring bitmap;
         };
 
diff --git a/be/src/olap/tablet_schema_cache.cpp 
b/be/src/olap/tablet_schema_cache.cpp
index e339c947bb9..51618f590a7 100644
--- a/be/src/olap/tablet_schema_cache.cpp
+++ b/be/src/olap/tablet_schema_cache.cpp
@@ -40,8 +40,8 @@ std::pair<Cache::Handle*, TabletSchemaSPtr> 
TabletSchemaCache::insert(const std:
         pb.ParseFromString(key);
         tablet_schema_ptr->init_from_pb(pb);
         value->tablet_schema = tablet_schema_ptr;
-        lru_handle = LRUCachePolicy::insert(key, value, 
tablet_schema_ptr->num_columns(), 0,
-                                            CachePriority::NORMAL);
+        lru_handle = LRUCachePolicyTrackingManual::insert(
+                key, value, tablet_schema_ptr->num_columns(), 0, 
CachePriority::NORMAL);
         g_tablet_schema_cache_count << 1;
         g_tablet_schema_cache_columns_count << 
tablet_schema_ptr->num_columns();
     }
diff --git a/be/src/olap/tablet_schema_cache.h 
b/be/src/olap/tablet_schema_cache.h
index 447be401eca..10462804ed2 100644
--- a/be/src/olap/tablet_schema_cache.h
+++ b/be/src/olap/tablet_schema_cache.h
@@ -23,11 +23,14 @@
 
 namespace doris {
 
-class TabletSchemaCache : public LRUCachePolicy {
+class TabletSchemaCache : public LRUCachePolicyTrackingManual {
 public:
+    using LRUCachePolicyTrackingManual::insert;
+
     TabletSchemaCache(size_t capacity)
-            : LRUCachePolicy(CachePolicy::CacheType::TABLET_SCHEMA_CACHE, 
capacity,
-                             LRUCacheType::NUMBER, 
config::tablet_schema_cache_recycle_interval) {}
+            : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::TABLET_SCHEMA_CACHE, 
capacity,
+                                           LRUCacheType::NUMBER,
+                                           
config::tablet_schema_cache_recycle_interval) {}
 
     static TabletSchemaCache* create_global_schema_cache(size_t capacity) {
         auto* res = new TabletSchemaCache(capacity);
@@ -45,7 +48,6 @@ public:
 private:
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::TABLET_SCHEMA_CACHE) {}
         ~CacheValue() override;
 
         TabletSchemaSPtr tablet_schema;
diff --git a/be/src/olap/txn_manager.h b/be/src/olap/txn_manager.h
index 9fd528b91a7..d201494b24f 100644
--- a/be/src/olap/txn_manager.h
+++ b/be/src/olap/txn_manager.h
@@ -130,8 +130,6 @@ public:
 
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::TABLET_VERSION_CACHE) {}
-
         int64_t value;
     };
 
@@ -268,12 +266,13 @@ private:
     void _insert_txn_partition_map_unlocked(int64_t transaction_id, int64_t 
partition_id);
     void _clear_txn_partition_map_unlocked(int64_t transaction_id, int64_t 
partition_id);
 
-    class TabletVersionCache : public LRUCachePolicy {
+    class TabletVersionCache : public LRUCachePolicyTrackingManual {
     public:
         TabletVersionCache(size_t capacity)
-                : LRUCachePolicy(CachePolicy::CacheType::TABLET_VERSION_CACHE, 
capacity,
-                                 LRUCacheType::NUMBER, -1, 
DEFAULT_LRU_CACHE_NUM_SHARDS,
-                                 DEFAULT_LRU_CACHE_ELEMENT_COUNT_CAPACITY, 
false) {}
+                : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::TABLET_VERSION_CACHE,
+                                               capacity, LRUCacheType::NUMBER, 
-1,
+                                               DEFAULT_LRU_CACHE_NUM_SHARDS,
+                                               
DEFAULT_LRU_CACHE_ELEMENT_COUNT_CAPACITY, false) {}
     };
 
 private:
diff --git a/be/src/runtime/load_channel_mgr.h 
b/be/src/runtime/load_channel_mgr.h
index 94bd210f262..c9c8f4c2a0f 100644
--- a/be/src/runtime/load_channel_mgr.h
+++ b/be/src/runtime/load_channel_mgr.h
@@ -72,12 +72,13 @@ private:
 
     Status _start_bg_worker();
 
-    class LastSuccessChannelCache : public LRUCachePolicy {
+    class LastSuccessChannelCache : public LRUCachePolicyTrackingManual {
     public:
         LastSuccessChannelCache(size_t capacity)
-                : 
LRUCachePolicy(CachePolicy::CacheType::LAST_SUCCESS_CHANNEL_CACHE, capacity,
-                                 LRUCacheType::SIZE, -1, 
DEFAULT_LRU_CACHE_NUM_SHARDS,
-                                 DEFAULT_LRU_CACHE_ELEMENT_COUNT_CAPACITY, 
false) {}
+                : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::LAST_SUCCESS_CHANNEL_CACHE,
+                                               capacity, LRUCacheType::SIZE, 
-1,
+                                               DEFAULT_LRU_CACHE_NUM_SHARDS,
+                                               
DEFAULT_LRU_CACHE_ELEMENT_COUNT_CAPACITY, false) {}
     };
 
 protected:
diff --git a/be/src/runtime/memory/cache_manager.h 
b/be/src/runtime/memory/cache_manager.h
index 4eff752a62b..20372366aa1 100644
--- a/be/src/runtime/memory/cache_manager.h
+++ b/be/src/runtime/memory/cache_manager.h
@@ -59,8 +59,6 @@ public:
         LOG(INFO) << "Unregister Cache " << CachePolicy::type_string(type);
     }
 
-    CachePolicy* get_cache(CachePolicy::CacheType type) { return 
_caches.at(type); }
-
     int64_t for_each_cache_prune_stale_wrap(std::function<void(CachePolicy* 
cache_policy)> func,
                                             RuntimeProfile* profile = nullptr);
 
diff --git a/be/src/runtime/memory/cache_policy.h 
b/be/src/runtime/memory/cache_policy.h
index 75bf4881894..e59c5c7ac3e 100644
--- a/be/src/runtime/memory/cache_policy.h
+++ b/be/src/runtime/memory/cache_policy.h
@@ -18,7 +18,6 @@
 #pragma once
 
 #include "runtime/exec_env.h"
-#include "runtime/memory/mem_tracker_limiter.h"
 #include "util/runtime_profile.h"
 
 namespace doris {
@@ -102,30 +101,6 @@ public:
     virtual void prune_all(bool force) = 0;
 
     CacheType type() { return _type; }
-    void init_mem_tracker(const std::string& type_name) {
-        _mem_tracker =
-                std::make_unique<MemTracker>(fmt::format("{}[{}]", 
type_string(_type), type_name),
-                                             
ExecEnv::GetInstance()->details_mem_tracker_set());
-    }
-    MemTracker* mem_tracker() { return _mem_tracker.get(); }
-    void init_mem_tracker_by_allocator(const std::string& type_name) {
-        _mem_tracker_by_allocator = MemTrackerLimiter::create_shared(
-                MemTrackerLimiter::Type::GLOBAL,
-                fmt::format("{}[{}](AllocByAllocator)", type_string(_type), 
type_name));
-    }
-    std::shared_ptr<MemTrackerLimiter> mem_tracker_by_allocator() const {
-        DCHECK(_mem_tracker_by_allocator != nullptr);
-        return _mem_tracker_by_allocator;
-    }
-    int64_t mem_consumption() {
-        if (_mem_tracker_by_allocator != nullptr) {
-            return _mem_tracker_by_allocator->consumption();
-        } else if (_mem_tracker != nullptr) {
-            return _mem_tracker->consumption();
-        }
-        LOG(FATAL) << "__builtin_unreachable";
-        __builtin_unreachable();
-    }
     bool enable_prune() const { return _enable_prune; }
     RuntimeProfile* profile() { return _profile.get(); }
 
@@ -142,9 +117,6 @@ protected:
 
     CacheType _type;
 
-    std::unique_ptr<MemTracker> _mem_tracker;
-    std::shared_ptr<MemTrackerLimiter> _mem_tracker_by_allocator;
-
     std::unique_ptr<RuntimeProfile> _profile;
     RuntimeProfile::Counter* _prune_stale_number_counter = nullptr;
     RuntimeProfile::Counter* _prune_all_number_counter = nullptr;
diff --git a/be/src/runtime/memory/lru_cache_policy.h 
b/be/src/runtime/memory/lru_cache_policy.h
index 773817393c7..1b6c9ead6d0 100644
--- a/be/src/runtime/memory/lru_cache_policy.h
+++ b/be/src/runtime/memory/lru_cache_policy.h
@@ -24,6 +24,7 @@
 #include "olap/lru_cache.h"
 #include "runtime/memory/cache_policy.h"
 #include "runtime/memory/lru_cache_value_base.h"
+#include "runtime/memory/mem_tracker_limiter.h"
 #include "runtime/thread_context.h"
 #include "util/time.h"
 
@@ -45,7 +46,6 @@ public:
             CHECK(ExecEnv::GetInstance()->get_dummy_lru_cache());
             _cache = ExecEnv::GetInstance()->get_dummy_lru_cache();
         }
-        init_mem_tracker(lru_cache_type_string(_lru_cache_type));
     }
 
     LRUCachePolicy(CacheType type, size_t capacity, LRUCacheType 
lru_cache_type,
@@ -63,10 +63,9 @@ public:
             CHECK(ExecEnv::GetInstance()->get_dummy_lru_cache());
             _cache = ExecEnv::GetInstance()->get_dummy_lru_cache();
         }
-        init_mem_tracker(lru_cache_type_string(_lru_cache_type));
     }
 
-    ~LRUCachePolicy() override { _cache.reset(); }
+    void reset_cache() { _cache.reset(); }
 
     bool check_capacity(size_t capacity, uint32_t num_shards) {
         if (capacity < num_shards) {
@@ -91,23 +90,11 @@ public:
         }
     }
 
-    // Insert and cache value destroy will be manually consume tracking_bytes 
to mem tracker.
-    // If lru cache is LRUCacheType::SIZE, tracking_bytes usually equal to 
charge.
-    Cache::Handle* insert(const CacheKey& key, void* value, size_t charge, 
size_t tracking_bytes,
-                          CachePriority priority = CachePriority::NORMAL) {
-        size_t bytes_with_handle = _get_bytes_with_handle(key, charge, 
tracking_bytes);
-        if (value != nullptr) { // if tracking_bytes = 0, only tracking handle 
size.
-            
((LRUCacheValueBase*)value)->mem_tracker()->consume(bytes_with_handle);
-            ((LRUCacheValueBase*)value)->set_tracking_bytes(bytes_with_handle);
-        }
-        return _cache->insert(key, value, charge, priority);
-    }
+    virtual int64_t mem_consumption() = 0;
 
-    Cache::Handle* insert_no_tracking(const CacheKey& key, void* value, size_t 
charge,
-                                      CachePriority priority = 
CachePriority::NORMAL) {
-        DCHECK(_mem_tracker_by_allocator != nullptr); // must be tracking in 
Allcator.
-        return _cache->insert(key, value, charge, priority);
-    }
+    virtual Cache::Handle* insert(const CacheKey& key, void* value, size_t 
charge,
+                                  size_t tracking_bytes,
+                                  CachePriority priority = 
CachePriority::NORMAL) = 0;
 
     Cache::Handle* lookup(const CacheKey& key) { return _cache->lookup(key); }
 
@@ -208,7 +195,117 @@ public:
         }
     }
 
+protected:
+    // if check_capacity failed, will return dummy lru cache,
+    // compatible with ShardedLRUCache usage, but will not actually cache.
+    std::shared_ptr<Cache> _cache;
+    LRUCacheType _lru_cache_type;
+};
+
+class LRUCachePolicyTrackingAllocator : public LRUCachePolicy {
+public:
+    LRUCachePolicyTrackingAllocator(
+            CacheType type, size_t capacity, LRUCacheType lru_cache_type,
+            uint32_t stale_sweep_time_s, uint32_t num_shards = 
DEFAULT_LRU_CACHE_NUM_SHARDS,
+            uint32_t element_count_capacity = 
DEFAULT_LRU_CACHE_ELEMENT_COUNT_CAPACITY,
+            bool enable_prune = true)
+            : LRUCachePolicy(type, capacity, lru_cache_type, 
stale_sweep_time_s, num_shards,
+                             element_count_capacity, enable_prune) {
+        _init_mem_tracker(lru_cache_type_string(lru_cache_type));
+    }
+
+    LRUCachePolicyTrackingAllocator(CacheType type, size_t capacity, 
LRUCacheType lru_cache_type,
+                                    uint32_t stale_sweep_time_s, uint32_t 
num_shards,
+                                    uint32_t element_count_capacity,
+                                    CacheValueTimeExtractor 
cache_value_time_extractor,
+                                    bool cache_value_check_timestamp, bool 
enable_prune = true)
+            : LRUCachePolicy(type, capacity, lru_cache_type, 
stale_sweep_time_s, num_shards,
+                             element_count_capacity, 
cache_value_time_extractor,
+                             cache_value_check_timestamp, enable_prune) {
+        _init_mem_tracker(lru_cache_type_string(lru_cache_type));
+    }
+
+    ~LRUCachePolicyTrackingAllocator() override { reset_cache(); }
+
+    std::shared_ptr<MemTrackerLimiter> mem_tracker() const {
+        DCHECK(_mem_tracker != nullptr);
+        return _mem_tracker;
+    }
+
+    int64_t mem_consumption() override {
+        DCHECK(_mem_tracker != nullptr);
+        return _mem_tracker->consumption();
+    }
+
+    Cache::Handle* insert(const CacheKey& key, void* value, size_t charge, 
size_t tracking_bytes,
+                          CachePriority priority = CachePriority::NORMAL) 
override {
+        return _cache->insert(key, value, charge, priority);
+    }
+
+protected:
+    void _init_mem_tracker(const std::string& type_name) {
+        _mem_tracker = MemTrackerLimiter::create_shared(
+                MemTrackerLimiter::Type::GLOBAL,
+                fmt::format("{}[{}](AllocByAllocator)", type_string(_type), 
type_name));
+    }
+
+    std::shared_ptr<MemTrackerLimiter> _mem_tracker;
+};
+
+class LRUCachePolicyTrackingManual : public LRUCachePolicy {
+public:
+    LRUCachePolicyTrackingManual(
+            CacheType type, size_t capacity, LRUCacheType lru_cache_type,
+            uint32_t stale_sweep_time_s, uint32_t num_shards = 
DEFAULT_LRU_CACHE_NUM_SHARDS,
+            uint32_t element_count_capacity = 
DEFAULT_LRU_CACHE_ELEMENT_COUNT_CAPACITY,
+            bool enable_prune = true)
+            : LRUCachePolicy(type, capacity, lru_cache_type, 
stale_sweep_time_s, num_shards,
+                             element_count_capacity, enable_prune) {
+        _init_mem_tracker(lru_cache_type_string(lru_cache_type));
+    }
+
+    LRUCachePolicyTrackingManual(CacheType type, size_t capacity, LRUCacheType 
lru_cache_type,
+                                 uint32_t stale_sweep_time_s, uint32_t 
num_shards,
+                                 uint32_t element_count_capacity,
+                                 CacheValueTimeExtractor 
cache_value_time_extractor,
+                                 bool cache_value_check_timestamp, bool 
enable_prune = true)
+            : LRUCachePolicy(type, capacity, lru_cache_type, 
stale_sweep_time_s, num_shards,
+                             element_count_capacity, 
cache_value_time_extractor,
+                             cache_value_check_timestamp, enable_prune) {
+        _init_mem_tracker(lru_cache_type_string(lru_cache_type));
+    }
+
+    ~LRUCachePolicyTrackingManual() override { reset_cache(); }
+
+    MemTracker* mem_tracker() {
+        DCHECK(_mem_tracker != nullptr);
+        return _mem_tracker.get();
+    }
+
+    int64_t mem_consumption() override {
+        DCHECK(_mem_tracker != nullptr);
+        return _mem_tracker->consumption();
+    }
+
+    // Insert and cache value destroy will be manually consume tracking_bytes 
to mem tracker.
+    // If lru cache is LRUCacheType::SIZE, tracking_bytes usually equal to 
charge.
+    Cache::Handle* insert(const CacheKey& key, void* value, size_t charge, 
size_t tracking_bytes,
+                          CachePriority priority = CachePriority::NORMAL) 
override {
+        size_t bytes_with_handle = _get_bytes_with_handle(key, charge, 
tracking_bytes);
+        if (value != nullptr) { // if tracking_bytes = 0, only tracking handle 
size.
+            mem_tracker()->consume(bytes_with_handle);
+            ((LRUCacheValueBase*)value)->set_tracking_bytes(bytes_with_handle, 
mem_tracker());
+        }
+        return _cache->insert(key, value, charge, priority);
+    }
+
 private:
+    void _init_mem_tracker(const std::string& type_name) {
+        _mem_tracker =
+                std::make_unique<MemTracker>(fmt::format("{}[{}]", 
type_string(_type), type_name),
+                                             
ExecEnv::GetInstance()->details_mem_tracker_set());
+    }
+
     // LRUCacheType::SIZE equal to total_size.
     size_t _get_bytes_with_handle(const CacheKey& key, size_t charge, size_t 
bytes) {
         size_t handle_size = sizeof(LRUHandle) - 1 + key.size();
@@ -219,10 +316,7 @@ private:
         return _lru_cache_type == LRUCacheType::SIZE ? handle_size + charge : 
handle_size + bytes;
     }
 
-    // if check_capacity failed, will return dummy lru cache,
-    // compatible with ShardedLRUCache usage, but will not actually cache.
-    std::shared_ptr<Cache> _cache;
-    LRUCacheType _lru_cache_type;
+    std::unique_ptr<MemTracker> _mem_tracker;
 };
 
 } // namespace doris
diff --git a/be/src/runtime/memory/lru_cache_value_base.h 
b/be/src/runtime/memory/lru_cache_value_base.h
index 08a689f3fd0..6d4b2991a02 100644
--- a/be/src/runtime/memory/lru_cache_value_base.h
+++ b/be/src/runtime/memory/lru_cache_value_base.h
@@ -25,20 +25,16 @@ namespace doris {
 // Base of the lru cache value.
 class LRUCacheValueBase {
 public:
-    LRUCacheValueBase() = default;
-    LRUCacheValueBase(CachePolicy::CacheType type) {
-        _mem_tracker = 
CacheManager::instance()->get_cache(type)->mem_tracker();
-    }
-
     virtual ~LRUCacheValueBase() {
         if (_tracking_bytes > 0) {
             _mem_tracker->consume(-_tracking_bytes);
         }
     }
 
-    void set_tracking_bytes(size_t tracking_bytes) { this->_tracking_bytes = 
tracking_bytes; }
-
-    MemTracker* mem_tracker() const { return _mem_tracker; }
+    void set_tracking_bytes(size_t tracking_bytes, MemTracker* mem_tracker) {
+        this->_tracking_bytes = tracking_bytes;
+        this->_mem_tracker = mem_tracker;
+    }
 
 protected:
     size_t _tracking_bytes = 0;
diff --git a/be/src/service/point_query_executor.cpp 
b/be/src/service/point_query_executor.cpp
index 8078467d5ca..81be6fa208c 100644
--- a/be/src/service/point_query_executor.cpp
+++ b/be/src/service/point_query_executor.cpp
@@ -186,9 +186,9 @@ LookupConnectionCache* 
LookupConnectionCache::create_global_instance(size_t capa
 }
 
 RowCache::RowCache(int64_t capacity, int num_shards)
-        : LRUCachePolicy(CachePolicy::CacheType::POINT_QUERY_ROW_CACHE, 
capacity,
-                         LRUCacheType::SIZE, 
config::point_query_row_cache_stale_sweep_time_sec,
-                         num_shards) {}
+        : LRUCachePolicyTrackingManual(
+                  CachePolicy::CacheType::POINT_QUERY_ROW_CACHE, capacity, 
LRUCacheType::SIZE,
+                  config::point_query_row_cache_stale_sweep_time_sec, 
num_shards) {}
 
 // Create global instance of this class
 RowCache* RowCache::create_global_cache(int64_t capacity, uint32_t num_shards) 
{
@@ -218,8 +218,8 @@ void RowCache::insert(const RowCacheKey& key, const Slice& 
value) {
     auto* row_cache_value = new RowCacheValue;
     row_cache_value->cache_value = cache_value;
     const std::string& encoded_key = key.encode();
-    auto* handle = LRUCachePolicy::insert(encoded_key, row_cache_value, 
value.size, value.size,
-                                          CachePriority::NORMAL);
+    auto* handle = LRUCachePolicyTrackingManual::insert(encoded_key, 
row_cache_value, value.size,
+                                                        value.size, 
CachePriority::NORMAL);
     // handle will released
     auto tmp = CacheHandle {this, handle};
 }
diff --git a/be/src/service/point_query_executor.h 
b/be/src/service/point_query_executor.h
index f374e094806..29c7348e3d5 100644
--- a/be/src/service/point_query_executor.h
+++ b/be/src/service/point_query_executor.h
@@ -121,8 +121,10 @@ private:
 };
 
 // RowCache is a LRU cache for row store
-class RowCache : public LRUCachePolicy {
+class RowCache : public LRUCachePolicyTrackingManual {
 public:
+    using LRUCachePolicyTrackingManual::insert;
+
     // The cache key for row lru cache
     struct RowCacheKey {
         RowCacheKey(int64_t tablet_id, const Slice& key) : 
tablet_id(tablet_id), key(key) {}
@@ -141,7 +143,6 @@ public:
 
     class RowCacheValue : public LRUCacheValueBase {
     public:
-        RowCacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::POINT_QUERY_ROW_CACHE) {}
         ~RowCacheValue() override { free(cache_value); }
         char* cache_value;
     };
@@ -214,7 +215,7 @@ private:
 
 // A cache used for prepare stmt.
 // One connection per stmt perf uuid
-class LookupConnectionCache : public LRUCachePolicy {
+class LookupConnectionCache : public LRUCachePolicyTrackingManual {
 public:
     static LookupConnectionCache* instance() {
         return ExecEnv::GetInstance()->get_lookup_connection_cache();
@@ -225,9 +226,9 @@ public:
 private:
     friend class PointQueryExecutor;
     LookupConnectionCache(size_t capacity)
-            : LRUCachePolicy(CachePolicy::CacheType::LOOKUP_CONNECTION_CACHE, 
capacity,
-                             LRUCacheType::NUMBER,
-                             config::tablet_lookup_cache_stale_sweep_time_sec) 
{}
+            : 
LRUCachePolicyTrackingManual(CachePolicy::CacheType::LOOKUP_CONNECTION_CACHE,
+                                           capacity, LRUCacheType::NUMBER,
+                                           
config::tablet_lookup_cache_stale_sweep_time_sec) {}
 
     static std::string encode_key(__int128_t cache_id) {
         fmt::memory_buffer buffer;
@@ -259,8 +260,6 @@ private:
 
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue() : 
LRUCacheValueBase(CachePolicy::CacheType::LOOKUP_CONNECTION_CACHE) {}
-
         std::shared_ptr<Reusable> item;
     };
 };
diff --git a/be/src/util/obj_lru_cache.cpp b/be/src/util/obj_lru_cache.cpp
index 600ffdb647c..05b8b8824b5 100644
--- a/be/src/util/obj_lru_cache.cpp
+++ b/be/src/util/obj_lru_cache.cpp
@@ -20,9 +20,9 @@
 namespace doris {
 
 ObjLRUCache::ObjLRUCache(int64_t capacity, uint32_t num_shards)
-        : LRUCachePolicy(CachePolicy::CacheType::COMMON_OBJ_LRU_CACHE, 
capacity,
-                         LRUCacheType::NUMBER, 
config::common_obj_lru_cache_stale_sweep_time_sec,
-                         num_shards) {
+        : LRUCachePolicyTrackingManual(
+                  CachePolicy::CacheType::COMMON_OBJ_LRU_CACHE, capacity, 
LRUCacheType::NUMBER,
+                  config::common_obj_lru_cache_stale_sweep_time_sec, 
num_shards) {
     _enabled = (capacity > 0);
 }
 
diff --git a/be/src/util/obj_lru_cache.h b/be/src/util/obj_lru_cache.h
index 7f50ab05114..c7f805fc3a1 100644
--- a/be/src/util/obj_lru_cache.h
+++ b/be/src/util/obj_lru_cache.h
@@ -25,8 +25,10 @@ namespace doris {
 // A common object cache depends on an Sharded LRU Cache.
 // It has a certain capacity, which determin how many objects it can cache.
 // Caller must hold a CacheHandle instance when visiting the cached object.
-class ObjLRUCache : public LRUCachePolicy {
+class ObjLRUCache : public LRUCachePolicyTrackingManual {
 public:
+    using LRUCachePolicyTrackingManual::insert;
+
     struct ObjKey {
         ObjKey(const std::string& key_) : key(key_) {}
 
@@ -36,8 +38,7 @@ public:
     template <typename T>
     class ObjValue : public LRUCacheValueBase {
     public:
-        ObjValue(const T* value)
-                : 
LRUCacheValueBase(CachePolicy::CacheType::COMMON_OBJ_LRU_CACHE), value(value) {}
+        ObjValue(const T* value) : value(value) {}
         ~ObjValue() override {
             T* v = (T*)value;
             delete v;
@@ -93,8 +94,8 @@ public:
         if (_enabled) {
             const std::string& encoded_key = key.key;
             auto* obj_value = new ObjValue<T>(value);
-            auto* handle = LRUCachePolicy::insert(encoded_key, obj_value, 1, 
sizeof(T),
-                                                  CachePriority::NORMAL);
+            auto* handle = LRUCachePolicyTrackingManual::insert(encoded_key, 
obj_value, 1,
+                                                                sizeof(T), 
CachePriority::NORMAL);
             *cache_handle = CacheHandle {this, handle};
         } else {
             cache_handle = nullptr;
diff --git a/be/test/olap/lru_cache_test.cpp b/be/test/olap/lru_cache_test.cpp
index 0d1890fe4de..4fc096380c7 100644
--- a/be/test/olap/lru_cache_test.cpp
+++ b/be/test/olap/lru_cache_test.cpp
@@ -71,8 +71,7 @@ public:
 
     class CacheValueWithKey : public LRUCacheValueBase {
     public:
-        CacheValueWithKey(int key, void* value)
-                : LRUCacheValueBase(CachePolicy::CacheType::FOR_UT), key(key), 
value(value) {}
+        CacheValueWithKey(int key, void* value) : key(key), value(value) {}
         ~CacheValueWithKey() override {
             _s_current->_deleted_keys.push_back(key);
             _s_current->_deleted_values.push_back(DecodeValue(value));
@@ -84,17 +83,16 @@ public:
 
     class CacheValue : public LRUCacheValueBase {
     public:
-        CacheValue(void* value) : 
LRUCacheValueBase(CachePolicy::CacheType::FOR_UT), value(value) {}
-        ~CacheValue() override = default;
+        CacheValue(void* value) : value(value) {}
 
         void* value;
     };
 
-    class CacheTestPolicy : public LRUCachePolicy {
+    class CacheTestPolicy : public LRUCachePolicyTrackingManual {
     public:
         CacheTestPolicy(size_t capacity)
-                : LRUCachePolicy(CachePolicy::CacheType::FOR_UT, capacity, 
LRUCacheType::SIZE, -1) {
-        }
+                : LRUCachePolicyTrackingManual(CachePolicy::CacheType::FOR_UT, 
capacity,
+                                               LRUCacheType::SIZE, -1) {}
     };
 
     // there is 16 shards in ShardedLRUCache
diff --git a/be/test/olap/page_cache_test.cpp b/be/test/olap/page_cache_test.cpp
index a0b1ea2c233..1feb6152add 100644
--- a/be/test/olap/page_cache_test.cpp
+++ b/be/test/olap/page_cache_test.cpp
@@ -39,7 +39,6 @@ public:
 
 // All cache space is allocated to data pages
 TEST_F(StoragePageCacheTest, data_page_only) {
-    std::cout << "44444" << std::endl;
     StoragePageCache cache(kNumShards * 2048, 0, 0, kNumShards);
 
     StoragePageCache::CacheKey key("abc", 0, 0);
@@ -50,7 +49,7 @@ TEST_F(StoragePageCacheTest, data_page_only) {
     {
         // insert normal page
         PageCacheHandle handle;
-        auto* data = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type);
         cache.insert(key, data, &handle, page_type, false);
 
         EXPECT_EQ(handle.data().data, data->data());
@@ -63,7 +62,7 @@ TEST_F(StoragePageCacheTest, data_page_only) {
     {
         // insert in_memory page
         PageCacheHandle handle;
-        auto* data = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type);
         cache.insert(memory_key, data, &handle, page_type, true);
 
         EXPECT_EQ(handle.data().data, data->data());
@@ -76,7 +75,7 @@ TEST_F(StoragePageCacheTest, data_page_only) {
     for (int i = 0; i < 10 * kNumShards; ++i) {
         StoragePageCache::CacheKey key("bcd", 0, i);
         PageCacheHandle handle;
-        auto* data = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type);
         cache.insert(key, data, &handle, page_type, false);
     }
 
@@ -106,7 +105,6 @@ TEST_F(StoragePageCacheTest, data_page_only) {
 
 // All cache space is allocated to index pages
 TEST_F(StoragePageCacheTest, index_page_only) {
-    std::cout << "33333" << std::endl;
     StoragePageCache cache(kNumShards * 2048, 100, 0, kNumShards);
 
     StoragePageCache::CacheKey key("abc", 0, 0);
@@ -117,7 +115,7 @@ TEST_F(StoragePageCacheTest, index_page_only) {
     {
         // insert normal page
         PageCacheHandle handle;
-        auto* data = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type);
         cache.insert(key, data, &handle, page_type, false);
 
         EXPECT_EQ(handle.data().data, data->data());
@@ -130,7 +128,7 @@ TEST_F(StoragePageCacheTest, index_page_only) {
     {
         // insert in_memory page
         PageCacheHandle handle;
-        auto* data = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type);
         cache.insert(memory_key, data, &handle, page_type, true);
 
         EXPECT_EQ(handle.data().data, data->data());
@@ -143,7 +141,7 @@ TEST_F(StoragePageCacheTest, index_page_only) {
     for (int i = 0; i < 10 * kNumShards; ++i) {
         StoragePageCache::CacheKey key("bcd", 0, i);
         PageCacheHandle handle;
-        auto* data = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type);
         cache.insert(key, data, &handle, page_type, false);
     }
 
@@ -186,8 +184,8 @@ TEST_F(StoragePageCacheTest, mixed_pages) {
     {
         // insert both normal pages
         PageCacheHandle data_handle, index_handle;
-        auto* data = new DataPage(1024, mem_tracker);
-        auto* index = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type_data);
+        auto* index = new DataPage(1024, true, page_type_index);
         cache.insert(data_key, data, &data_handle, page_type_data, false);
         cache.insert(index_key, index, &index_handle, page_type_index, false);
 
@@ -205,8 +203,8 @@ TEST_F(StoragePageCacheTest, mixed_pages) {
     {
         // insert both in_memory pages
         PageCacheHandle data_handle, index_handle;
-        auto* data = new DataPage(1024, mem_tracker);
-        auto* index = new DataPage(1024, mem_tracker);
+        auto* data = new DataPage(1024, true, page_type_data);
+        auto* index = new DataPage(1024, true, page_type_index);
         cache.insert(data_key_mem, data, &data_handle, page_type_data, true);
         cache.insert(index_key_mem, index, &index_handle, page_type_index, 
true);
 
@@ -223,8 +221,8 @@ TEST_F(StoragePageCacheTest, mixed_pages) {
     for (int i = 0; i < 10 * kNumShards; ++i) {
         StoragePageCache::CacheKey key("bcd", 0, i);
         PageCacheHandle handle;
-        std::unique_ptr<DataPage> data = std::make_unique<DataPage>(1024, 
mem_tracker);
-        std::unique_ptr<DataPage> index = std::make_unique<DataPage>(1024, 
mem_tracker);
+        std::unique_ptr<DataPage> data = std::make_unique<DataPage>(1024, 
true, page_type_data);
+        std::unique_ptr<DataPage> index = std::make_unique<DataPage>(1024, 
true, page_type_index);
         cache.insert(key, data.release(), &handle, page_type_data, false);
         cache.insert(key, index.release(), &handle, page_type_index, false);
     }
@@ -244,8 +242,8 @@ TEST_F(StoragePageCacheTest, mixed_pages) {
         PageCacheHandle data_handle, index_handle;
         StoragePageCache::CacheKey miss_key_data("data_miss", 0, 1);
         StoragePageCache::CacheKey miss_key_index("index_miss", 0, 1);
-        std::unique_ptr<DataPage> data = std::make_unique<DataPage>(1024, 
mem_tracker);
-        std::unique_ptr<DataPage> index = std::make_unique<DataPage>(1024, 
mem_tracker);
+        std::unique_ptr<DataPage> data = std::make_unique<DataPage>(1024, 
true, page_type_data);
+        std::unique_ptr<DataPage> index = std::make_unique<DataPage>(1024, 
true, page_type_index);
         cache.insert(miss_key_data, data.release(), &data_handle, 
page_type_data, false);
         cache.insert(miss_key_index, index.release(), &index_handle, 
page_type_index, false);
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to