@@ -3082,13 +3082,35 @@ BitmapFilterPtr Segment::buildMVCCBitmapFilter(
30823082 if (enable_version_chain)
30833083 {
30843084 consumeBuildMVCCReadBytesRU (dm_context, segment_snap, pack_filter_results, start_ts);
3085- return ::DB::DM::buildMVCCBitmapFilter (
3085+ auto bitmap_filter = ::DB::DM::buildMVCCBitmapFilter (
30863086 dm_context,
30873087 *segment_snap,
30883088 read_ranges,
30893089 pack_filter_results,
30903090 start_ts,
30913091 *version_chain);
3092+ if (dm_context.isVersionChainForTestEnabled ())
3093+ {
3094+ if (is_common_handle)
3095+ checkMVCCBitmap<String>(
3096+ dm_context,
3097+ segment_snap,
3098+ read_ranges,
3099+ pack_filter_results,
3100+ start_ts,
3101+ expected_block_size,
3102+ *bitmap_filter);
3103+ else
3104+ checkMVCCBitmap<Int64>(
3105+ dm_context,
3106+ segment_snap,
3107+ read_ranges,
3108+ pack_filter_results,
3109+ start_ts,
3110+ expected_block_size,
3111+ *bitmap_filter);
3112+ }
3113+ return bitmap_filter;
30923114 }
30933115 }
30943116
@@ -3307,6 +3329,7 @@ BitmapFilterPtr Segment::buildMVCCBitmapFilterStableOnly(
33073329 " buildMVCCBitmapFilterStableOnly not have use packs, total_rows={}, cost={:.3f}ms" ,
33083330 segment_snap->stable ->getDMFilesRows (),
33093331 elapse_ms);
3332+ bitmap_filter->runOptimize ();
33103333 return bitmap_filter;
33113334 }
33123335
@@ -3748,6 +3771,198 @@ BitmapFilterPtr Segment::buildBitmapFilter(
37483771 return mvcc_bitmap_filter;
37493772}
37503773
3774+ // `checkMVCCBitmap` is only used for testing.
3775+ // It will check both bitmaps that generating by version chain and delta index.
3776+ // If the bitmaps are not equal, it will throw an exception.
3777+ template <ExtraHandleType HandleType>
3778+ void Segment::checkMVCCBitmap (
3779+ const DMContext & dm_context,
3780+ const SegmentSnapshotPtr & segment_snap,
3781+ const RowKeyRanges & read_ranges,
3782+ const DMFilePackFilterResults & pack_filter_results,
3783+ UInt64 start_ts,
3784+ size_t expected_block_size,
3785+ const BitmapFilter & bitmap_filter)
3786+ {
3787+ auto new_bitmap_filter = buildMVCCBitmapFilter (
3788+ dm_context,
3789+ segment_snap,
3790+ read_ranges,
3791+ pack_filter_results,
3792+ start_ts,
3793+ expected_block_size,
3794+ /* enable_version_chain*/ false );
3795+ if (*new_bitmap_filter == bitmap_filter)
3796+ {
3797+ LOG_DEBUG (
3798+ segment_snap->log ,
3799+ " {} success, snapshot={}, dt_bitmap_filter={}/{}, bitmap_filter={}/{}" ,
3800+ __FUNCTION__,
3801+ segment_snap->detailInfo (),
3802+ new_bitmap_filter->count (),
3803+ new_bitmap_filter->size (),
3804+ bitmap_filter.count (),
3805+ bitmap_filter.size ());
3806+ return ;
3807+ }
3808+
3809+ auto print_minmax_ver = [&]() {
3810+ const auto & global_context = dm_context.global_context ;
3811+ const auto & dmfile = segment_snap->stable ->getDMFiles ().front ();
3812+ auto [type, minmax_index] = DMFilePackFilter::loadIndex (
3813+ *dmfile,
3814+ global_context.getFileProvider (),
3815+ global_context.getMinMaxIndexCache (),
3816+ /* set_cache_if_miss*/ true ,
3817+ MutSup::version_col_id,
3818+ global_context.getReadLimiter (),
3819+ dm_context.scan_context );
3820+ for (size_t i = 0 ; i < dmfile->getPacks (); ++i)
3821+ LOG_ERROR (
3822+ segment_snap->log ,
3823+ " pack={} minmax={} minmax2={}" ,
3824+ i,
3825+ minmax_index->getUInt64MinMax (i),
3826+ minmax_index->getUInt64MinMax2 (i));
3827+ };
3828+
3829+ static std::mutex check_mtx;
3830+ static bool check_failed = false ;
3831+ // To Avoid concurrent check that logs are mixed together.
3832+ // Since this function is only used for test, we don't need to consider performance.
3833+ std::lock_guard lock (check_mtx);
3834+ if (check_failed && std::is_same_v<HandleType, String>)
3835+ {
3836+ // Aoid too many logs.
3837+ LOG_ERROR (segment_snap->log , " {} failed, skip" , __FUNCTION__);
3838+ return ;
3839+ }
3840+ print_minmax_ver ();
3841+ check_failed = true ;
3842+
3843+ if (new_bitmap_filter->size () != bitmap_filter.size ())
3844+ {
3845+ LOG_ERROR (
3846+ segment_snap->log ,
3847+ " {} failed, snapshot={}, dt_bitmap_filter_size={}, bitmap_filter_size={}" ,
3848+ __FUNCTION__,
3849+ segment_snap->detailInfo (),
3850+ new_bitmap_filter->size (),
3851+ bitmap_filter.size ());
3852+ throw Exception (" Bitmap size not equal" , ErrorCodes::LOGICAL_ERROR);
3853+ }
3854+
3855+ if (new_bitmap_filter->isAllMatch () != bitmap_filter.isAllMatch ())
3856+ {
3857+ LOG_ERROR (
3858+ segment_snap->log ,
3859+ " {} failed, snapshot={}, dt_bitmap_filter_all_match={}, bitmap_filter_all_match={}" ,
3860+ __FUNCTION__,
3861+ segment_snap->detailInfo (),
3862+ new_bitmap_filter->isAllMatch (),
3863+ bitmap_filter.isAllMatch ());
3864+ throw Exception (" Bitmap all_match not euqal" , ErrorCodes::LOGICAL_ERROR);
3865+ }
3866+
3867+ LOG_ERROR (
3868+ segment_snap->log ,
3869+ " {} failed, snapshot={}, dt_bitmap_filter: count/size={}/{}, bitmap_filter: count/size={}/{} "
3870+ " read_ranges={}, segment_range={}" ,
3871+ __FUNCTION__,
3872+ segment_snap->detailInfo (),
3873+ new_bitmap_filter->count (),
3874+ new_bitmap_filter->size (),
3875+ bitmap_filter.count (),
3876+ bitmap_filter.size (),
3877+ read_ranges,
3878+ rowkey_range);
3879+
3880+ const auto cds = ColumnDefines{
3881+ getExtraHandleColumnDefine (dm_context.is_common_handle ),
3882+ getVersionColumnDefine (),
3883+ getTagColumnDefine (),
3884+ };
3885+ auto stream = getConcatSkippableBlockInputStream (
3886+ segment_snap,
3887+ dm_context,
3888+ cds,
3889+ /* read_ranges*/ {},
3890+ /* pack_filter_results*/ {},
3891+ start_ts,
3892+ expected_block_size,
3893+ ReadTag::Query);
3894+ Blocks blocks;
3895+ while (true )
3896+ {
3897+ auto block = stream->read ();
3898+ if (!block)
3899+ break ;
3900+ blocks.emplace_back (std::move (block));
3901+ }
3902+ auto block = vstackBlocks (std::move (blocks));
3903+ RUNTIME_CHECK_MSG (
3904+ block.rows () == bitmap_filter.size (),
3905+ " Block rows not equal: block_rows={}, bitmap_size={}" ,
3906+ block.rows (),
3907+ bitmap_filter.size ());
3908+ auto handle_col = block.getByName (MutSup::extra_handle_column_name).column ;
3909+ auto version_col = block.getByName (MutSup::version_column_name).column ;
3910+ auto delmark_col = block.getByName (MutSup::delmark_column_name).column ;
3911+ const auto handles = ColumnView<HandleType>(*handle_col);
3912+ const auto versions = ColumnView<UInt64>(*version_col);
3913+ const auto delmarks = ColumnView<UInt8>(*delmark_col);
3914+ for (UInt32 i = 0 ; i < bitmap_filter.size (); ++i)
3915+ {
3916+ RowKeyValue rowkey;
3917+ if constexpr (std::is_same_v<HandleType, String>)
3918+ rowkey = RowKeyValue (dm_context.is_common_handle , std::make_shared<String>(String (handles[i])), 0 );
3919+ else
3920+ rowkey = RowKeyValue (dm_context.is_common_handle , nullptr , handles[i]);
3921+
3922+ if (new_bitmap_filter->get (i) != bitmap_filter.get (i))
3923+ {
3924+ LOG_ERROR (
3925+ segment_snap->log ,
3926+ " {} {} dt={} vc={} handle={} version={} delmark={} version_filter={} "
3927+ " rowkey_filter={} ver_by_delta={} ver_by_stable={} ver_by_rs={}" ,
3928+ __FUNCTION__,
3929+ i,
3930+ new_bitmap_filter->get (i),
3931+ bitmap_filter.get (i),
3932+ rowkey.toDebugString (),
3933+ versions[i],
3934+ delmarks[i],
3935+ bitmap_filter.version_filter [i],
3936+ bitmap_filter.rowkey_filter [i],
3937+ bitmap_filter.version_filter_by_delta [i],
3938+ bitmap_filter.version_filter_by_stable [i],
3939+ bitmap_filter.version_filter_by_read_ts [i]);
3940+ continue ;
3941+ }
3942+
3943+ if constexpr (std::is_same_v<HandleType, Int64>)
3944+ {
3945+ LOG_INFO (
3946+ segment_snap->log ,
3947+ " {} {} dt={} vc={} handle={} version={} delmark={} version_filter={} "
3948+ " rowkey_filter={} ver_by_delta={} ver_by_stable={} ver_by_rs={}" ,
3949+ __FUNCTION__,
3950+ i,
3951+ new_bitmap_filter->get (i),
3952+ bitmap_filter.get (i),
3953+ rowkey.toDebugString (),
3954+ versions[i],
3955+ delmarks[i],
3956+ bitmap_filter.version_filter [i],
3957+ bitmap_filter.rowkey_filter [i],
3958+ bitmap_filter.version_filter_by_delta [i],
3959+ bitmap_filter.version_filter_by_stable [i],
3960+ bitmap_filter.version_filter_by_read_ts [i]);
3961+ }
3962+ }
3963+ throw Exception (" Bitmap not equal" , ErrorCodes::LOGICAL_ERROR);
3964+ }
3965+
37513966template <bool is_fast_scan>
37523967BlockInputStreamPtr Segment::getBitmapFilterInputStream (
37533968 const DMContext & dm_context,
0 commit comments