@@ -592,6 +592,31 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
592592 // Initialize the required internal states of DataDistributor from system metadata. It's necessary before
593593 // DataDistributor start working. Doesn't include initialization of optional components, like TenantCache, DDQueue,
594594 // Tracker, TeamCollection. The components should call its own ::init methods.
595+ //
596+ // DD Startup Progress (trace events in order):
597+ // DDInitRunning - DD process recruited and starting init
598+ // DDInitTakingMoveKeysLock - Acquiring move keys lock
599+ // DDInitTookMoveKeysLock - Lock acquired
600+ // DDInitGotConfiguration - Database configuration loaded
601+ // DDInitUpdatedReplicaKeys - Replica keys updated
602+ // DDInitSlowDataMoveRead - (SevWarn) dataMoveKeys read taking >5s
603+ // DDInitServerListAndDataMoveReadComplete - Server list + data moves read: NumDataMoves, NumServers,
604+ // ElapsedSeconds
605+ // DDInitKeyServerScanProgress - (every 30s) keyServer scan: BeginKey, Batches, ShardsScanned
606+ // DDInitKeyServerScanComplete - keyServer scan done: NumShards, ElapsedSeconds
607+ // DDInitGotInitialDD - Init data loaded: NumShards, NumServers
608+ // DDInitDataLoaded - Init data loaded, ElapsedSeconds (does NOT mean DD is fully operational)
609+ //
610+ // After init(), the following startup events fire from other components:
611+ // DDInitResumeDataMovesProgress - (every 30s) data move resume: ValidMoves, CancelledMoves, EmptyMoves
612+ // DDInitResumedDataMoves - Data move resume complete with counts
613+ // TrackInitialShards - Shard tracker setup started with InitialShardCount
614+ // TrackInitialShardsComplete - Shard trackers created: ShardsTracked
615+ // DDTrackerStarting - Teams ready (fires from DDTeamCollection after readyToStart + delay)
616+ // TrackInitialShardsMetricsComplete - All shard metrics received: ElapsedSeconds
617+ // WaitStorageMetricsHandleError may fire (SevWarn after 60s) if a
618+ // shard's metrics read is stuck retrying: Keys, Retries
619+ // DDInitDone - DD is fully operational with all shard sizes loaded
595620 ACTOR static Future<Void> init (Reference<DataDistributor> self) {
596621 loop {
597622 wait (self->waitDataDistributorEnabled ());
@@ -650,13 +675,17 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
650675 .detail (" E" , self->initData ->shards .end ()[-1 ].key )
651676 .detail (" Src" , describe (self->initData ->shards .end ()[-2 ].primarySrc ))
652677 .detail (" Dest" , describe (self->initData ->shards .end ()[-2 ].primaryDest ))
678+ .detail (" NumShards" , self->initData ->shards .size ())
679+ .detail (" NumServers" , self->initData ->allServers .size ())
653680 .trackLatest (self->initialDDEventHolder ->trackingKey );
654681 } else {
655682 TraceEvent (" DDInitGotInitialDD" , self->ddId )
656683 .detail (" B" , " " )
657684 .detail (" E" , " " )
658685 .detail (" Src" , " [no items]" )
659686 .detail (" Dest" , " [no items]" )
687+ .detail (" NumShards" , self->initData ->shards .size ())
688+ .detail (" NumServers" , self->initData ->allServers .size ())
660689 .trackLatest (self->initialDDEventHolder ->trackingKey );
661690 }
662691
@@ -853,6 +882,11 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
853882 // TODO: unit test needed
854883 ACTOR static Future<Void> resumeFromDataMoves (Reference<DataDistributor> self, Future<Void> readyToStart) {
855884 state KeyRangeMap<std::shared_ptr<DataMove>>::iterator it = self->initData ->dataMoveMap .ranges ().begin ();
885+ state int validMoves = 0 ;
886+ state int cancelledMoves = 0 ;
887+ state int emptyMoves = 0 ;
888+ state double resumeStart = now ();
889+ state double lastLogTime = now ();
856890
857891 wait (readyToStart);
858892
@@ -861,6 +895,7 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
861895 DataMoveType dataMoveType = getDataMoveTypeFromDataMoveId (meta.id );
862896 if (meta.ranges .empty ()) {
863897 TraceEvent (SevInfo, " EmptyDataMoveRange" , self->ddId ).detail (" DataMoveMetaData" , meta.toString ());
898+ emptyMoves++;
864899 continue ;
865900 }
866901 if (meta.bulkLoadTaskState .present ()) {
@@ -891,6 +926,7 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
891926 rs.cancelled = true ;
892927 self->relocationProducer .send (rs);
893928 TraceEvent (" DDInitScheduledCancelDataMove" , self->ddId ).detail (" DataMove" , meta.toString ());
929+ cancelledMoves++;
894930 } else if (it.value ()->valid ) {
895931 TraceEvent (SevDebug, " DDInitFoundDataMove" , self->ddId ).detail (" DataMove" , meta.toString ());
896932 ASSERT (meta.ranges .front () == it.range ());
@@ -914,9 +950,24 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
914950 self->shardsAffectedByTeamFailure ->moveShard (rs.keys , teams);
915951 self->relocationProducer .send (rs);
916952 wait (yield (TaskPriority::DataDistribution));
953+ validMoves++;
954+ }
955+ if (now () - lastLogTime >= 30.0 ) {
956+ lastLogTime = now ();
957+ TraceEvent (" DDInitResumeDataMovesProgress" , self->ddId )
958+ .detail (" ValidMoves" , validMoves)
959+ .detail (" CancelledMoves" , cancelledMoves)
960+ .detail (" EmptyMoves" , emptyMoves)
961+ .detail (" ElapsedSeconds" , now () - resumeStart);
917962 }
918963 }
919964
965+ TraceEvent (" DDInitResumedDataMoves" , self->ddId )
966+ .detail (" ValidMoves" , validMoves)
967+ .detail (" CancelledMoves" , cancelledMoves)
968+ .detail (" EmptyMoves" , emptyMoves)
969+ .detail (" ElapsedSeconds" , now () - resumeStart);
970+
920971 // Trigger background cleanup for datamove tombstones
921972 if (!self->txnProcessor ->isMocked ()) {
922973 self->addActor .send (self->removeDataMoveTombstoneBackground (self));
@@ -2588,6 +2639,7 @@ ACTOR Future<Void> dataDistribution(Reference<DataDistributor> self,
25882639
25892640 loop {
25902641 self->context ->trackerCancelled = false ;
2642+ state double ddStartTime = now ();
25912643 // whether all initial shard are tracked
25922644 self->initialized = Promise<Void>();
25932645
@@ -2599,7 +2651,7 @@ ACTOR Future<Void> dataDistribution(Reference<DataDistributor> self,
25992651
26002652 wait (DataDistributor::init (self));
26012653
2602- TraceEvent (SevInfo, " DataDistributionInitProgress " , self->ddId ).detail (" Phase " , " Metadata Initialized " );
2654+ TraceEvent (" DDInitDataLoaded " , self->ddId ).detail (" ElapsedSeconds " , now () - ddStartTime );
26032655
26042656 // When/If this assertion fails, Evan owes Ben a pat on the back for his foresight
26052657 ASSERT (self->configuration .storageTeamSize > 0 );
@@ -2831,6 +2883,10 @@ ACTOR Future<Void> dataDistribution(Reference<DataDistributor> self,
28312883 self->context ->markTrackerCancelled ();
28322884 state Error err = e;
28332885 TraceEvent (" DataDistributorDestroyTeamCollections" , self->ddId ).error (e);
2886+ // Log every DD exit with the reason. movekeys_conflict is the most common
2887+ // non-kill cause — it's a normal internal restart, but was previously
2888+ // invisible because reportErrorsExcept suppresses logging for "normal" DD errors.
2889+ TraceEvent (SevWarn, " DDExiting" , self->ddId ).error (e).detail (" ErrorCode" , e.code ());
28342890 state std::vector<UID> teamForDroppedRange;
28352891 if (removeFailedServer.getFuture ().isReady () && !removeFailedServer.getFuture ().isError ()) {
28362892 // Choose a random healthy team to host the to-be-dropped range.
@@ -5127,6 +5183,10 @@ ACTOR Future<Void> dataDistributor_impl(DataDistributorInterface di,
51275183 &normalDataDistributorErrors ());
51285184
51295185 try {
5186+ TraceEvent (" DataDistributorRunning" , di.id ());
5187+ // DDInitRunning duplicates the above with DDInit* prefix so the full startup sequence
5188+ // can be queried with Type="DDInit*" in trace logs
5189+ TraceEvent (" DDInitRunning" , di.id ());
51305190 loop choose {
51315191 when (wait (distributor || collection)) {
51325192 ASSERT (false );
0 commit comments