[feature] add Generic debug timer for debugging or profiling (#7923)

add a group of debug-timer for the purpose of profiling or testing
you can use these timers for custom meaning purpose unlike the specific named timer
This commit is contained in:
zuochunwei
2022-01-31 22:15:43 +08:00
committed by GitHub
parent a6962af30f
commit 4e783afa7a
9 changed files with 38 additions and 7 deletions

View File

@ -159,6 +159,13 @@ void OlapScanNode::_init_counter(RuntimeState* state) {
// time of node to wait for batch/block queue
_olap_wait_batch_queue_timer = ADD_TIMER(_runtime_profile, "BatchQueueWaitTime");
// for the purpose of debugging or profiling
for (int i = 0; i < sizeof(_general_debug_timer)/sizeof(*_general_debug_timer); ++i) {
char name[64];
snprintf(name, sizeof(name), "GeneralDebugTimer%d", i);
_general_debug_timer[i] = ADD_TIMER(_segment_profile, name);
}
}
Status OlapScanNode::prepare(RuntimeState* state) {

View File

@ -325,6 +325,9 @@ protected:
RuntimeProfile::Counter* _olap_wait_batch_queue_timer = nullptr;
// for debugging or profiling, record any info as you want
RuntimeProfile::Counter* _general_debug_timer[GENERAL_DEBUG_COUNT] = {};
vectorized::VExpr* _dfs_peel_conjunct(vectorized::VExpr* expr, int& leaf_index);
void _peel_pushed_conjuncts(); // remove pushed expr from conjunct tree
};

View File

@ -541,6 +541,11 @@ void OlapScanner::update_counter() {
COUNTER_UPDATE(_parent->_index_load_timer, stats.index_load_ns);
size_t timer_count = sizeof(stats.general_debug_ns) / sizeof(*stats.general_debug_ns);
for (size_t i = 0; i < timer_count; ++i) {
COUNTER_UPDATE(_parent->_general_debug_timer[i], stats.general_debug_ns[i]);
}
COUNTER_UPDATE(_parent->_total_pages_num_counter, stats.total_pages_num);
COUNTER_UPDATE(_parent->_cached_pages_num_counter, stats.cached_pages_num);

View File

@ -238,6 +238,8 @@ class Field;
class WrapperField;
using KeyRange = std::pair<WrapperField*, WrapperField*>;
static const int GENERAL_DEBUG_COUNT = 4;
// ReaderStatistics used to collect statistics when scan data from storage
struct OlapReaderStatistics {
int64_t io_ns = 0;
@ -285,6 +287,17 @@ struct OlapReaderStatistics {
int64_t filtered_segment_number = 0;
// total number of segment
int64_t total_segment_number = 0;
// general_debug_ns is designed for the purpose of DEBUG, to record any infomations of debugging or profiling.
// different from specific meaningful timer such as index_load_ns, general_debug_ns can be used flexibly.
// general_debug_ns has associated with OlapScanNode's _general_debug_timer already.
// so general_debug_ns' values will update to _general_debug_timer automaticly,
// the timer result can be checked through QueryProfile web page easily.
// when search general_debug_ns, you can find that general_debug_ns has not been used,
// this is because such codes added for debug purpose should not commit, it's just for debuging.
// so, please do not delete general_debug_ns defined here
// usage example:
// SCOPED_RAW_TIMER(&_stats->general_debug_ns[1]);
int64_t general_debug_ns[GENERAL_DEBUG_COUNT] = {};
};
typedef uint32_t ColumnId;

View File

@ -154,8 +154,6 @@ private:
class BinaryPlainPageDecoder : public PageDecoder {
public:
BinaryPlainPageDecoder(Slice data) : BinaryPlainPageDecoder(data, PageDecoderOptions()) {}
BinaryPlainPageDecoder(Slice data, const PageDecoderOptions& options)
: _data(data),
_options(options),

View File

@ -652,6 +652,7 @@ Status FileColumnIterator::_read_data_page(const OrdinalPageIndexIterator& iter)
RETURN_IF_ERROR(_reader->read_page(_opts, iter.page(), &handle, &page_body, &footer));
// parse data page
RETURN_IF_ERROR(ParsedPage::create(std::move(handle), page_body, footer.data_page_footer(),
_opts.stats,
_reader->encoding_info(), iter.page(), iter.page_index(),
&_page));
@ -672,7 +673,7 @@ Status FileColumnIterator::_read_data_page(const OrdinalPageIndexIterator& iter)
&_dict_page_handle, &dict_data, &dict_footer));
// ignore dict_footer.dict_page_footer().encoding() due to only
// PLAIN_ENCODING is supported for dict page right now
_dict_decoder.reset(new BinaryPlainPageDecoder(dict_data));
_dict_decoder.reset(new BinaryPlainPageDecoder(dict_data, _opts.stats));
RETURN_IF_ERROR(_dict_decoder->init());
auto* pd_decoder = (BinaryPlainPageDecoder*)_dict_decoder.get();

View File

@ -102,7 +102,7 @@ Status IndexedColumnIterator::_read_data_page(const PagePointer& pp) {
// parse data page
// note that page_index is not used in IndexedColumnIterator, so we pass 0
return ParsedPage::create(std::move(handle), body, footer.data_page_footer(),
_reader->encoding_info(), pp, 0, &_data_page);
nullptr, _reader->encoding_info(), pp, 0, &_data_page);
}
Status IndexedColumnIterator::seek_to_ordinal(ordinal_t idx) {

View File

@ -32,7 +32,10 @@ struct PageBuilderOptions {
size_t dict_page_size = DEFAULT_PAGE_SIZE;
};
struct PageDecoderOptions {};
struct PageDecoderOptions {
struct OlapReaderStatistics* stats;
PageDecoderOptions(struct OlapReaderStatistics* stats) : stats(stats) {}
};
} // namespace segment_v2
} // namespace doris

View File

@ -36,6 +36,7 @@ namespace segment_v2 {
// this object
struct ParsedPage {
static Status create(PageHandle handle, const Slice& body, const DataPageFooterPB& footer,
struct OlapReaderStatistics* stats,
const EncodingInfo* encoding, const PagePointer& page_pointer,
uint32_t page_index, std::unique_ptr<ParsedPage>* result) {
std::unique_ptr<ParsedPage> page(new ParsedPage);
@ -51,7 +52,7 @@ struct ParsedPage {
}
Slice data_slice(body.data, body.size - null_size);
PageDecoderOptions opts;
PageDecoderOptions opts(stats);
RETURN_IF_ERROR(encoding->create_page_decoder(data_slice, opts, &page->data_decoder));
RETURN_IF_ERROR(page->data_decoder->init());
@ -102,4 +103,4 @@ private:
};
} // namespace segment_v2
} // namespace doris
} // namespace doris