Explicitly using min and max restorable version from backup description in query command in stead of going throw snapshots

This commit is contained in:
Zhe Wu 2023-02-26 12:17:07 -08:00
parent 92a90c78d2
commit ffa3467098
3 changed files with 35 additions and 21 deletions

View File

@ -2697,6 +2697,24 @@ static void reportBackupQueryError(UID operationId, JsonBuilderObject& result, s
TraceEvent("BackupQueryFailure").detail("OperationId", operationId).detail("Reason", errorMessage);
}
std::pair<Version, Version> getMaxMinRestorableVersions(const BackupDescription& desc, bool mayOnlyApplyMutationLog) {
Version maxRestorableVersion = invalidVersion;
Version minRestorableVersion = invalidVersion;
if (desc.maxRestorableVersion.present()) {
maxRestorableVersion = desc.maxRestorableVersion.get();
} else if (mayOnlyApplyMutationLog && desc.contiguousLogEnd.present()) {
maxRestorableVersion = desc.contiguousLogEnd.get();
}
if (desc.minRestorableVersion.present()) {
minRestorableVersion = desc.minRestorableVersion.get();
} else if (mayOnlyApplyMutationLog && desc.minLogBegin.present()) {
minRestorableVersion = desc.minLogBegin.get();
}
return std::make_pair(maxRestorableVersion, minRestorableVersion);
}
// If restoreVersion is invalidVersion or latestVersion, use the maximum or minimum restorable version respectively for
// selected key ranges. If restoreTimestamp is specified, any specified restoreVersion will be overriden to the version
// resolved to that timestamp.
@ -2753,23 +2771,21 @@ ACTOR Future<Void> queryBackup(const char* name,
try {
state Reference<IBackupContainer> bc = openBackupContainer(name, destinationContainer, proxy, {});
BackupDescription desc = wait(bc->describeBackup());
auto [maxRestorableVersion, minRestorableVersion] = getMaxMinRestorableVersions(desc, !keyRangesFilter.empty());
if (restoreVersion == invalidVersion) {
BackupDescription desc = wait(bc->describeBackup());
if (desc.maxRestorableVersion.present()) {
restoreVersion = desc.maxRestorableVersion.get();
// Use continuous log end version for the maximum restorable version for the key ranges.
} else if (keyRangesFilter.size() && desc.contiguousLogEnd.present()) {
restoreVersion = desc.contiguousLogEnd.get();
} else {
reportBackupQueryError(
operationId,
result,
errorMessage = format("the backup for the specified key ranges is not restorable to any version"));
}
TraceEvent("BackupQueryResolveMaxRestoreVersion").detail("Version", restoreVersion);
restoreVersion = maxRestorableVersion;
}
if (restoreVersion < 0 && restoreVersion != earliestVersion) {
if (restoreVersion == earliestVersion) {
restoreVersion = minRestorableVersion;
}
if (snapshotVersion == earliestVersion) {
snapshotVersion = minRestorableVersion;
}
TraceEvent("BackupQueryResolveRestoreVersion")
.detail("RestoreVersion", restoreVersion)
.detail("SnapshotVersion", snapshotVersion);
if (restoreVersion < 0) {
reportBackupQueryError(operationId,
result,
errorMessage =
@ -2785,7 +2801,6 @@ ACTOR Future<Void> queryBackup(const char* name,
Optional<RestorableFileSet> fileSet = wait(bc->getRestoreSet(snapshotVersion, keyRangesFilter));
if (fileSet.present()) {
result["snapshot_version"] = fileSet.get().targetVersion;
result["restore_version"] = fileSet.get().targetVersion; // In case there isn't any more log files.
for (const auto& rangeFile : fileSet.get().ranges) {
JsonBuilderObject object;
object["file_name"] = rangeFile.fileName;
@ -2830,6 +2845,7 @@ ACTOR Future<Void> queryBackup(const char* name,
state Optional<RestorableFileSet> fileSet;
if (snapshotVersion == invalidVersion) {
// Using the latest snapshot.
wait(store(fileSet, bc->getRestoreSet(restoreVersion, keyRangesFilter)));
} else {
// We only need to know all the log files from snapshotVersion to restoreVersion.

View File

@ -914,6 +914,7 @@ public:
if (logsOnly) {
state RestorableFileSet restorableSet;
restorableSet.targetVersion = targetVersion;
state std::vector<LogFile> logFiles;
Version begin = beginVersion == invalidVersion ? 0 : beginVersion;
wait(store(logFiles, bc->listLogFiles(begin, targetVersion, false)));
@ -927,9 +928,6 @@ public:
// Find the most recent keyrange snapshot through which we can restore filtered key ranges into targetVersion.
state std::vector<KeyspaceSnapshotFile> snapshots = wait(bc->listKeyspaceSnapshots());
state int i = snapshots.size() - 1;
if (targetVersion == earliestVersion) {
i = 0;
}
for (; i >= 0; i--) {
// The smallest version of filtered range files >= snapshot beginVersion > targetVersion
if (targetVersion >= 0 && snapshots[i].beginVersion > targetVersion) {
@ -970,7 +968,7 @@ public:
}
}
// 'latestVersion' represents using the minimum restorable version in a snapshot.
restorable.targetVersion = targetVersion == earliestVersion ? maxKeyRangeVersion : targetVersion;
restorable.targetVersion = targetVersion == latestVersion ? maxKeyRangeVersion : targetVersion;
// Any version < maxKeyRangeVersion is not restorable.
if (restorable.targetVersion < maxKeyRangeVersion)
continue;

View File

@ -288,7 +288,7 @@ public:
Version end = std::numeric_limits<Version>::max()) = 0;
// Get exactly the files necessary to restore the key space filtered by the specified key ranges to targetVersion.
// If targetVersion is 'earliestVersion', use the minimum restorable version in a snapshot.
// If targetVersion is 'latestVersion', use the minimum restorable version in a snapshot.
// If logsOnly is set, only use log files in [beginVersion, targetVervions) in restore set.
// Returns non-present if restoring to the given version is not possible.
virtual Future<Optional<RestorableFileSet>> getRestoreSet(Version targetVersion,