Skip to content

Commit 1aa4dc5

Browse files
branch-4.0: [fix](olap) Should erase the segment footer cache after compaction #59101 (#59172)
Cherry-picked from #59101 Co-authored-by: Jerry Hu <hushenggang@selectdb.com>
1 parent 1f5be7f commit 1aa4dc5

File tree

7 files changed

+113
-2
lines changed

7 files changed

+113
-2
lines changed

be/src/olap/page_cache.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ class StoragePageCache {
186186
return _get_page_cache(page_type)->mem_tracker();
187187
}
188188

189+
// Erase the page with key from this cache.
190+
void erase(const CacheKey& key, segment_v2::PageTypePB page_type) {
191+
auto* cache = _get_page_cache(page_type);
192+
cache->erase(key.encode());
193+
}
194+
189195
private:
190196
StoragePageCache();
191197

be/src/olap/rowset/beta_rowset_writer.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ Status BetaRowsetWriter::_rename_compacted_segments(int64_t begin, int64_t end)
482482
"failed to rename {} to {}. ret:{}, errno:{}", src_seg_path, dst_seg_path, ret,
483483
errno);
484484
}
485+
RETURN_IF_ERROR(_remove_segment_footer_cache(_num_segcompacted, dst_seg_path));
485486

486487
// rename inverted index files
487488
RETURN_IF_ERROR(_rename_compacted_indices(begin, end, 0));
@@ -525,13 +526,43 @@ Status BetaRowsetWriter::_rename_compacted_segment_plain(uint32_t seg_id) {
525526
"failed to rename {} to {}. ret:{}, errno:{}", src_seg_path, dst_seg_path, ret,
526527
errno);
527528
}
529+
530+
RETURN_IF_ERROR(_remove_segment_footer_cache(_num_segcompacted, dst_seg_path));
528531
// rename remaining inverted index files
529532
RETURN_IF_ERROR(_rename_compacted_indices(-1, -1, seg_id));
530533

531534
++_num_segcompacted;
532535
return Status::OK();
533536
}
534537

538+
Status BetaRowsetWriter::_remove_segment_footer_cache(const uint32_t seg_id,
539+
const std::string& segment_path) {
540+
auto* footer_page_cache = ExecEnv::GetInstance()->get_storage_page_cache();
541+
if (!footer_page_cache) {
542+
return Status::OK();
543+
}
544+
545+
auto fs = _rowset_meta->fs();
546+
bool exists = false;
547+
RETURN_IF_ERROR(fs->exists(segment_path, &exists));
548+
if (exists) {
549+
io::FileReaderSPtr file_reader;
550+
io::FileReaderOptions reader_options {
551+
.cache_type = config::enable_file_cache ? io::FileCachePolicy::FILE_BLOCK_CACHE
552+
: io::FileCachePolicy::NO_CACHE,
553+
.is_doris_table = true,
554+
.cache_base_path = "",
555+
.file_size = _rowset_meta->segment_file_size(static_cast<int>(seg_id)),
556+
.tablet_id = _rowset_meta->tablet_id(),
557+
};
558+
RETURN_IF_ERROR(fs->open_file(segment_path, &file_reader, &reader_options));
559+
DCHECK(file_reader != nullptr);
560+
auto cache_key = segment_v2::Segment::get_segment_footer_cache_key(file_reader);
561+
footer_page_cache->erase(cache_key, segment_v2::PageTypePB::INDEX_PAGE);
562+
}
563+
return Status::OK();
564+
}
565+
535566
Status BetaRowsetWriter::_rename_compacted_indices(int64_t begin, int64_t end, uint64_t seg_id) {
536567
int ret;
537568

be/src/olap/rowset/beta_rowset_writer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ class BetaRowsetWriter : public BaseBetaRowsetWriter {
296296
Status _rename_compacted_segments(int64_t begin, int64_t end);
297297
Status _rename_compacted_segment_plain(uint32_t seg_id);
298298
Status _rename_compacted_indices(int64_t begin, int64_t end, uint64_t seg_id);
299+
Status _remove_segment_footer_cache(const uint32_t seg_id, const std::string& segment_path);
299300
void _clear_statistics_for_deleting_segments_unsafe(uint32_t begin, uint32_t end);
300301

301302
StorageEngine& _engine;

be/src/olap/rowset/segment_v2/column_reader.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#include "vec/core/types.h"
7777
#include "vec/data_types/data_type_agg_state.h"
7878
#include "vec/data_types/data_type_factory.hpp"
79+
#include "vec/data_types/data_type_nullable.h"
7980
#include "vec/runtime/vdatetime_value.h" //for VecDateTime
8081

8182
namespace doris::segment_v2 {
@@ -295,6 +296,61 @@ int64_t ColumnReader::get_metadata_size() const {
295296
return sizeof(ColumnReader) + (_segment_zone_map ? _segment_zone_map->ByteSizeLong() : 0);
296297
}
297298

299+
#ifdef BE_TEST
300+
/// This function is only used in UT to verify the correctness of data read from zone map
301+
/// See UT case 'SegCompactionMoWTest.SegCompactionInterleaveWithBig_ooooOOoOooooooooO'
302+
/// be/test/olap/segcompaction_mow_test.cpp
303+
void ColumnReader::check_data_by_zone_map_for_test(const vectorized::MutableColumnPtr& dst) const {
304+
if (!_segment_zone_map) {
305+
return;
306+
}
307+
308+
const auto rows = dst->size();
309+
if (rows == 0) {
310+
return;
311+
}
312+
313+
FieldType type = _type_info->type();
314+
315+
if (type != FieldType::OLAP_FIELD_TYPE_INT) {
316+
return;
317+
}
318+
319+
auto* non_nullable_column = dst->is_nullable()
320+
? assert_cast<vectorized::ColumnNullable*>(dst.get())
321+
->get_nested_column_ptr()
322+
.get()
323+
: dst.get();
324+
325+
/// `PredicateColumnType<TYPE_INT>` does not support `void get(size_t n, Field& res)`,
326+
/// So here only check `CoumnVector<TYPE_INT>`
327+
if (vectorized::check_and_get_column<vectorized::ColumnVector<TYPE_INT>>(non_nullable_column) ==
328+
nullptr) {
329+
return;
330+
}
331+
332+
std::unique_ptr<WrapperField> min_value(WrapperField::create_by_type(type, _meta_length));
333+
std::unique_ptr<WrapperField> max_value(WrapperField::create_by_type(type, _meta_length));
334+
THROW_IF_ERROR(_parse_zone_map(*_segment_zone_map, min_value.get(), max_value.get()));
335+
336+
if (min_value->is_null() || max_value->is_null()) {
337+
return;
338+
}
339+
340+
int32_t min_v = *reinterpret_cast<int32_t*>(min_value->cell_ptr());
341+
int32_t max_v = *reinterpret_cast<int32_t*>(max_value->cell_ptr());
342+
343+
for (size_t i = 0; i != rows; ++i) {
344+
vectorized::Field field;
345+
dst->get(i, field);
346+
DCHECK(!field.is_null());
347+
const auto v = field.get<int32_t>();
348+
DCHECK_GE(v, min_v);
349+
DCHECK_LE(v, max_v);
350+
}
351+
}
352+
#endif
353+
298354
Status ColumnReader::init(const ColumnMetaPB* meta) {
299355
_type_info = get_type_info(meta);
300356

@@ -1349,6 +1405,10 @@ Status FileColumnIterator::next_batch(size_t* n, vectorized::MutableColumnPtr& d
13491405
}
13501406
*n -= remaining;
13511407
_opts.stats->bytes_read += (dst->byte_size() - curr_size) + BitmapSize(*n);
1408+
1409+
#ifdef BE_TEST
1410+
_reader->check_data_by_zone_map_for_test(dst);
1411+
#endif
13521412
return Status::OK();
13531413
}
13541414

be/src/olap/rowset/segment_v2/column_reader.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ class ColumnReader : public MetadataAdder<ColumnReader>,
228228

229229
int64_t get_metadata_size() const override;
230230

231+
#ifdef BE_TEST
232+
void check_data_by_zone_map_for_test(const vectorized::MutableColumnPtr& dst) const;
233+
#endif
234+
231235
private:
232236
friend class VariantColumnReader;
233237

be/src/olap/rowset/segment_v2/segment.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,13 @@ StoragePageCache::CacheKey Segment::get_segment_footer_cache_key() const {
10361036
// The footer is always at the end of the segment file.
10371037
// The size of footer is 12.
10381038
// So we use the size of file minus 12 as the cache key, which is unique for each segment file.
1039-
return StoragePageCache::CacheKey(_file_reader->path().native(), _file_reader->size(),
1040-
_file_reader->size() - 12);
1039+
return get_segment_footer_cache_key(_file_reader);
1040+
}
1041+
1042+
StoragePageCache::CacheKey Segment::get_segment_footer_cache_key(
1043+
const io::FileReaderSPtr& file_reader) {
1044+
return {file_reader->path().native(), file_reader->size(),
1045+
static_cast<int64_t>(file_reader->size() - 12)};
10411046
}
10421047

10431048
#include "common/compile_check_end.h"

be/src/olap/rowset/segment_v2/segment.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "agent/be_exec_version_manager.h"
3333
#include "common/status.h" // Status
34+
#include "io/fs/file_reader.h"
3435
#include "io/fs/file_reader_writer_fwd.h"
3536
#include "io/fs/file_system.h"
3637
#include "olap/field.h"
@@ -206,6 +207,9 @@ class Segment : public std::enable_shared_from_this<Segment>, public MetadataAdd
206207

207208
Status traverse_column_meta_pbs(const std::function<void(const ColumnMetaPB&)>& visitor);
208209

210+
static StoragePageCache::CacheKey get_segment_footer_cache_key(
211+
const io::FileReaderSPtr& file_reader);
212+
209213
private:
210214
DISALLOW_COPY_AND_ASSIGN(Segment);
211215
Segment(uint32_t segment_id, RowsetId rowset_id, TabletSchemaSPtr tablet_schema,

0 commit comments

Comments
 (0)