diff --git a/be/src/common/config.cpp b/be/src/common/config.cpp index dd88a1f812d012..69741ce21bd1cb 100644 --- a/be/src/common/config.cpp +++ b/be/src/common/config.cpp @@ -1211,6 +1211,8 @@ DEFINE_mInt32(mow_publish_max_discontinuous_version_num, "20"); // current txn's publishing version and the max version of the tablet exceeds this value, // don't print warning log DEFINE_mInt32(publish_version_gap_logging_threshold, "200"); +// get agg by cache for mow table +DEFINE_mBool(enable_mow_get_agg_by_cache, "true"); // The secure path with user files, used in the `local` table function. DEFINE_mString(user_files_secure_path, "${DORIS_HOME}"); diff --git a/be/src/common/config.h b/be/src/common/config.h index 79f871b4248f55..5d66dc3286d88b 100644 --- a/be/src/common/config.h +++ b/be/src/common/config.h @@ -1274,6 +1274,8 @@ DECLARE_mInt32(mow_publish_max_discontinuous_version_num); // current txn's publishing version and the max version of the tablet exceeds this value, // don't print warning log DECLARE_mInt32(publish_version_gap_logging_threshold); +// get agg by cache for mow table +DECLARE_mBool(enable_mow_get_agg_by_cache); // The secure path with user files, used in the `local` table function. DECLARE_mString(user_files_secure_path); diff --git a/be/src/olap/tablet_meta.cpp b/be/src/olap/tablet_meta.cpp index 9bbb99a44b6632..b54764bfed25e1 100644 --- a/be/src/olap/tablet_meta.cpp +++ b/be/src/olap/tablet_meta.cpp @@ -925,6 +925,7 @@ void TabletMeta::revise_delete_bitmap_unlocked(const DeleteBitmap& delete_bitmap } void TabletMeta::delete_stale_rs_meta_by_version(const Version& version) { + size_t rowset_cache_version_size = 0; auto it = _stale_rs_metas.begin(); while (it != _stale_rs_metas.end()) { if ((*it)->version() == version) { @@ -932,12 +933,21 @@ void TabletMeta::delete_stale_rs_meta_by_version(const Version& version) { // remove rowset delete bitmap delete_bitmap().remove({(*it)->rowset_id(), 0, 0}, {(*it)->rowset_id(), UINT32_MAX, 0}); + rowset_cache_version_size = + delete_bitmap().remove_rowset_cache_version((*it)->rowset_id()); } it = _stale_rs_metas.erase(it); } else { it++; } } + if (_enable_unique_key_merge_on_write) { + DCHECK(rowset_cache_version_size <= _rs_metas.size() + _stale_rs_metas.size()) + << "tablet: " << _tablet_id + << ", rowset_cache_version size: " << rowset_cache_version_size + << ", _rs_metas size: " << _rs_metas.size() + << ", _stale_rs_metas size:" << _stale_rs_metas.size(); + } } RowsetMetaSharedPtr TabletMeta::acquire_rs_meta_by_version(const Version& version) const { @@ -1270,6 +1280,24 @@ bool DeleteBitmap::has_calculated_for_multi_segments(const RowsetId& rowset_id) return contains({rowset_id, INVALID_SEGMENT_ID, TEMP_VERSION_COMMON}, ROWSET_SENTINEL_MARK); } +size_t DeleteBitmap::remove_rowset_cache_version(const RowsetId& rowset_id) { + std::lock_guard l(_rowset_cache_version_lock); + _rowset_cache_version.erase(rowset_id); + return _rowset_cache_version.size(); +} + +DeleteBitmap::Version DeleteBitmap::_get_rowset_cache_version(const BitmapKey& bmk) const { + std::shared_lock l(_rowset_cache_version_lock); + if (auto it = _rowset_cache_version.find(std::get<0>(bmk)); it != _rowset_cache_version.end()) { + auto& segment_cache_version = it->second; + if (auto it1 = segment_cache_version.find(std::get<1>(bmk)); + it1 != segment_cache_version.end()) { + return it1->second; + } + } + return 0; +} + // We cannot just copy the underlying memory to construct a string // due to equivalent objects may have different padding bytes. // Reading padding bytes is undefined behavior, neither copy nor @@ -1301,9 +1329,28 @@ std::shared_ptr DeleteBitmap::get_agg(const BitmapKey& bmk) co // of cache entries in some cases? if (val == nullptr) { // Renew if needed, put a new Value to cache val = new AggCache::Value(); + Version start_version = + config::enable_mow_get_agg_by_cache ? _get_rowset_cache_version(bmk) : 0; + if (start_version > 0) { + Cache::Handle* handle2 = _agg_cache->repr()->lookup( + agg_cache_key(_tablet_id, {std::get<0>(bmk), std::get<1>(bmk), start_version})); + if (handle2 == nullptr) { + start_version = 0; + } else { + val->bitmap |= + reinterpret_cast(_agg_cache->repr()->value(handle2)) + ->bitmap; + _agg_cache->repr()->release(handle2); + VLOG_DEBUG << "get agg cache version=" << start_version + << " for tablet=" << _tablet_id + << ", rowset=" << std::get<0>(bmk).to_string() + << ", segment=" << std::get<1>(bmk); + start_version += 1; + } + } { std::shared_lock l(lock); - DeleteBitmap::BitmapKey start {std::get<0>(bmk), std::get<1>(bmk), 0}; + DeleteBitmap::BitmapKey start {std::get<0>(bmk), std::get<1>(bmk), start_version}; for (auto it = delete_bitmap.lower_bound(start); it != delete_bitmap.end(); ++it) { auto& [k, bm] = *it; if (std::get<0>(k) != std::get<0>(bmk) || std::get<1>(k) != std::get<1>(bmk) || @@ -1315,6 +1362,15 @@ std::shared_ptr DeleteBitmap::get_agg(const BitmapKey& bmk) co } size_t charge = val->bitmap.getSizeInBytes() + sizeof(AggCache::Value); handle = _agg_cache->repr()->insert(key, val, charge, charge, CachePriority::NORMAL); + if (config::enable_mow_get_agg_by_cache && !val->bitmap.isEmpty()) { + std::lock_guard l(_rowset_cache_version_lock); + // this version is already agg + _rowset_cache_version[std::get<0>(bmk)][std::get<1>(bmk)] = std::get<2>(bmk); + VLOG_DEBUG << "set agg cache version=" << std::get<2>(bmk) + << " for tablet=" << _tablet_id + << ", rowset=" << std::get<0>(bmk).to_string() + << ", segment=" << std::get<1>(bmk); + } } // It is natural for the cache to reclaim the underlying memory diff --git a/be/src/olap/tablet_meta.h b/be/src/olap/tablet_meta.h index dc4be4f5ef059a..12ac97d665d73e 100644 --- a/be/src/olap/tablet_meta.h +++ b/be/src/olap/tablet_meta.h @@ -556,6 +556,9 @@ class DeleteBitmap { bool has_calculated_for_multi_segments(const RowsetId& rowset_id) const; + // return the size of the map + size_t remove_rowset_cache_version(const RowsetId& rowset_id); + class AggCachePolicy : public LRUCachePolicy { public: AggCachePolicy(size_t capacity) @@ -587,8 +590,12 @@ class DeleteBitmap { }; private: + DeleteBitmap::Version _get_rowset_cache_version(const BitmapKey& bmk) const; + mutable std::shared_ptr _agg_cache; int64_t _tablet_id; + mutable std::shared_mutex _rowset_cache_version_lock; + mutable std::map> _rowset_cache_version; // > std::map>>