2020#include < Storages/DeltaMerge/ColumnFile/ColumnFileDataProvider.h>
2121#include < Storages/DeltaMerge/ColumnFile/ColumnFileTinyLocalIndexWriter.h>
2222#include < Storages/DeltaMerge/DMContext.h>
23+ #include < Storages/DeltaMerge/Delta/DeltaValueSpace.h>
2324#include < Storages/DeltaMerge/DeltaMergeStore.h>
2425#include < Storages/DeltaMerge/File/DMFileLocalIndexWriter.h>
2526#include < Storages/DeltaMerge/LocalIndexerScheduler.h>
@@ -851,75 +852,110 @@ void DeltaMergeStore::segmentEnsureStableLocalIndexWithErrorReport(
851852 }
852853}
853854
854- bool DeltaMergeStore::segmentEnsureDeltaLocalIndexAsync (const SegmentPtr & segment)
855+ namespace
856+ {
857+ struct LocalIndexOnDeltaVSBuildInfo
858+ {
859+ ColumnFileTinyLocalIndexWriter::LocalIndexBuildInfo build_info;
860+ std::weak_ptr<DeltaValueSpace> delta_weak_ptr;
861+ };
862+ std::optional<LocalIndexOnDeltaVSBuildInfo> //
863+ genBuildInfoFromDeltaVS (const SegmentPtr & segment, const LocalIndexInfosSnapshot & local_index_infos)
855864{
856- RUNTIME_CHECK (segment != nullptr );
857-
858- auto local_index_infos_snap = getLocalIndexInfosSnapshot ();
859- if (!local_index_infos_snap)
860- return false ;
861-
862865 // Acquire a lock to make sure delta is not changed during the process.
863866 auto lock = segment->getUpdateLock ();
864867 if (!lock)
865- return false ;
868+ return std::nullopt ;
869+ // The segment is running an update(SegmentMergeDelta/SegmentMerge/SegmentSplit) task, skip the index build.
870+ if (segment->getDelta ()->isUpdating ())
871+ return std::nullopt ;
872+
873+ // In case nothing to be built
866874 auto column_file_persisted_set = segment->getDelta ()->getPersistedFileSet ();
867875 if (!column_file_persisted_set)
868- return false ;
876+ return std:: nullopt ;
869877 auto build_info
870- = ColumnFileTinyLocalIndexWriter::getLocalIndexBuildInfo (local_index_infos_snap , column_file_persisted_set);
878+ = ColumnFileTinyLocalIndexWriter::getLocalIndexBuildInfo (local_index_infos , column_file_persisted_set);
871879 if (!build_info.indexes_to_build || build_info.indexes_to_build ->empty ())
872- return false ;
880+ return std::nullopt ;
881+
873882 // Use weak_ptr to avoid blocking gc.
874883 auto delta_weak_ptr = std::weak_ptr<DeltaValueSpace>(segment->getDelta ());
875884 lock->unlock ();
885+ return LocalIndexOnDeltaVSBuildInfo{build_info, delta_weak_ptr};
886+ }
887+ } // namespace
888+
889+ bool DeltaMergeStore::segmentEnsureDeltaLocalIndexAsync (const SegmentPtr & segment)
890+ {
891+ RUNTIME_CHECK (segment != nullptr );
892+
893+ auto local_index_infos_snap = getLocalIndexInfosSnapshot ();
894+ if (!local_index_infos_snap)
895+ return false ;
896+
897+ auto delta_vs_build_info = genBuildInfoFromDeltaVS (segment, local_index_infos_snap);
898+ if (!delta_vs_build_info)
899+ {
900+ LOG_DEBUG (
901+ log,
902+ " segmentEnsureDeltaLocalIndexAsync - Give up because no index to build or delta is being updated, "
903+ " segment={}" ,
904+ segment->simpleInfo ());
905+ return true ;
906+ }
876907
877908 auto store_weak_ptr = weak_from_this ();
878- auto tracing_id = fmt::format ( " segmentEnsureDeltaLocalIndexAsync source_segment={} " , segment->simpleInfo () );
879- auto workload = [store_weak_ptr, build_info, delta_weak_ptr, segment, tracing_id ]() -> void {
909+ const auto source_segment_info = segment->simpleInfo ();
910+ auto workload = [store_weak_ptr, delta_vs_build_info, source_segment_info ]() -> void {
880911 auto store = store_weak_ptr.lock ();
881912 if (!store) // Store is destroyed before the task is executed.
882913 return ;
883- auto delta = delta_weak_ptr.lock ();
914+ auto delta = delta_vs_build_info-> delta_weak_ptr .lock ();
884915 if (!delta) // Delta is destroyed before the task is executed.
885916 return ;
917+ auto tracing_id = fmt::format (" segmentEnsureDeltaLocalIndexAsync source_segment={}" , source_segment_info);
886918 auto dm_context = store->newDMContext ( //
887919 store->global_context ,
888920 store->global_context .getSettingsRef (),
889921 tracing_id);
890- const auto source_segment_info = segment->simpleInfo ();
891- store->segmentEnsureDeltaLocalIndex (*dm_context, build_info.indexes_to_build , delta, source_segment_info);
922+ store->segmentEnsureDeltaLocalIndex (
923+ *dm_context,
924+ delta_vs_build_info->build_info .indexes_to_build ,
925+ delta,
926+ source_segment_info);
892927 };
893928
894929 auto indexer_scheduler = global_context.getGlobalLocalIndexerScheduler ();
895930 RUNTIME_CHECK (indexer_scheduler != nullptr );
896931 try
897932 {
898933 // new task of these index are generated, clear existing error_message in segment
899- segment->clearIndexBuildError (build_info.index_ids );
934+ segment->clearIndexBuildError (delta_vs_build_info-> build_info .index_ids );
900935
901936 auto [ok, reason] = indexer_scheduler->pushTask (LocalIndexerScheduler::Task{
902937 .keyspace_id = keyspace_id,
903938 .table_id = physical_table_id,
904- .file_ids = build_info.file_ids ,
905- .request_memory = build_info.estimated_memory_bytes ,
939+ .file_ids = delta_vs_build_info-> build_info .file_ids ,
940+ .request_memory = delta_vs_build_info-> build_info .estimated_memory_bytes ,
906941 .workload = workload,
907942 });
908943 if (ok)
909944 return true ;
910945
911- segment->setIndexBuildError (build_info.index_ids , reason);
946+ segment->setIndexBuildError (delta_vs_build_info->build_info .index_ids , reason);
947+ auto tracing_id = fmt::format (" segmentEnsureDeltaLocalIndexAsync source_segment={}" , source_segment_info);
912948 LOG_ERROR (
913949 log->getChild (tracing_id),
914950 " Failed to generate async segment stable index task, index_ids={} reason={}" ,
915- build_info.index_ids ,
951+ delta_vs_build_info-> build_info .index_ids ,
916952 reason);
917953 return false ;
918954 }
919955 catch (...)
920956 {
921957 const auto message = getCurrentExceptionMessage (false , false );
922- segment->setIndexBuildError (build_info.index_ids , message);
958+ segment->setIndexBuildError (delta_vs_build_info-> build_info .index_ids , message);
923959
924960 tryLogCurrentException (log);
925961
@@ -937,18 +973,15 @@ bool DeltaMergeStore::segmentWaitDeltaLocalIndexReady(const SegmentPtr & segment
937973 if (!local_index_infos_snap)
938974 return true ;
939975
940- // Acquire a lock to make sure delta is not changed during the process.
941- auto lock = segment->mustGetUpdateLock ();
942- auto column_file_persisted_set = segment->getDelta ()->getPersistedFileSet ();
943- if (!column_file_persisted_set)
944- return false ;
945- auto build_info
946- = ColumnFileTinyLocalIndexWriter::getLocalIndexBuildInfo (local_index_infos, column_file_persisted_set);
947- // Use weak_ptr to avoid blocking gc.
948- auto delta_weak_ptr = std::weak_ptr<DeltaValueSpace>(segment->getDelta ());
949- lock.unlock ();
950- if (!build_info.indexes_to_build || build_info.indexes_to_build ->empty ())
951- return false ;
976+ auto delta_vs_build_info = genBuildInfoFromDeltaVS (segment, local_index_infos_snap);
977+ if (!delta_vs_build_info)
978+ {
979+ LOG_INFO (
980+ log,
981+ " WaitDeltaLocalIndexReady - Give up because no index to build or delta is being updated, segment={}" ,
982+ segment->simpleInfo ());
983+ return true ;
984+ }
952985
953986 auto segment_id = segment->segmentId ();
954987 static constexpr size_t MAX_CHECK_TIME_SECONDS = 60 ; // 60s
@@ -964,11 +997,11 @@ bool DeltaMergeStore::segmentWaitDeltaLocalIndexReady(const SegmentPtr & segment
964997 if (!column_file_persisted_set)
965998 return false ; // ColumnFilePersistedSet is not exist, return false
966999 bool all_indexes_built = true ;
967- auto delta_ptr = delta_weak_ptr.lock ();
1000+ auto delta_ptr = delta_vs_build_info-> delta_weak_ptr .lock ();
9681001 if (auto lock = delta_ptr ? delta_ptr->getLock () : std::nullopt ; lock)
9691002 {
9701003 const auto & column_files = column_file_persisted_set->getFiles ();
971- for (const auto & index : *build_info.indexes_to_build )
1004+ for (const auto & index : *delta_vs_build_info-> build_info .indexes_to_build )
9721005 {
9731006 for (const auto & column_file : column_files)
9741007 {
0 commit comments