Skip to content
Open

DNM #10405

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion dbms/src/Debug/TiFlashTestEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ void TiFlashTestEnv::initializeGlobalContext(
PageStorageRunMode ps_run_mode,
uint64_t bg_thread_count)
{
addGlobalContext(DB::Settings(), testdata_path, ps_run_mode, bg_thread_count);
// In unit-tests, compare the MVCC bitmap between version chain and delta index, if version chain is enabled.
DB::Settings settings;
if (settings.enable_version_chain == static_cast<Int64>(DM::VersionChainMode::Enabled))
settings.set("enable_version_chain", std::to_string(static_cast<Int64>(DM::VersionChainMode::EnabledForTest)));
addGlobalContext(settings, testdata_path, ps_run_mode, bg_thread_count);
}

void TiFlashTestEnv::addGlobalContext(
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/Interpreters/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ struct Settings
M(SettingUInt64, dt_merged_file_max_size, 16 * 1024 * 1024, "Small files are merged into one or more files not larger than dt_merged_file_max_size") \
M(SettingDouble, dt_page_gc_threshold, 0.5, "Max valid rate of deciding to do a GC in PageStorage") \
M(SettingDouble, dt_page_gc_threshold_raft_data, 0.05, "Max valid rate of deciding to do a GC for BlobFile storing PageData in PageStorage") \
M(SettingInt64, enable_version_chain, 0, "Enable version chain or not: 0 - disable, 1 - enabled. " \
M(SettingInt64, enable_version_chain, 1, "Enable version chain or not: 0 - disable, 1 - enabled, 2 - enabled_for_test. " \
"More details are in the comments of `enum class VersionChainMode`." \
"Modifying this configuration requires a restart to reset the in-memory state.") \
/* DeltaTree engine testing settings */\
Expand Down
5 changes: 4 additions & 1 deletion dbms/src/Storages/DeltaMerge/BitmapFilter/BitmapFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ namespace DB::DM
{

BitmapFilter::BitmapFilter(UInt32 size_, bool default_value)
: filter(size_, static_cast<UInt8>(default_value))
: version_filter_by_delta(size_, static_cast<UInt8>(0))
, version_filter_by_read_ts(size_, static_cast<UInt8>(0))
, version_filter_by_stable(size_, static_cast<UInt8>(0))
, filter(size_, static_cast<UInt8>(default_value))
, all_match(default_value)
{}

Expand Down
10 changes: 10 additions & 0 deletions dbms/src/Storages/DeltaMerge/BitmapFilter/BitmapFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ class BitmapFilter

friend class BitmapFilterView;

// Debug helpers
void saveRowKeyFilterForDebug() { rowkey_filter.assign(filter); }
void saveVersionFilterForDebug() { version_filter.assign(filter); }
IColumn::Filter rowkey_filter;
IColumn::Filter version_filter;

IColumn::Filter version_filter_by_delta;
IColumn::Filter version_filter_by_read_ts;
IColumn::Filter version_filter_by_stable;

private:
IColumn::Filter filter;
bool all_match;
Expand Down
5 changes: 5 additions & 0 deletions dbms/src/Storages/DeltaMerge/DMContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,9 @@ bool DMContext::isVersionChainEnabled() const
{
return global_context.getSettingsRef().enable_version_chain != static_cast<Int64>(VersionChainMode::Disabled);
}

bool DMContext::isVersionChainForTestEnabled() const
{
return global_context.getSettingsRef().enable_version_chain == static_cast<Int64>(VersionChainMode::EnabledForTest);
}
} // namespace DB::DM
1 change: 1 addition & 0 deletions dbms/src/Storages/DeltaMerge/DMContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ struct DMContext : private boost::noncopyable
DM::DMConfigurationOpt createChecksumConfig() const { return DMChecksumConfig::fromDBContext(global_context); }

bool isVersionChainEnabled() const;
bool isVersionChainForTestEnabled() const;

private:
DMContext(
Expand Down
4 changes: 4 additions & 0 deletions dbms/src/Storages/DeltaMerge/Index/MinMaxIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ std::pair<UInt64, UInt64> MinMaxIndex::getUInt64MinMax(size_t pack_index) const
{
return {minmaxes->get64(pack_index * 2), minmaxes->get64(pack_index * 2 + 1)};
}
std::pair<UInt64, UInt64> MinMaxIndex::getUInt64MinMax2(size_t pack_index) const
{
return {minmaxes->getUInt(pack_index * 2), minmaxes->getUInt(pack_index * 2 + 1)};
}

template <typename T>
RSResults MinMaxIndex::checkNullableInImpl(
Expand Down
2 changes: 2 additions & 0 deletions dbms/src/Storages/DeltaMerge/Index/MinMaxIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class MinMaxIndex
std::pair<StringRef, StringRef> getStringMinMax(size_t pack_index) const;

std::pair<UInt64, UInt64> getUInt64MinMax(size_t pack_index) const;
std::pair<UInt64, UInt64> getUInt64MinMax2(size_t pack_index) const;


template <typename Op>
RSResults checkCmp(size_t start_pack, size_t pack_count, const Field & value, const DataTypePtr & type);
Expand Down
217 changes: 216 additions & 1 deletion dbms/src/Storages/DeltaMerge/Segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3082,13 +3082,35 @@ BitmapFilterPtr Segment::buildMVCCBitmapFilter(
if (enable_version_chain)
{
consumeBuildMVCCReadBytesRU(dm_context, segment_snap, pack_filter_results, start_ts);
return ::DB::DM::buildMVCCBitmapFilter(
auto bitmap_filter = ::DB::DM::buildMVCCBitmapFilter(
dm_context,
*segment_snap,
read_ranges,
pack_filter_results,
start_ts,
*version_chain);
if (dm_context.isVersionChainForTestEnabled())
{
if (is_common_handle)
checkMVCCBitmap<String>(
dm_context,
segment_snap,
read_ranges,
pack_filter_results,
start_ts,
expected_block_size,
*bitmap_filter);
else
checkMVCCBitmap<Int64>(
dm_context,
segment_snap,
read_ranges,
pack_filter_results,
start_ts,
expected_block_size,
*bitmap_filter);
}
return bitmap_filter;
}
}

Expand Down Expand Up @@ -3307,6 +3329,7 @@ BitmapFilterPtr Segment::buildMVCCBitmapFilterStableOnly(
"buildMVCCBitmapFilterStableOnly not have use packs, total_rows={}, cost={:.3f}ms",
segment_snap->stable->getDMFilesRows(),
elapse_ms);
bitmap_filter->runOptimize();
return bitmap_filter;
}

Expand Down Expand Up @@ -3748,6 +3771,198 @@ BitmapFilterPtr Segment::buildBitmapFilter(
return mvcc_bitmap_filter;
}

// `checkMVCCBitmap` is only used for testing.
// It will check both bitmaps that generating by version chain and delta index.
// If the bitmaps are not equal, it will throw an exception.
template <ExtraHandleType HandleType>
void Segment::checkMVCCBitmap(
const DMContext & dm_context,
const SegmentSnapshotPtr & segment_snap,
const RowKeyRanges & read_ranges,
const DMFilePackFilterResults & pack_filter_results,
UInt64 start_ts,
size_t expected_block_size,
const BitmapFilter & bitmap_filter)
{
auto new_bitmap_filter = buildMVCCBitmapFilter(
dm_context,
segment_snap,
read_ranges,
pack_filter_results,
start_ts,
expected_block_size,
/*enable_version_chain*/ false);
if (*new_bitmap_filter == bitmap_filter)
{
LOG_DEBUG(
segment_snap->log,
"{} success, snapshot={}, dt_bitmap_filter={}/{}, bitmap_filter={}/{}",
__FUNCTION__,
segment_snap->detailInfo(),
new_bitmap_filter->count(),
new_bitmap_filter->size(),
bitmap_filter.count(),
bitmap_filter.size());
return;
}

auto print_minmax_ver = [&]() {
const auto & global_context = dm_context.global_context;
const auto & dmfile = segment_snap->stable->getDMFiles().front();
auto [type, minmax_index] = DMFilePackFilter::loadIndex(
*dmfile,
global_context.getFileProvider(),
global_context.getMinMaxIndexCache(),
/*set_cache_if_miss*/ true,
MutSup::version_col_id,
global_context.getReadLimiter(),
dm_context.scan_context);
for (size_t i = 0; i < dmfile->getPacks(); ++i)
LOG_ERROR(
segment_snap->log,
"pack={} minmax={} minmax2={}",
i,
minmax_index->getUInt64MinMax(i),
minmax_index->getUInt64MinMax2(i));
};

static std::mutex check_mtx;
static bool check_failed = false;
// To Avoid concurrent check that logs are mixed together.
// Since this function is only used for test, we don't need to consider performance.
std::lock_guard lock(check_mtx);
if (check_failed && std::is_same_v<HandleType, String>)
{
// Aoid too many logs.
LOG_ERROR(segment_snap->log, "{} failed, skip", __FUNCTION__);
return;
}
print_minmax_ver();
check_failed = true;

if (new_bitmap_filter->size() != bitmap_filter.size())
{
LOG_ERROR(
segment_snap->log,
"{} failed, snapshot={}, dt_bitmap_filter_size={}, bitmap_filter_size={}",
__FUNCTION__,
segment_snap->detailInfo(),
new_bitmap_filter->size(),
bitmap_filter.size());
throw Exception("Bitmap size not equal", ErrorCodes::LOGICAL_ERROR);
}

if (new_bitmap_filter->isAllMatch() != bitmap_filter.isAllMatch())
{
LOG_ERROR(
segment_snap->log,
"{} failed, snapshot={}, dt_bitmap_filter_all_match={}, bitmap_filter_all_match={}",
__FUNCTION__,
segment_snap->detailInfo(),
new_bitmap_filter->isAllMatch(),
bitmap_filter.isAllMatch());
throw Exception("Bitmap all_match not euqal", ErrorCodes::LOGICAL_ERROR);
}

LOG_ERROR(
segment_snap->log,
"{} failed, snapshot={}, dt_bitmap_filter: count/size={}/{}, bitmap_filter: count/size={}/{} "
"read_ranges={}, segment_range={}",
__FUNCTION__,
segment_snap->detailInfo(),
new_bitmap_filter->count(),
new_bitmap_filter->size(),
bitmap_filter.count(),
bitmap_filter.size(),
read_ranges,
rowkey_range);

const auto cds = ColumnDefines{
getExtraHandleColumnDefine(dm_context.is_common_handle),
getVersionColumnDefine(),
getTagColumnDefine(),
};
auto stream = getConcatSkippableBlockInputStream(
segment_snap,
dm_context,
cds,
/*read_ranges*/ {},
/*pack_filter_results*/ {},
start_ts,
expected_block_size,
ReadTag::Query);
Blocks blocks;
while (true)
{
auto block = stream->read();
if (!block)
break;
blocks.emplace_back(std::move(block));
}
auto block = vstackBlocks(std::move(blocks));
RUNTIME_CHECK_MSG(
block.rows() == bitmap_filter.size(),
"Block rows not equal: block_rows={}, bitmap_size={}",
block.rows(),
bitmap_filter.size());
auto handle_col = block.getByName(MutSup::extra_handle_column_name).column;
auto version_col = block.getByName(MutSup::version_column_name).column;
auto delmark_col = block.getByName(MutSup::delmark_column_name).column;
const auto handles = ColumnView<HandleType>(*handle_col);
const auto versions = ColumnView<UInt64>(*version_col);
const auto delmarks = ColumnView<UInt8>(*delmark_col);
for (UInt32 i = 0; i < bitmap_filter.size(); ++i)
{
RowKeyValue rowkey;
if constexpr (std::is_same_v<HandleType, String>)
rowkey = RowKeyValue(dm_context.is_common_handle, std::make_shared<String>(String(handles[i])), 0);
else
rowkey = RowKeyValue(dm_context.is_common_handle, nullptr, handles[i]);

if (new_bitmap_filter->get(i) != bitmap_filter.get(i))
{
LOG_ERROR(
segment_snap->log,
"{} {} dt={} vc={} handle={} version={} delmark={} version_filter={} "
"rowkey_filter={} ver_by_delta={} ver_by_stable={} ver_by_rs={}",
__FUNCTION__,
i,
new_bitmap_filter->get(i),
bitmap_filter.get(i),
rowkey.toDebugString(),
versions[i],
delmarks[i],
bitmap_filter.version_filter[i],
bitmap_filter.rowkey_filter[i],
bitmap_filter.version_filter_by_delta[i],
bitmap_filter.version_filter_by_stable[i],
bitmap_filter.version_filter_by_read_ts[i]);
continue;
}

if constexpr (std::is_same_v<HandleType, Int64>)
{
LOG_INFO(
segment_snap->log,
"{} {} dt={} vc={} handle={} version={} delmark={} version_filter={} "
"rowkey_filter={} ver_by_delta={} ver_by_stable={} ver_by_rs={}",
__FUNCTION__,
i,
new_bitmap_filter->get(i),
bitmap_filter.get(i),
rowkey.toDebugString(),
versions[i],
delmarks[i],
bitmap_filter.version_filter[i],
bitmap_filter.rowkey_filter[i],
bitmap_filter.version_filter_by_delta[i],
bitmap_filter.version_filter_by_stable[i],
bitmap_filter.version_filter_by_read_ts[i]);
}
}
throw Exception("Bitmap not equal", ErrorCodes::LOGICAL_ERROR);
}

template <bool is_fast_scan>
BlockInputStreamPtr Segment::getBitmapFilterInputStream(
const DMContext & dm_context,
Expand Down
10 changes: 10 additions & 0 deletions dbms/src/Storages/DeltaMerge/Segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,16 @@ class Segment
const ColumnDefines & read_columns,
const StableValueSpacePtr & stable);

template <ExtraHandleType HandleType>
void checkMVCCBitmap(
const DMContext & dm_context,
const SegmentSnapshotPtr & segment_snap,
const RowKeyRanges & read_ranges,
const DMFilePackFilterResults & pack_filter_results,
UInt64 start_ts,
size_t expected_block_size,
const BitmapFilter & bitmap_filter);

#ifndef DBMS_PUBLIC_GTEST
private:
#else
Expand Down
Loading