diff --git a/be/src/common/config.cpp b/be/src/common/config.cpp index 9b3a2edbf59743..560cbf2d6ee0ad 100644 --- a/be/src/common/config.cpp +++ b/be/src/common/config.cpp @@ -1306,8 +1306,6 @@ DEFINE_mInt64(hdfs_write_batch_buffer_size_mb, "1"); // 1MB //disable shrink memory by default DEFINE_mBool(enable_shrink_memory, "false"); -DEFINE_mInt32(schema_cache_capacity, "1024"); -DEFINE_mInt32(schema_cache_sweep_time_sec, "100"); // max number of segment cache, default -1 for backward compatibility fd_number*2/5 DEFINE_Int32(segment_cache_capacity, "-1"); diff --git a/be/src/common/config.h b/be/src/common/config.h index b5e18014e7df65..95bf94667d7529 100644 --- a/be/src/common/config.h +++ b/be/src/common/config.h @@ -1346,9 +1346,6 @@ DECLARE_mInt64(file_cache_max_file_reader_cache_size); DECLARE_mInt64(hdfs_write_batch_buffer_size_mb); //enable shrink memory DECLARE_mBool(enable_shrink_memory); -// enable cache for high concurrent point query work load -DECLARE_mInt32(schema_cache_capacity); -DECLARE_mInt32(schema_cache_sweep_time_sec); // max number of segment cache DECLARE_Int32(segment_cache_capacity); diff --git a/be/src/exec/scan/olap_scanner.cpp b/be/src/exec/scan/olap_scanner.cpp index 2649300aff48f1..99a6094d2c3a2e 100644 --- a/be/src/exec/scan/olap_scanner.cpp +++ b/be/src/exec/scan/olap_scanner.cpp @@ -51,7 +51,6 @@ #include "runtime/runtime_profile.h" #include "runtime/runtime_state.h" #include "service/backend_options.h" -#include "storage/cache/schema_cache.h" #include "storage/id_manager.h" #include "storage/index/inverted/inverted_index_profile.h" #include "storage/iterator/block_reader.h" @@ -164,68 +163,24 @@ Status OlapScanner::prepare() { // value (e.g. select a from t where a .. and b ... limit 1), // it will be very slow when reading data in segment iterator _tablet_reader->set_batch_size(_state->batch_size()); - TabletSchemaSPtr cached_schema; - std::string schema_key; { TOlapScanNode& olap_scan_node = local_state->olap_scan_node(); - const auto check_can_use_cache = [&]() { - if (!(olap_scan_node.__isset.schema_version && olap_scan_node.__isset.columns_desc && - !olap_scan_node.columns_desc.empty() && - olap_scan_node.columns_desc[0].col_unique_id >= 0 && // Why check first column? - tablet->tablet_schema()->num_variant_columns() == 0 && - tablet->tablet_schema()->num_virtual_columns() == 0)) { - return false; + // Each scanner builds its own TabletSchema to avoid concurrent modification. + tablet_schema = std::make_shared(); + tablet_schema->copy_from(*tablet->tablet_schema()); + if (olap_scan_node.__isset.columns_desc && !olap_scan_node.columns_desc.empty() && + olap_scan_node.columns_desc[0].col_unique_id >= 0) { + tablet_schema->clear_columns(); + for (const auto& column_desc : olap_scan_node.columns_desc) { + tablet_schema->append_column(TabletColumn(column_desc)); } - - // If `delete_predicates` is not empty, will merge the columns in delete predicate into current tablet schema - if (!_tablet_reader_params.delete_predicates.empty()) { - return false; + if (olap_scan_node.__isset.schema_version) { + tablet_schema->set_schema_version(olap_scan_node.schema_version); } - - const bool has_pruned_column = - std::ranges::any_of(_output_tuple_desc->slots(), [](const auto& slot) { - if ((slot->type()->get_primitive_type() == PrimitiveType::TYPE_STRUCT || - slot->type()->get_primitive_type() == PrimitiveType::TYPE_MAP || - slot->type()->get_primitive_type() == PrimitiveType::TYPE_ARRAY) && - !slot->all_access_paths().empty()) { - return true; - } - return false; - }); - return !has_pruned_column; - }(); - - if (check_can_use_cache) { - schema_key = - SchemaCache::get_schema_key(tablet->tablet_id(), olap_scan_node.columns_desc, - olap_scan_node.schema_version); - cached_schema = SchemaCache::instance()->get_schema(schema_key); } - if (cached_schema && cached_schema->num_virtual_columns() == 0) { - tablet_schema = cached_schema; - } else { - // If schema is not cached or cached schema has virtual columns, - // we need to create a new TabletSchema. - tablet_schema = std::make_shared(); - tablet_schema->copy_from(*tablet->tablet_schema()); - if (olap_scan_node.__isset.columns_desc && !olap_scan_node.columns_desc.empty() && - olap_scan_node.columns_desc[0].col_unique_id >= 0) { - // Originally scanner get TabletSchema from tablet object in BE. - // To support lightweight schema change for adding / dropping columns, - // tabletschema is bounded to rowset and tablet's schema maybe outdated, - // so we have to use schema from a query plan witch FE puts it in query plans. - tablet_schema->clear_columns(); - for (const auto& column_desc : olap_scan_node.columns_desc) { - tablet_schema->append_column(TabletColumn(column_desc)); - } - if (olap_scan_node.__isset.schema_version) { - tablet_schema->set_schema_version(olap_scan_node.schema_version); - } - } - if (olap_scan_node.__isset.indexes_desc) { - tablet_schema->update_indexes_from_thrift(olap_scan_node.indexes_desc); - } + if (olap_scan_node.__isset.indexes_desc) { + tablet_schema->update_indexes_from_thrift(olap_scan_node.indexes_desc); } if (_tablet_reader_params.rs_splits.empty()) { @@ -283,12 +238,6 @@ Status OlapScanner::prepare() { read_columns_to_string(tablet_schema, _return_columns)); } - // Add newly created tablet schema to schema cache if it does not have virtual columns. - if (cached_schema == nullptr && !schema_key.empty() && - tablet_schema->num_virtual_columns() == 0 && !tablet_schema->has_pruned_columns()) { - SchemaCache::instance()->insert_schema(schema_key, tablet_schema); - } - if (_tablet_reader_params.score_runtime) { SCOPED_TIMER(local_state->_statistics_collect_timer); _tablet_reader_params.collection_statistics = std::make_shared(); diff --git a/be/src/runtime/exec_env.h b/be/src/runtime/exec_env.h index 4d7872430cf0c2..0823f34b93e53d 100644 --- a/be/src/runtime/exec_env.h +++ b/be/src/runtime/exec_env.h @@ -119,7 +119,6 @@ class CdcClientMgr; class TabletSchemaCache; class TabletColumnObjectPool; class UserFunctionCache; -class SchemaCache; class StoragePageCache; class AnnIndexIVFListCache; class SegmentLoader; @@ -379,7 +378,6 @@ class ExecEnv { TabletSchemaCache* get_tablet_schema_cache() { return _tablet_schema_cache; } TabletColumnObjectPool* get_tablet_column_object_pool() { return _tablet_column_object_pool; } - SchemaCache* schema_cache() { return _schema_cache; } StoragePageCache* get_storage_page_cache() { return _storage_page_cache; } AnnIndexIVFListCache* get_ann_index_ivf_list_cache() { return _ann_index_ivf_list_cache; } SegmentLoader* segment_loader() { return _segment_loader; } @@ -539,7 +537,6 @@ class ExecEnv { TabletSchemaCache* _tablet_schema_cache = nullptr; TabletColumnObjectPool* _tablet_column_object_pool = nullptr; std::unique_ptr _storage_engine; - SchemaCache* _schema_cache = nullptr; StoragePageCache* _storage_page_cache = nullptr; AnnIndexIVFListCache* _ann_index_ivf_list_cache = nullptr; SegmentLoader* _segment_loader = nullptr; diff --git a/be/src/runtime/exec_env_init.cpp b/be/src/runtime/exec_env_init.cpp index d1f22cd8476a8b..b4d517d1dbec7c 100644 --- a/be/src/runtime/exec_env_init.cpp +++ b/be/src/runtime/exec_env_init.cpp @@ -99,7 +99,6 @@ #include "service/point_query_executor.h" #include "storage/cache/ann_index_ivf_list_cache.h" #include "storage/cache/page_cache.h" -#include "storage/cache/schema_cache.h" #include "storage/id_manager.h" #include "storage/index/inverted/inverted_index_cache.h" #include "storage/olap_define.h" @@ -641,8 +640,6 @@ Status ExecEnv::init_mem_env() { << " segment_cache_capacity: " << segment_cache_capacity << " min_segment_cache_mem_limit " << segment_cache_mem_limit; - _schema_cache = new SchemaCache(config::schema_cache_capacity); - size_t block_file_cache_fd_cache_size = std::min((uint64_t)config::file_cache_max_file_reader_cache_size, fd_number / 3); LOG(INFO) << "max file reader cache size is: " << block_file_cache_fd_cache_size @@ -725,7 +722,7 @@ void ExecEnv::init_mem_tracker() { _segcompaction_mem_tracker = MemTrackerLimiter::create_shared(MemTrackerLimiter::Type::COMPACTION, "SegCompaction"); _tablets_no_cache_mem_tracker = MemTrackerLimiter::create_shared( - MemTrackerLimiter::Type::METADATA, "Tablets(not in SchemaCache, TabletSchemaCache)"); + MemTrackerLimiter::Type::METADATA, "Tablets(not in TabletSchemaCache)"); _segments_no_cache_mem_tracker = MemTrackerLimiter::create_shared( MemTrackerLimiter::Type::METADATA, "Segments(not in SegmentCache)"); _rowsets_no_cache_mem_tracker = @@ -885,7 +882,6 @@ void ExecEnv::destroy() { SAFE_DELETE(_condition_cache); SAFE_DELETE(_encoding_info_resolver); SAFE_DELETE(_lookup_connection_cache); - SAFE_DELETE(_schema_cache); SAFE_DELETE(_segment_loader); SAFE_DELETE(_row_cache); SAFE_DELETE(_query_cache); diff --git a/be/src/runtime/memory/cache_policy.h b/be/src/runtime/memory/cache_policy.h index 60b269ebd2f615..591c9c7c0e60dd 100644 --- a/be/src/runtime/memory/cache_policy.h +++ b/be/src/runtime/memory/cache_policy.h @@ -149,8 +149,8 @@ class CachePolicy { } } - inline static std::vector MetadataCache { - CacheType::SEGMENT_CACHE, CacheType::SCHEMA_CACHE, CacheType::TABLET_SCHEMA_CACHE}; + inline static std::vector MetadataCache {CacheType::SEGMENT_CACHE, + CacheType::TABLET_SCHEMA_CACHE}; CachePolicy(CacheType type, size_t capacity, uint32_t stale_sweep_time_s, bool enable_prune); virtual ~CachePolicy(); diff --git a/be/src/runtime/memory/memory_profile.cpp b/be/src/runtime/memory/memory_profile.cpp index e4210f1c5cdb41..35f3ee372b4f57 100644 --- a/be/src/runtime/memory/memory_profile.cpp +++ b/be/src/runtime/memory/memory_profile.cpp @@ -23,8 +23,8 @@ #include "runtime/memory/jemalloc_control.h" #include "runtime/memory/mem_tracker_limiter.h" #include "runtime/runtime_profile.h" -#include "storage/cache/schema_cache.h" #include "storage/metadata_adder.h" +#include "storage/segment/segment_loader.h" #include "storage/tablet/tablet_schema_cache.h" #include "util/mem_info.h" @@ -161,8 +161,7 @@ void MemoryProfile::refresh_memory_overview_profile() { // 2 refresh metadata memory tracker ExecEnv::GetInstance()->tablets_no_cache_mem_tracker()->set_consumption( MetadataAdder::get_all_tablets_size() - - TabletSchemaCache::instance()->value_mem_consumption() - - SchemaCache::instance()->value_mem_consumption()); + TabletSchemaCache::instance()->value_mem_consumption()); ExecEnv::GetInstance()->rowsets_no_cache_mem_tracker()->set_consumption( MetadataAdder::get_all_rowsets_size()); ExecEnv::GetInstance()->segments_no_cache_mem_tracker()->set_consumption( diff --git a/be/src/storage/cache/schema_cache.cpp b/be/src/storage/cache/schema_cache.cpp deleted file mode 100644 index eed455edce7cc4..00000000000000 --- a/be/src/storage/cache/schema_cache.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#include "storage/cache/schema_cache.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "common/config.h" -#include "storage/schema.h" -#include "storage/tablet/tablet.h" -#include "storage/tablet/tablet_schema.h" -#include "util/defer_op.h" -#include "util/time.h" - -namespace doris { - -SchemaCache* SchemaCache::instance() { - return ExecEnv::GetInstance()->schema_cache(); -} - -// format: tabletId-unique_id1-uniqueid2...-version-type -std::string SchemaCache::get_schema_key(int64_t tablet_id, const std::vector& columns, - int32_t version) { - if (columns.empty() || columns[0].col_unique_id < 0) { - return ""; - } - std::string key = fmt::format("{}-", tablet_id); - std::for_each(columns.begin(), columns.end(), [&](const TColumn& col) { - key.append(fmt::format("{}-", col.col_unique_id)); - // Remove the check after we del old impl of topn materialize code - if (col.column_name.find("ROWID") != std::string::npos) { - key.append(fmt::format("{}-", col.column_name)); - } - }); - key.append(fmt::format("{}", version)); - return key; -} - -} // namespace doris \ No newline at end of file diff --git a/be/src/storage/cache/schema_cache.h b/be/src/storage/cache/schema_cache.h deleted file mode 100644 index c6bd6710ae312c..00000000000000 --- a/be/src/storage/cache/schema_cache.h +++ /dev/null @@ -1,98 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#include -#include - -#include -#include -#include -#include -#include - -#include "common/logging.h" -#include "storage/iterators.h" -#include "storage/olap_common.h" -#include "storage/schema.h" -#include "storage/tablet/tablet.h" -#include "storage/tablet/tablet_schema.h" -#include "util/time.h" - -namespace doris { - -namespace segment_v2 { -class Segment; -class SegmentIterator; -using SegmentIteratorUPtr = std::unique_ptr; -} // namespace segment_v2 - -// The SchemaCache is utilized to cache pre-allocated data structures, -// 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 { -public: - static SchemaCache* instance(); - - static void create_global_instance(size_t capacity); - - static std::string get_schema_key(int64_t tablet_id, const std::vector& columns, - int32_t version); - - // Get a shared cached schema from cache, schema_key is a subset of column unique ids - TabletSchemaSPtr get_schema(const std::string& schema_key) { - if (!instance() || schema_key.empty()) { - return {}; - } - auto* lru_handle = lookup(schema_key); - if (lru_handle) { - Defer release([cache = this, lru_handle] { cache->release(lru_handle); }); - auto* value = (CacheValue*)LRUCachePolicy::value(lru_handle); - VLOG_DEBUG << "use cache schema"; - return value->tablet_schema; - } - return {}; - } - - // Insert a shared Schema into cache, schema_key is full column unique ids - void insert_schema(const std::string& key, TabletSchemaSPtr schema) { - if (!instance() || key.empty()) { - return; - } - auto* value = new CacheValue; - value->tablet_schema = schema; - - auto* lru_handle = insert(key, value, 1, schema->mem_size(), CachePriority::NORMAL); - release(lru_handle); - } - - class CacheValue : public LRUCacheValueBase { - public: - TabletSchemaSPtr tablet_schema = nullptr; - }; - - SchemaCache(size_t capacity) - : LRUCachePolicy(CachePolicy::CacheType::SCHEMA_CACHE, capacity, LRUCacheType::NUMBER, - config::schema_cache_sweep_time_sec, /*num shards*/ 32, - /*element_count_capacity*/ 0, /*enable_prune*/ true, - /*is lru-k*/ false) {} - -private: - static constexpr char SCHEMA_DELIMITER = '-'; -}; - -} // namespace doris \ No newline at end of file diff --git a/be/src/storage/iterator/vgeneric_iterators.cpp b/be/src/storage/iterator/vgeneric_iterators.cpp index b19778dd018147..b18305dae99431 100644 --- a/be/src/storage/iterator/vgeneric_iterators.cpp +++ b/be/src/storage/iterator/vgeneric_iterators.cpp @@ -26,7 +26,6 @@ #include "core/block/column_with_type_and_name.h" #include "core/column/column.h" #include "core/data_type/data_type.h" -#include "storage/cache/schema_cache.h" #include "storage/field.h" #include "storage/iterators.h" #include "storage/olap_common.h" diff --git a/be/src/storage/rowset/beta_rowset_reader.cpp b/be/src/storage/rowset/beta_rowset_reader.cpp index 097f64c98f407b..ac80a8f53e2b45 100644 --- a/be/src/storage/rowset/beta_rowset_reader.cpp +++ b/be/src/storage/rowset/beta_rowset_reader.cpp @@ -34,7 +34,6 @@ #include "io/io_common.h" #include "runtime/descriptors.h" #include "runtime/runtime_profile.h" -#include "storage/cache/schema_cache.h" #include "storage/delete/delete_handler.h" #include "storage/iterator/vgeneric_iterators.h" #include "storage/olap_define.h" diff --git a/be/src/storage/storage_engine.cpp b/be/src/storage/storage_engine.cpp index ad9b78752ff458..1a15929111d275 100644 --- a/be/src/storage/storage_engine.cpp +++ b/be/src/storage/storage_engine.cpp @@ -61,7 +61,6 @@ #include "load/stream_load/stream_load_recorder.h" #include "runtime/exec_env.h" #include "storage/binlog.h" -#include "storage/cache/schema_cache.h" #include "storage/compaction/single_replica_compaction.h" #include "storage/data_dir.h" #include "storage/id_manager.h"