-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Make log servers return an empty version range only when it is correct to do so #12188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
an empty version range (on peeks) only when it is correct to do so. This is so the receiver will receive all versions (even though the sender is sending an empty version range) that it is supposed to receive. Changes: - Make the cluster controller collect the set of log servers participated in recovery and propagate that information to the other processes. - Extend the ServerPeekCursor to take a flag that tells the source log server whether it can return an empty version range or not (in the context of version vector/unicast), and make the source log server return an empty version range only when this flag is set. - Make the peek APIs set the flag appropriately when initializing ServerPeekCursors. - Also, take the internal logic used by SetPeekCursor and MergedPeekCursor into account while initializing the above mentioned flag.
Result of foundationdb-pr-clang-ide on Linux RHEL 9
|
Result of foundationdb-pr-macos-m1 on macOS Ventura 13.x
|
Result of foundationdb-pr-clang-arm on Linux CentOS 7
|
Result of foundationdb-pr-clang on Linux RHEL 9
|
Result of foundationdb-pr on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests on Linux RHEL 9
|
int bestSet, | ||
int& bestServer, | ||
Optional<Version> end, | ||
Optional<std::map<uint8_t, std::vector<uint16_t>>> knownLockedTLogIds) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo - do both these have to be optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TagPartitionedLogSystem::peekLogRouter(), an invoker of this, takes these arguments as Optional. Outside the recovery context, I don't think these arguments need to be specified so I think it makes sense to have these as optional. Also I plan to feed the locked server list from the serialized TagPartitionedLogSystem to this method from TagPartitionedLogSystem::peekLogRouter() in a follow up PR, so I think it makes sense to have this argument as Optional in that sense too. The "Optional end" argument has a value assigned to it in both the contexts that this method is currently getting called from, so it may not need to be Optional (but we may not want to change this purely based on the current invokers).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more context, I added the argument Optional<Version> end
to TagPartitionedLogSystem::peekLogRouter()
. In that iteration end
would have to be present and not equal to -1 to indicate we are in recovery and should return up to end
.
It would be good to not add any extra work for the non-version-vector case. ie. only call resetBestServerIfNotLocked
if version vector is enabled, as was done for resetBestServerIfNotAvailable()
I think knownLockedTLogIds
could be a reference, maybe const.
@@ -1997,11 +2038,13 @@ Optional<DurableVersionInfo> TagPartitionedLogSystem::getDurableVersion(UID dbgi | |||
std::vector<TLogLockResult> results; | |||
std::string sServerState; | |||
LocalityGroup unResponsiveSet; | |||
std::vector<uint16_t> lockedTLogIds; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can lockedTLogIds.reserve(logSet->logServers.size());
to prevent repeated reallocations.
results[new_safe_range_begin].end, | ||
results, | ||
failedLogsCompletePolicy, | ||
lockedTLogIds); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid copying the vector into the constructor here, I think you can define DurableVersionInfo::std::vector<uint16_t> knownLockedTLogIds;
to be DurableVersionInfo::std::vector<uint16_t> &&knownLockedTLogIds;
. Or alternatively, make a constructor for DurableVersionInfo(...lockedTLogIds)
that sets lockedTLogIds = std::move(lockedTLogIds);
The same could be done with results
.
|
||
TLogPeekRequest(Version begin, | ||
Tag tag, | ||
bool returnIfBlocked, | ||
bool onlySpilled, | ||
Optional<std::pair<UID, int>> sequence = Optional<std::pair<UID, int>>(), | ||
Optional<Version> end = Optional<Version>()) | ||
Optional<Version> end = Optional<Version>(), | ||
Optional<bool> returnEmptyIfStopped = Optional<bool>()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the new variable returnEmptyIfStopped
necessary? Prior to the PR, Optional end
being present indicated "return empty if stopped" and end
should only be set in that case. The Optional end
could be renamed to clarify that intention.
int bestSet, | ||
int& bestServer, | ||
Optional<Version> end, | ||
Optional<std::map<uint8_t, std::vector<uint16_t>>> knownLockedTLogIds) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more context, I added the argument Optional<Version> end
to TagPartitionedLogSystem::peekLogRouter()
. In that iteration end
would have to be present and not equal to -1 to indicate we are in recovery and should return up to end
.
It would be good to not add any extra work for the non-version-vector case. ie. only call resetBestServerIfNotLocked
if version vector is enabled, as was done for resetBestServerIfNotAvailable()
I think knownLockedTLogIds
could be a reference, maybe const.
Tag tag, | ||
bool useSatellite, | ||
Optional<Version> end, | ||
Optional<std::map<uint8_t, std::vector<uint16_t>>> knownStoppedTLogIds) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think knownStoppedTLogIds
can be a reference, maybe pipe it through as a const as well.
quorumResults.push_back(quorum(tLogCommitResults, tLogCommitResults.size() - it->tLogWriteAntiQuorum)); | ||
logGroupLocal++; | ||
} | ||
|
||
return minVersionWhenReady(waitForAll(quorumResults), allReplies); | ||
} | ||
|
||
void TagPartitionedLogSystem::resetBestServerIfNotLocked( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a few comments describing this function's purpose, so maintainers do not have to dig through PR history, thanks
@@ -667,13 +668,31 @@ Future<Version> TagPartitionedLogSystem::push(const ILogSystem::PushVersionSet& | |||
tLogCommitResults.push_back(commitSuccess); | |||
location++; | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit remove
In the context of version vector/unicast, make log servers return an empty version range (on peeks) only when it is correct to do so. This is so the receiver will receive all versions (even though the sender is sending an empty version range) that it is supposed to receive.
Changes:
Testing:
Joshua id (with version vector disabled): 20250609-200159-sre-0c15ba89fee21207 (no failures).
Code-Reviewer Section
The general pull request guidelines can be found here.
Please check each of the following things and check all boxes before accepting a PR.
For Release-Branches
If this PR is made against a release-branch, please also check the following:
release-branch
ormain
if this is the youngest branch)