diff --git a/be/src/runtime/tablets_channel.cpp b/be/src/runtime/tablets_channel.cpp index d0d742e9152dac..dfae3433f3513f 100644 --- a/be/src/runtime/tablets_channel.cpp +++ b/be/src/runtime/tablets_channel.cpp @@ -406,7 +406,7 @@ void BaseTabletsChannel::refresh_profile() { Status BaseTabletsChannel::_open_all_writers(const PTabletWriterOpenRequest& request) { std::vector* index_slots = nullptr; int32_t schema_hash = 0; - for (auto& index : _schema->indexes()) { + for (const auto& index : _schema->indexes()) { if (index->index_id == _index_id) { index_slots = &index->slots; schema_hash = index->schema_hash; @@ -430,7 +430,7 @@ Status BaseTabletsChannel::_open_all_writers(const PTabletWriterOpenRequest& req #endif int tablet_cnt = 0; - for (auto& tablet : request.tablets()) { + for (const auto& tablet : request.tablets()) { if (_tablet_writers.find(tablet.tablet_id()) != _tablet_writers.end()) { continue; } @@ -513,23 +513,7 @@ Status BaseTabletsChannel::add_batch(const PTabletWriterAddBlockRequest& request std::unordered_map /* row index */> tablet_to_rowidxs; - for (uint32_t i = 0; i < request.tablet_ids_size(); ++i) { - if (request.is_single_tablet_block()) { - break; - } - int64_t tablet_id = request.tablet_ids(i); - if (_is_broken_tablet(tablet_id)) { - // skip broken tablets - VLOG_PROGRESS << "skip broken tablet tablet=" << tablet_id; - continue; - } - auto it = tablet_to_rowidxs.find(tablet_id); - if (it == tablet_to_rowidxs.end()) { - tablet_to_rowidxs.emplace(tablet_id, std::initializer_list {i}); - } else { - it->second.emplace_back(i); - } - } + _build_tablet_to_rowidxs(request, &tablet_to_rowidxs); vectorized::Block send_data; RETURN_IF_ERROR(send_data.deserialize(request.block())); @@ -589,9 +573,34 @@ void BaseTabletsChannel::_add_broken_tablet(int64_t tablet_id) { _broken_tablets.insert(tablet_id); } -bool BaseTabletsChannel::_is_broken_tablet(int64_t tablet_id) { - std::shared_lock rlock(_broken_tablets_lock); +bool BaseTabletsChannel::_is_broken_tablet(int64_t tablet_id) const { return _broken_tablets.find(tablet_id) != _broken_tablets.end(); } +void BaseTabletsChannel::_build_tablet_to_rowidxs( + const PTabletWriterAddBlockRequest& request, + std::unordered_map>* tablet_to_rowidxs) { + // just add a coarse-grained read lock here rather than each time when visiting _broken_tablets + // tests show that a relatively coarse-grained read lock here performs better under multicore scenario + // see: https://github.com/apache/doris/pull/28552 + std::shared_lock rlock(_broken_tablets_lock); + for (uint32_t i = 0; i < request.tablet_ids_size(); ++i) { + if (request.is_single_tablet_block()) { + break; + } + int64_t tablet_id = request.tablet_ids(i); + if (_is_broken_tablet(tablet_id)) { + // skip broken tablets + VLOG_PROGRESS << "skip broken tablet tablet=" << tablet_id; + continue; + } + auto it = tablet_to_rowidxs->find(tablet_id); + if (it == tablet_to_rowidxs->end()) { + tablet_to_rowidxs->emplace(tablet_id, std::initializer_list {i}); + } else { + it->second.emplace_back(i); + } + } +} + } // namespace doris diff --git a/be/src/runtime/tablets_channel.h b/be/src/runtime/tablets_channel.h index 2f9ec9d51a9251..75a0b7679ef096 100644 --- a/be/src/runtime/tablets_channel.h +++ b/be/src/runtime/tablets_channel.h @@ -116,9 +116,14 @@ class BaseTabletsChannel { Status _open_all_writers(const PTabletWriterOpenRequest& request); void _add_broken_tablet(int64_t tablet_id); + // thread-unsafe, add a shared lock for `_tablet_writers_lock` if needed + bool _is_broken_tablet(int64_t tablet_id) const; void _add_error_tablet(google::protobuf::RepeatedPtrField* tablet_errors, int64_t tablet_id, Status error) const; - bool _is_broken_tablet(int64_t tablet_id); + void _build_tablet_to_rowidxs( + const PTabletWriterAddBlockRequest& request, + std::unordered_map /* row index */>* + tablet_to_rowidxs); virtual void _init_profile(RuntimeProfile* profile); // id of this load channel