Add an option for fast restore to restore old backups
If "usePartitionedLogs" is set to false, then the workload uses old backups for restore.
This commit is contained in:
parent
1052b23ee1
commit
772ab70aee
|
@ -657,6 +657,18 @@ public:
|
||||||
return dumpFileList_impl(Reference<BackupContainerFileSystem>::addRef(this), begin, end);
|
return dumpFileList_impl(Reference<BackupContainerFileSystem>::addRef(this), begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ACTOR static Future<bool> isPartitionedBackup_impl(Reference<BackupContainerFileSystem> bc) {
|
||||||
|
BackupFileList list = wait(bc->dumpFileList(0, std::numeric_limits<Version>::max()));
|
||||||
|
for (const auto& file : list.logs) {
|
||||||
|
if (file.isPartitionedLog()) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isPartitionedBackup() final {
|
||||||
|
return isPartitionedBackup_impl(Reference<BackupContainerFileSystem>::addRef(this));
|
||||||
|
}
|
||||||
|
|
||||||
static Version resolveRelativeVersion(Optional<Version> max, Version v, const char *name, Error e) {
|
static Version resolveRelativeVersion(Optional<Version> max, Version v, const char *name, Error e) {
|
||||||
if(v == invalidVersion) {
|
if(v == invalidVersion) {
|
||||||
TraceEvent(SevError, "BackupExpireInvalidVersion").detail(name, v);
|
TraceEvent(SevError, "BackupExpireInvalidVersion").detail(name, v);
|
||||||
|
|
|
@ -88,6 +88,10 @@ struct LogFile {
|
||||||
return beginVersion >= rhs.beginVersion && endVersion <= rhs.endVersion && tagId == rhs.tagId;
|
return beginVersion >= rhs.beginVersion && endVersion <= rhs.endVersion && tagId == rhs.tagId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isPartitionedLog() const {
|
||||||
|
return tagId >= 0 && tagId < totalTags;
|
||||||
|
}
|
||||||
|
|
||||||
std::string toString() const {
|
std::string toString() const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "beginVersion:" << std::to_string(beginVersion) << " endVersion:" << std::to_string(endVersion)
|
ss << "beginVersion:" << std::to_string(beginVersion) << " endVersion:" << std::to_string(endVersion)
|
||||||
|
@ -261,6 +265,9 @@ public:
|
||||||
|
|
||||||
virtual Future<BackupFileList> dumpFileList(Version begin = 0, Version end = std::numeric_limits<Version>::max()) = 0;
|
virtual Future<BackupFileList> dumpFileList(Version begin = 0, Version end = std::numeric_limits<Version>::max()) = 0;
|
||||||
|
|
||||||
|
// If there are partitioned log files, then returns true; otherwise, returns false.
|
||||||
|
virtual Future<bool> isPartitionedBackup() = 0;
|
||||||
|
|
||||||
// Get exactly the files necessary to restore to targetVersion. Returns non-present if
|
// Get exactly the files necessary to restore to targetVersion. Returns non-present if
|
||||||
// restore to given version is not possible.
|
// restore to given version is not possible.
|
||||||
virtual Future<Optional<RestorableFileSet>> getRestoreSet(Version targetVersion) = 0;
|
virtual Future<Optional<RestorableFileSet>> getRestoreSet(Version targetVersion) = 0;
|
||||||
|
|
|
@ -641,7 +641,8 @@ ACTOR static Future<Standalone<VectorRef<RestoreRequest>>> collectRestoreRequest
|
||||||
ACTOR static Future<Version> collectBackupFiles(Reference<IBackupContainer> bc, std::vector<RestoreFileFR>* rangeFiles,
|
ACTOR static Future<Version> collectBackupFiles(Reference<IBackupContainer> bc, std::vector<RestoreFileFR>* rangeFiles,
|
||||||
std::vector<RestoreFileFR>* logFiles, Database cx,
|
std::vector<RestoreFileFR>* logFiles, Database cx,
|
||||||
RestoreRequest request) {
|
RestoreRequest request) {
|
||||||
state BackupDescription desc = wait(bc->describePartitionedBackup());
|
state bool partitioned = wait(bc->isPartitionedBackup());
|
||||||
|
state BackupDescription desc = wait(partitioned ? bc->describePartitionedBackup() : bc->describeBackup());
|
||||||
|
|
||||||
// Convert version to real time for operators to read the BackupDescription desc.
|
// Convert version to real time for operators to read the BackupDescription desc.
|
||||||
wait(desc.resolveVersionTimes(cx));
|
wait(desc.resolveVersionTimes(cx));
|
||||||
|
@ -657,9 +658,8 @@ ACTOR static Future<Version> collectBackupFiles(Reference<IBackupContainer> bc,
|
||||||
std::cout << "Restore to version: " << request.targetVersion << "\nBackupDesc: \n" << desc.toString() << "\n\n";
|
std::cout << "Restore to version: " << request.targetVersion << "\nBackupDesc: \n" << desc.toString() << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<RestorableFileSet> restorable =
|
Optional<RestorableFileSet> restorable = wait(partitioned ? bc->getPartitionedRestoreSet(request.targetVersion)
|
||||||
wait(SERVER_KNOBS->FASTRESTORE_USE_PARTITIONED_LOGS ? bc->getPartitionedRestoreSet(request.targetVersion)
|
: bc->getRestoreSet(request.targetVersion));
|
||||||
: bc->getRestoreSet(request.targetVersion));
|
|
||||||
|
|
||||||
if (!restorable.present()) {
|
if (!restorable.present()) {
|
||||||
TraceEvent(SevWarn, "FastRestoreMasterPhaseCollectBackupFiles").detail("NotRestorable", request.targetVersion);
|
TraceEvent(SevWarn, "FastRestoreMasterPhaseCollectBackupFiles").detail("NotRestorable", request.targetVersion);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "fdbrpc/simulator.h"
|
#include "fdbrpc/simulator.h"
|
||||||
#include "fdbclient/BackupAgent.actor.h"
|
#include "fdbclient/BackupAgent.actor.h"
|
||||||
#include "fdbclient/BackupContainer.h"
|
#include "fdbclient/BackupContainer.h"
|
||||||
|
#include "fdbserver/Knobs.h"
|
||||||
#include "fdbserver/workloads/workloads.actor.h"
|
#include "fdbserver/workloads/workloads.actor.h"
|
||||||
#include "fdbserver/workloads/BulkSetup.actor.h"
|
#include "fdbserver/workloads/BulkSetup.actor.h"
|
||||||
#include "fdbclient/RestoreWorkerInterface.actor.h"
|
#include "fdbclient/RestoreWorkerInterface.actor.h"
|
||||||
|
@ -40,6 +41,7 @@ struct BackupAndParallelRestoreCorrectnessWorkload : TestWorkload {
|
||||||
bool locked;
|
bool locked;
|
||||||
bool allowPauses;
|
bool allowPauses;
|
||||||
bool shareLogRange;
|
bool shareLogRange;
|
||||||
|
bool usePartitionedLogs;
|
||||||
|
|
||||||
std::map<Standalone<KeyRef>, Standalone<ValueRef>> dbKVs;
|
std::map<Standalone<KeyRef>, Standalone<ValueRef>> dbKVs;
|
||||||
|
|
||||||
|
@ -67,6 +69,7 @@ struct BackupAndParallelRestoreCorrectnessWorkload : TestWorkload {
|
||||||
agentRequest = getOption(options, LiteralStringRef("simBackupAgents"), true);
|
agentRequest = getOption(options, LiteralStringRef("simBackupAgents"), true);
|
||||||
allowPauses = getOption(options, LiteralStringRef("allowPauses"), true);
|
allowPauses = getOption(options, LiteralStringRef("allowPauses"), true);
|
||||||
shareLogRange = getOption(options, LiteralStringRef("shareLogRange"), false);
|
shareLogRange = getOption(options, LiteralStringRef("shareLogRange"), false);
|
||||||
|
usePartitionedLogs = getOption(options, LiteralStringRef("usePartitionedLogs"), true);
|
||||||
|
|
||||||
KeyRef beginRange;
|
KeyRef beginRange;
|
||||||
KeyRef endRange;
|
KeyRef endRange;
|
||||||
|
@ -181,7 +184,7 @@ struct BackupAndParallelRestoreCorrectnessWorkload : TestWorkload {
|
||||||
try {
|
try {
|
||||||
wait(backupAgent->submitBackup(cx, StringRef(backupContainer), deterministicRandom()->randomInt(0, 100),
|
wait(backupAgent->submitBackup(cx, StringRef(backupContainer), deterministicRandom()->randomInt(0, 100),
|
||||||
tag.toString(), backupRanges, stopDifferentialDelay ? false : true,
|
tag.toString(), backupRanges, stopDifferentialDelay ? false : true,
|
||||||
/*partitionedLog=*/true));
|
/*partitionedLog=*/self->usePartitionedLogs));
|
||||||
} catch (Error& e) {
|
} catch (Error& e) {
|
||||||
TraceEvent("BARW_DoBackupSubmitBackupException", randomID).error(e).detail("Tag", printable(tag));
|
TraceEvent("BARW_DoBackupSubmitBackupException", randomID).error(e).detail("Tag", printable(tag));
|
||||||
if (e.code() != error_code_backup_unneeded && e.code() != error_code_backup_duplicate) throw;
|
if (e.code() != error_code_backup_unneeded && e.code() != error_code_backup_duplicate) throw;
|
||||||
|
@ -209,8 +212,10 @@ struct BackupAndParallelRestoreCorrectnessWorkload : TestWorkload {
|
||||||
TraceEvent("BARW_DoBackupWaitForRestorable", randomID).detail("Tag", backupTag.tagName).detail("Result", resultWait);
|
TraceEvent("BARW_DoBackupWaitForRestorable", randomID).detail("Tag", backupTag.tagName).detail("Result", resultWait);
|
||||||
|
|
||||||
state bool restorable = false;
|
state bool restorable = false;
|
||||||
if(lastBackupContainer) {
|
if (lastBackupContainer) {
|
||||||
state Future<BackupDescription> fdesc = lastBackupContainer->describePartitionedBackup();
|
state Future<BackupDescription> fdesc = self->usePartitionedLogs
|
||||||
|
? lastBackupContainer->describePartitionedBackup()
|
||||||
|
: lastBackupContainer->describeBackup();
|
||||||
wait(ready(fdesc));
|
wait(ready(fdesc));
|
||||||
|
|
||||||
if(!fdesc.isError()) {
|
if(!fdesc.isError()) {
|
||||||
|
@ -398,7 +403,7 @@ struct BackupAndParallelRestoreCorrectnessWorkload : TestWorkload {
|
||||||
try {
|
try {
|
||||||
extraBackup = backupAgent.submitBackup(
|
extraBackup = backupAgent.submitBackup(
|
||||||
cx, LiteralStringRef("file://simfdb/backups/"), deterministicRandom()->randomInt(0, 100),
|
cx, LiteralStringRef("file://simfdb/backups/"), deterministicRandom()->randomInt(0, 100),
|
||||||
self->backupTag.toString(), self->backupRanges, true, /*partitionedLog=*/true);
|
self->backupTag.toString(), self->backupRanges, true, self->usePartitionedLogs);
|
||||||
} catch (Error& e) {
|
} catch (Error& e) {
|
||||||
TraceEvent("BARW_SubmitBackup2Exception", randomID)
|
TraceEvent("BARW_SubmitBackup2Exception", randomID)
|
||||||
.error(e)
|
.error(e)
|
||||||
|
@ -431,7 +436,8 @@ struct BackupAndParallelRestoreCorrectnessWorkload : TestWorkload {
|
||||||
.detail("BackupTag", printable(self->backupTag));
|
.detail("BackupTag", printable(self->backupTag));
|
||||||
|
|
||||||
auto container = IBackupContainer::openContainer(lastBackupContainer->getURL());
|
auto container = IBackupContainer::openContainer(lastBackupContainer->getURL());
|
||||||
BackupDescription desc = wait(container->describePartitionedBackup());
|
BackupDescription desc = wait(self->usePartitionedLogs ? container->describePartitionedBackup()
|
||||||
|
: container->describeBackup());
|
||||||
|
|
||||||
state Version targetVersion = -1;
|
state Version targetVersion = -1;
|
||||||
if (desc.maxRestorableVersion.present()) {
|
if (desc.maxRestorableVersion.present()) {
|
||||||
|
|
Loading…
Reference in New Issue