Skip to content

Commit 30c7a2a

Browse files
saintstackmichael stack
andauthored
Add DD init visibility, metrics retries, shard tracking, scan progress, and team collection logging (#12913)
* Add DD init and team collection logging for diagnosing slow startups When SHARD_ENCODE_LOCATION_METADATA=true we take new codepaths often opaque. Add logging. For example, DD init hung for 14-16 minutes with zero visibility into what was stuck. The only clue was a gap between DDInitUpdatedReplicaKeys and DDInitGotInitialDD trace events. Diagnosing the root cause required extensive log splunking of SS metrics to determine that a single getRange(dataMoveKeys) read was queued on an overloaded storage server. DDTxnProcessor.actor.cpp: - Log elapsed time for the server list + data move read transaction (DDInitServerListAndDataMoveReadComplete) with NumDataMoves, NumServers - Log elapsed time for the keyServer scan (DDInitKeyServerScanComplete) with NumShards - Warn when getRange(dataMoveKeys) takes >5 seconds (DDInitSlowDataMoveRead) DataDistribution.actor.cpp: - Add NumShards and NumServers to DDInitGotInitialDD - Promote DDInitFoundDataMove from SevDebug to SevInfo so individual data moves are visible in production logs - Add DDInitResumedDataMoves summary event with ValidMoves, CancelledMoves, EmptyMoves counts and elapsed time DDTeamCollection.actor.cpp: - Add Reason and Address details to UndesiredStorageServer trace events to distinguish version lag, same-address, wrong-class, and exclusion causes without needing to correlate with other log lines * Revert DDInitFoundDataMove to SevDebug to avoid log spam with many data moves * Add DD startup visibility: metrics retries, shard tracking, scan progress Additional logging to address DD operational opacity during startup, based on past incidents where DD hung with no visibility into the cause. NativeAPI.actor.cpp: - Log WaitStorageMetricsRetrying every 60s when waitStorageMetrics is stuck retrying wrong_shard_server or all_alternatives_failed, with the key range, retry count, and elapsed time. Previously these retries were silent (SevDebug only), making it impossible to identify which shard was stuck or that retries were even happening. DDShardTracker.actor.cpp: - Log TrackInitialShardsComplete after shard tracker setup with count - Log TrackInitialShardsMetricsComplete after changeSizes() finishes with elapsed time. changeSizes() waits for ALL shards to report metrics via getFirstSize/waitStorageMetrics -- if any shard metrics never arrive, this hangs silently. DDTxnProcessor.actor.cpp: - Log DDInitKeyServerScanProgress every 30s during the multi-transaction keyServer scan with current beginKey, batch count, shards scanned, and elapsed time. With 255K shards this scan requires many transactions and a stuck one was previously invisible. DataDistribution.actor.cpp: - Log DDInitComplete with elapsed time after DataDistributor::init() finishes, providing a single event showing total init duration. * Formatting * Try to get past gcc 13 compile faillures * Try and fix FAILED: flow/CMakeFiles/flow.dir/ActorCollection.actor.g.cpp.o /usr/local/bin/ccache /usr/local/bin/clang++ -DBOOST_ATOMIC_NO_LIB -DBOOST_CONTEXT_NO_LIB -DBOOST_ERROR_CODE_HEADER_ONLY -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_NO_LIB -DBOOST_SERIALIZATION_NO_LIB -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_SYSTEM_NO_LIB -DNO_INTELLISENSE -DWITH_FOLLY_MEMCPY -DCOMPILATION_UNIT=/codebuild/output/src2645037596/src/github.com/apple/foundationdb/build_output/flow/ActorCollection.actor.g.cpp -I/codebuild/output/src2645037596/src/github.com/apple/foundationdb/flow/include -I/codebuild/output/src2645037596/src/github.com/apple/foundationdb/build_output/flow/include -I/codebuild/output/src2645037596/src/github.com/apple/foundationdb/contrib/stacktrace/include -I/codebuild/output/src2645037596/src/github.com/apple/foundationdb/contrib/fmt-8.1.1/include -I/codebuild/output/src2645037596/src/github.com/apple/foundationdb/contrib/SimpleOpt/include -I/codebuild/output/src2645037596/src/github.com/apple/foundationdb/contrib/crc32/include -I/codebuild/output/src2645037596/src/github.com/apple/foundationdb/contrib/folly_memcpy -isystem /opt/boost_1_78_0_clang/include -stdlib=libc++ -O3 -DNDEBUG -std=gnu++20 -DCMAKE_BUILD -fno-omit-frame-pointer -gdwarf-4 -ggdb1 -gz -Wall -Wextra -Wredundant-move -Wpessimizing-move -Woverloaded-virtual -Wshift-sign-overflow -Wno-sign-compare -Wno-undefined-var-template -Wno-unknown-warning-option -Wno-unused-parameter -Wno-constant-logical-operand -Wno-deprecated-copy -Wno-delete-non-abstract-non-virtual-dtor -Wno-range-loop-construct -Wno-reorder-ctor -Wno-unused-command-line-argument -Wno-ambiguous-reversed-operator -Wno-register -Werror -Wno-error=format -Wunused-variable -Wno-deprecated -fvisibility=hidden -Wreturn-type -fPIC -march=armv8.2-a+crc+simd -DHAVE_OPENSSL -Wno-unused-function -MD -MT flow/CMakeFiles/flow.dir/ActorCollection.actor.g.cpp.o -MF flow/CMakeFiles/flow.dir/ActorCollection.actor.g.cpp.o.d -o flow/CMakeFiles/flow.dir/ActorCollection.actor.g.cpp.o -c /codebuild/output/src2645037596/src/github.com/apple/foundationdb/build_output/flow/ActorCollection.actor.g.cpp In file included from /codebuild/output/src2645037596/src/github.com/apple/foundationdb/flow/ActorCollection.actor.cpp:21: In file included from /codebuild/output/src2645037596/src/github.com/apple/foundationdb/flow/include/flow/ActorCollection.h:25: In file included from /codebuild/output/src2645037596/src/github.com/apple/foundationdb/flow/include/flow/flow.h:23: In file included from /codebuild/output/src2645037596/src/github.com/apple/foundationdb/flow/include/flow/Arena.h:37: In file included from /opt/boost_1_78_0_clang/include/boost/functional/hash.hpp:6: /opt/boost_1_78_0_clang/include/boost/container_hash/hash.hpp:132:33: error: no template named 'unary_function' in namespace 'std'; did you mean '__unary_function'? 132 | struct hash_base : std::unary_function<T, std::size_t> {}; | ~~~~~^ /usr/local/bin/../include/c++/v1/__functional/unary_function.h:46:1: note: '__unary_function' declared here 46 | using __unary_function = __unary_function_keep_layout_base<_Arg, _Result>; | ^ 1 error generated. * Address PR review feedback - NativeAPI.actor.cpp: Move retry logging outside the error-type if block so all errors get keys/elapsed/retries details. Use severity upgrade (SevDebug -> SevWarn after 60s) on the existing WaitStorageMetricsHandleError event instead of a separate event name. - DataDistribution.actor.cpp: Add periodic progress logging (every 30s) in resumeFromDataMoves loop so operators can watch counts go up during long data move recovery. - CompileBoost.cmake: Remove BOOST_NO_CXX98_FUNCTION_BASE since 7.3 CI is broken independently of this change. * More definition of what comprises DD startup * Add explanation as to why DDStarted is where it is * Rename traces I added to have DDInit as prefix instead of just DD * s/DD*/DDInit*/ for DD init loggings query * Log DD exit reason as DDExiting at SevWarn DD exits (e.g. movekeys_conflict) were invisible because reportErrorsExcept suppresses logging for "normal" DD errors. Add DDExiting trace event at SevWarn with error and code so every DD death is visible in trace logs. * Fix comment --------- Co-authored-by: michael stack <stack@duboce.com>
1 parent a042081 commit 30c7a2a

6 files changed

Lines changed: 139 additions & 5 deletions

File tree

fdbclient/NativeAPI.actor.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8022,6 +8022,9 @@ ACTOR Future<std::pair<Optional<StorageMetrics>, int>> waitStorageMetrics(
80228022
int expectedShardCount,
80238023
Optional<Reference<TransactionState>> trState) {
80248024
state Span span("NAPI:WaitStorageMetrics"_loc, generateSpanID(cx->transactionTracingSample));
8025+
state double startTime = now();
8026+
state double lastLogTime = 0;
8027+
state int retryCount = 0;
80258028
loop {
80268029
if (trState.present()) {
80278030
wait(trState.get()->startTransaction());
@@ -8065,7 +8068,14 @@ ACTOR Future<std::pair<Optional<StorageMetrics>, int>> waitStorageMetrics(
80658068
return std::make_pair(res, -1);
80668069
}
80678070
} catch (Error& e) {
8068-
TraceEvent(SevDebug, "WaitStorageMetricsHandleError").error(e);
8071+
retryCount++;
8072+
// Upgrade from SevDebug to SevWarn after 60 seconds of retrying
8073+
Severity sev = (now() - startTime > 60.0) ? SevWarn : SevDebug;
8074+
TraceEvent(sev, "WaitStorageMetricsHandleError")
8075+
.error(e)
8076+
.detail("Keys", keys)
8077+
.detail("Elapsed", now() - startTime)
8078+
.detail("Retries", retryCount);
80698079
if (e.code() == error_code_wrong_shard_server || e.code() == error_code_all_alternatives_failed) {
80708080
cx->invalidateCache(tenantInfo.prefix, keys);
80718081
wait(delay(CLIENT_KNOBS->WRONG_SHARD_SERVER_DELAY, TaskPriority::DataDistribution));

fdbserver/DDShardTracker.actor.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,9 +1313,23 @@ ACTOR Future<Void> trackInitialShards(DataDistributionTracker* self, Reference<I
13131313
wait(yield(TaskPriority::DataDistribution));
13141314
}
13151315

1316+
TraceEvent("TrackInitialShardsComplete", self->distributorId).detail("ShardsTracked", s);
1317+
1318+
state double changeSizesStart = now();
13161319
Future<Void> initialSize = changeSizes(self, KeyRangeRef(allKeys.begin, allKeys.end), 0);
13171320
self->readyToStart.send(Void());
13181321
wait(initialSize);
1322+
1323+
TraceEvent("TrackInitialShardsMetricsComplete", self->distributorId)
1324+
.detail("ElapsedSeconds", now() - changeSizesStart);
1325+
1326+
// DDInitDone bookends DDInitRunning — marks DD fully operational. Uses DD* prefix so
1327+
// the full startup sequence can be queried with Type="DD*" in trace logs.
1328+
// Ideally this would be in DataDistribution.actor.cpp but dataDistribution() has no
1329+
// callback after trackInitialShards completes — it launches all actors and waits forever.
1330+
// Adding a new promise to signal completion would work but risks disturbing current operation.
1331+
TraceEvent("DDInitDone", self->distributorId);
1332+
13191333
self->maxShardSizeUpdater = updateMaxShardSize(self->dbSizeEstimate, self->maxShardSize);
13201334

13211335
return Void();

fdbserver/DDTeamCollection.actor.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,17 @@ class DDTeamCollectionImpl {
12641264
state Future<Void> storageMetadataTracker = self->updateStorageMetadata(server);
12651265
try {
12661266
loop {
1267-
status.isUndesired = !self->disableFailingLaggingServers.get() && server->ssVersionTooFarBehind.get();
1267+
{
1268+
bool versionLagUndesired =
1269+
!self->disableFailingLaggingServers.get() && server->ssVersionTooFarBehind.get();
1270+
if (versionLagUndesired && !status.isUndesired) {
1271+
TraceEvent(SevWarn, "UndesiredStorageServer", self->distributorId)
1272+
.detail("Server", server->getId())
1273+
.detail("Address", server->getLastKnownInterface().address())
1274+
.detail("Reason", "VersionLag");
1275+
}
1276+
status.isUndesired = versionLagUndesired;
1277+
}
12681278
status.isWrongConfiguration = false;
12691279
status.isWiggling = false;
12701280
hasWrongDC = !self->isCorrectDC(*server);
@@ -1298,6 +1308,7 @@ class DDTeamCollectionImpl {
12981308
TraceEvent(SevWarn, "UndesiredStorageServer", self->distributorId)
12991309
.detail("Server", server->getId())
13001310
.detail("Address", server->getLastKnownInterface().address())
1311+
.detail("Reason", "SameAddress")
13011312
.detail("OtherServer", i.second->getId())
13021313
.detail("NumShards",
13031314
self->shardsAffectedByTeamFailure->getNumberOfShards(server->getId()))
@@ -1323,6 +1334,8 @@ class DDTeamCollectionImpl {
13231334
if (self->optimalTeamCount > 0) {
13241335
TraceEvent(SevWarn, "UndesiredStorageServer", self->distributorId)
13251336
.detail("Server", server->getId())
1337+
.detail("Address", server->getLastKnownInterface().address())
1338+
.detail("Reason", "WrongMachineClass")
13261339
.detail("OptimalTeamCount", self->optimalTeamCount)
13271340
.detail("Fitness", server->getLastKnownClass().machineClassFitness(ProcessClass::Storage));
13281341
status.isUndesired = true;
@@ -1399,9 +1412,16 @@ class DDTeamCollectionImpl {
13991412
}
14001413

14011414
if (worstStatus != DDTeamCollection::Status::NONE) {
1415+
const char* exclusionType = worstStatus == DDTeamCollection::Status::WIGGLING ? "Wiggling"
1416+
: worstStatus == DDTeamCollection::Status::FAILED ? "Failed"
1417+
: worstStatus == DDTeamCollection::Status::EXCLUDED ? "Excluded"
1418+
: "Unknown";
14021419
TraceEvent(SevWarn, "UndesiredStorageServer", self->distributorId)
14031420
.detail("Server", server->getId())
1404-
.detail("Excluded", worstAddr.toString());
1421+
.detail("Address", server->getLastKnownInterface().address())
1422+
.detail("Reason", "Excluded")
1423+
.detail("ExclusionType", exclusionType)
1424+
.detail("ExcludedAddress", worstAddr.toString());
14051425
status.isUndesired = true;
14061426
status.isWrongConfiguration = true;
14071427

fdbserver/DDTxnProcessor.actor.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ class DDTxnProcessorImpl {
255255
CODE_PROBE((bool)skipDDModeCheck, "DD Mode won't prevent read initial data distribution.");
256256
// Get the server list in its own try/catch block since it modifies result. We don't want a subsequent failure
257257
// causing entries to be duplicated
258+
// Phase 1: Single transaction to read server list and all persisted data moves
259+
state double serverListAndDataMoveReadStart = now();
258260
loop {
259261
numDataMoves = 0;
260262
server_dc.clear();
@@ -312,7 +314,12 @@ class DDTxnProcessorImpl {
312314
}
313315
}
314316

317+
state double dataMoveReadStart = now();
315318
RangeResult dms = wait(tr.getRange(dataMoveKeys, CLIENT_KNOBS->TOO_MANY));
319+
if (now() - dataMoveReadStart > 5.0) {
320+
TraceEvent(SevWarn, "DDInitSlowDataMoveRead", distributorId)
321+
.detail("ElapsedSeconds", now() - dataMoveReadStart);
322+
}
316323
ASSERT(!dms.more && dms.size() < CLIENT_KNOBS->TOO_MANY);
317324
// For each data move, find out the src or dst servers are in primary or remote DC.
318325
for (int i = 0; i < dms.size(); ++i) {
@@ -360,6 +367,11 @@ class DDTxnProcessorImpl {
360367

361368
succeeded = true;
362369

370+
TraceEvent("DDInitServerListAndDataMoveReadComplete", distributorId)
371+
.detail("NumDataMoves", numDataMoves)
372+
.detail("NumServers", result->allServers.size())
373+
.detail("ElapsedSeconds", now() - serverListAndDataMoveReadStart);
374+
363375
break;
364376
} catch (Error& e) {
365377
TraceEvent("GetInitialTeamsRetry", distributorId).error(e);
@@ -371,6 +383,10 @@ class DDTxnProcessorImpl {
371383

372384
// If keyServers is too large to read in a single transaction, then we will have to break this process up into
373385
// multiple transactions. In that case, each iteration should begin where the previous left off
386+
// Scan keyServers in batches to build the shard map
387+
state double keyServerScanStart = now();
388+
state double lastScanLogTime = now();
389+
state int scanBatchCount = 0;
374390
while (beginKey < allKeys.end) {
375391
CODE_PROBE(beginKey > allKeys.begin, "Multi-transactional getInitialDataDistribution");
376392
loop {
@@ -457,6 +473,15 @@ class DDTxnProcessorImpl {
457473

458474
ASSERT_GT(keyServers.size(), 0);
459475
beginKey = keyServers.end()[-1].key;
476+
scanBatchCount++;
477+
if (now() - lastScanLogTime >= 30.0) {
478+
lastScanLogTime = now();
479+
TraceEvent("DDInitKeyServerScanProgress", distributorId)
480+
.detail("BeginKey", beginKey)
481+
.detail("Batches", scanBatchCount)
482+
.detail("ShardsScanned", result->shards.size())
483+
.detail("ElapsedSeconds", now() - keyServerScanStart);
484+
}
460485
break;
461486
} catch (Error& e) {
462487
TraceEvent("GetInitialTeamsKeyServersRetry", distributorId).error(e);
@@ -473,6 +498,10 @@ class DDTxnProcessorImpl {
473498
// a dummy shard at the end with no keys or servers makes life easier for trackInitialShards()
474499
result->shards.push_back(DDShardInfo(allKeys.end));
475500

501+
TraceEvent("DDInitKeyServerScanComplete", distributorId)
502+
.detail("NumShards", result->shards.size())
503+
.detail("ElapsedSeconds", now() - keyServerScanStart);
504+
476505
if (SERVER_KNOBS->SHARD_ENCODE_LOCATION_METADATA && numDataMoves > 0) {
477506
for (int shard = 0; shard < result->shards.size() - 1; ++shard) {
478507
const DDShardInfo& iShard = result->shards[shard];

fdbserver/DataDistribution.actor.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,31 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
505505
// Initialize the required internal states of DataDistributor from system metadata. It's necessary before
506506
// DataDistributor start working. Doesn't include initialization of optional components, like TenantCache, DDQueue,
507507
// Tracker, TeamCollection. The components should call its own ::init methods.
508+
//
509+
// DD Startup Progress (trace events in order):
510+
// DDInitRunning - DD process recruited and starting init
511+
// DDInitTakingMoveKeysLock - Acquiring move keys lock
512+
// DDInitTookMoveKeysLock - Lock acquired
513+
// DDInitGotConfiguration - Database configuration loaded
514+
// DDInitUpdatedReplicaKeys - Replica keys updated
515+
// DDInitSlowDataMoveRead - (SevWarn) dataMoveKeys read taking >5s
516+
// DDInitServerListAndDataMoveReadComplete - Server list + data moves read: NumDataMoves, NumServers,
517+
// ElapsedSeconds
518+
// DDInitKeyServerScanProgress - (every 30s) keyServer scan: BeginKey, Batches, ShardsScanned
519+
// DDInitKeyServerScanComplete - keyServer scan done: NumShards, ElapsedSeconds
520+
// DDInitGotInitialDD - Init data loaded: NumShards, NumServers
521+
// DDInitDataLoaded - Init data loaded, ElapsedSeconds (does NOT mean DD is fully operational)
522+
//
523+
// After init(), the following startup events fire from other components:
524+
// DDInitResumeDataMovesProgress - (every 30s) data move resume: ValidMoves, CancelledMoves, EmptyMoves
525+
// DDInitResumedDataMoves - Data move resume complete with counts
526+
// TrackInitialShards - Shard tracker setup started with InitialShardCount
527+
// TrackInitialShardsComplete - Shard trackers created: ShardsTracked
528+
// DDTrackerStarting - Teams ready (fires from DDTeamCollection after readyToStart + delay)
529+
// TrackInitialShardsMetricsComplete - All shard metrics received: ElapsedSeconds
530+
// WaitStorageMetricsHandleError may fire (SevWarn after 60s) if a
531+
// shard's metrics read is stuck retrying: Keys, Retries
532+
// DDInitDone - DD is fully operational with all shard sizes loaded
508533
ACTOR static Future<Void> init(Reference<DataDistributor> self) {
509534
loop {
510535
TraceEvent("DDInitTakingMoveKeysLock", self->ddId).log();
@@ -554,13 +579,17 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
554579
.detail("E", self->initData->shards.end()[-1].key)
555580
.detail("Src", describe(self->initData->shards.end()[-2].primarySrc))
556581
.detail("Dest", describe(self->initData->shards.end()[-2].primaryDest))
582+
.detail("NumShards", self->initData->shards.size())
583+
.detail("NumServers", self->initData->allServers.size())
557584
.trackLatest(self->initialDDEventHolder->trackingKey);
558585
} else {
559586
TraceEvent("DDInitGotInitialDD", self->ddId)
560587
.detail("B", "")
561588
.detail("E", "")
562589
.detail("Src", "[no items]")
563590
.detail("Dest", "[no items]")
591+
.detail("NumShards", self->initData->shards.size())
592+
.detail("NumServers", self->initData->allServers.size())
564593
.trackLatest(self->initialDDEventHolder->trackingKey);
565594
}
566595

@@ -752,13 +781,19 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
752781
// TODO: unit test needed
753782
ACTOR static Future<Void> resumeFromDataMoves(Reference<DataDistributor> self, Future<Void> readyToStart) {
754783
state KeyRangeMap<std::shared_ptr<DataMove>>::iterator it = self->initData->dataMoveMap.ranges().begin();
784+
state int validMoves = 0;
785+
state int cancelledMoves = 0;
786+
state int emptyMoves = 0;
787+
state double resumeStart = now();
788+
state double lastLogTime = now();
755789

756790
wait(readyToStart);
757791

758792
for (; it != self->initData->dataMoveMap.ranges().end(); ++it) {
759793
const DataMoveMetaData& meta = it.value()->meta;
760794
if (meta.ranges.empty()) {
761795
TraceEvent(SevInfo, "EmptyDataMoveRange", self->ddId).detail("DataMoveMetaData", meta.toString());
796+
emptyMoves++;
762797
continue;
763798
}
764799
if (it.value()->isCancelled() || (it.value()->valid && !SERVER_KNOBS->SHARD_ENCODE_LOCATION_METADATA)) {
@@ -767,6 +802,7 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
767802
rs.cancelled = true;
768803
self->relocationProducer.send(rs);
769804
TraceEvent("DDInitScheduledCancelDataMove", self->ddId).detail("DataMove", meta.toString());
805+
cancelledMoves++;
770806
} else if (it.value()->valid) {
771807
TraceEvent(SevDebug, "DDInitFoundDataMove", self->ddId).detail("DataMove", meta.toString());
772808
ASSERT(meta.ranges.front() == it.range());
@@ -790,9 +826,24 @@ struct DataDistributor : NonCopyable, ReferenceCounted<DataDistributor> {
790826
self->shardsAffectedByTeamFailure->moveShard(rs.keys, teams);
791827
self->relocationProducer.send(rs);
792828
wait(yield(TaskPriority::DataDistribution));
829+
validMoves++;
830+
}
831+
if (now() - lastLogTime >= 30.0) {
832+
lastLogTime = now();
833+
TraceEvent("DDInitResumeDataMovesProgress", self->ddId)
834+
.detail("ValidMoves", validMoves)
835+
.detail("CancelledMoves", cancelledMoves)
836+
.detail("EmptyMoves", emptyMoves)
837+
.detail("ElapsedSeconds", now() - resumeStart);
793838
}
794839
}
795840

841+
TraceEvent("DDInitResumedDataMoves", self->ddId)
842+
.detail("ValidMoves", validMoves)
843+
.detail("CancelledMoves", cancelledMoves)
844+
.detail("EmptyMoves", emptyMoves)
845+
.detail("ElapsedSeconds", now() - resumeStart);
846+
796847
// Trigger background cleanup for datamove tombstones
797848
self->addActor.send((self->removeDataMoveTombstoneBackground(self)));
798849

@@ -920,6 +971,7 @@ ACTOR Future<Void> dataDistribution(Reference<DataDistributor> self,
920971

921972
loop {
922973
trackerCancelled = false;
974+
state double ddStartTime = now();
923975
// whether all initial shard are tracked
924976
self->initialized = Promise<Void>();
925977

@@ -930,6 +982,8 @@ ACTOR Future<Void> dataDistribution(Reference<DataDistributor> self,
930982
try {
931983
wait(DataDistributor::init(self));
932984

985+
TraceEvent("DDInitDataLoaded", self->ddId).detail("ElapsedSeconds", now() - ddStartTime);
986+
933987
// When/If this assertion fails, Evan owes Ben a pat on the back for his foresight
934988
ASSERT(self->configuration.storageTeamSize > 0);
935989

@@ -1115,6 +1169,10 @@ ACTOR Future<Void> dataDistribution(Reference<DataDistributor> self,
11151169
trackerCancelled = true;
11161170
state Error err = e;
11171171
TraceEvent("DataDistributorDestroyTeamCollections").error(e);
1172+
// Log every DD exit with the reason. movekeys_conflict is the most common
1173+
// non-kill cause — it's a normal internal restart, but was previously
1174+
// invisible because reportErrorsExcept suppresses logging for "normal" DD errors.
1175+
TraceEvent(SevWarn, "DDExiting", self->ddId).error(e).detail("ErrorCode", e.code());
11181176
state std::vector<UID> teamForDroppedRange;
11191177
if (removeFailedServer.getFuture().isReady() && !removeFailedServer.getFuture().isError()) {
11201178
// Choose a random healthy team to host the to-be-dropped range.
@@ -3298,6 +3356,9 @@ ACTOR Future<Void> dataDistributor(DataDistributorInterface di, Reference<AsyncV
32983356

32993357
try {
33003358
TraceEvent("DataDistributorRunning", di.id());
3359+
// DDInitRunning duplicates the above with DDInit* prefix so the full startup sequence
3360+
// can be queried with Type="DDInit*" in trace logs
3361+
TraceEvent("DDInitRunning", di.id());
33013362
self->addActor.send(waitFailureServer(di.waitFailure.getFuture()));
33023363
self->addActor.send(cacheServerWatcher(&cx));
33033364
state Future<Void> distributor = reportErrorsExcept(

flow/include/flow/IndexedSet.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,11 @@ struct IndexedSet {
344344
// direction 0 = left, 1 = right
345345
template <int direction>
346346
static void moveIterator(Node const*& node) {
347-
moveIteratorImpl<direction, true>(node);
347+
IndexedSet::template moveIteratorImpl<direction, true>(node);
348348
}
349349
template <int direction>
350350
static void moveIterator(Node*& node) {
351-
moveIteratorImpl<direction, false>(node);
351+
IndexedSet::template moveIteratorImpl<direction, false>(node);
352352
}
353353

354354
public: // but testonly

0 commit comments

Comments
 (0)