Merge pull request #1240 from satherton/feature-restore-by-timestamp
Restore by timestamp
This commit is contained in:
commit
f3391ea413
|
@ -376,12 +376,14 @@ The following options apply to all commands:
|
|||
|
||||
.. warning:: If multiple restore tasks are in progress they should be restoring to different prefixes or the result is undefined.
|
||||
|
||||
``-C <CLUSTER_FILE>``
|
||||
Path to the cluster file that should be used to connect to the FoundationDB cluster you want to use. If not specified, a :ref:`default cluster file <default-cluster-file>` will be used.
|
||||
|
||||
``--blob_credentials <FILE>``
|
||||
Use FILE as a :ref:`Blob Credential File<blob-credential-files>`. Can be used multiple times.
|
||||
|
||||
The following options apply to all commands except ``start``:
|
||||
|
||||
``-C <CLUSTER_FILE>``
|
||||
Path to the cluster file that should be used to connect to the FoundationDB cluster you want to use. If not specified, a :ref:`default cluster file <default-cluster-file>` will be used.
|
||||
|
||||
.. _restore-start:
|
||||
|
||||
``start``
|
||||
|
@ -395,6 +397,10 @@ The ``start`` command will start a new restore on the specified (or default) tag
|
|||
``-r <BACKUP_URL>``
|
||||
Required. Specifies the Backup URL for the source backup data to restore to the database. The source data must be accessible by the ``backup_agent`` processes for the cluster.
|
||||
|
||||
``--dest_cluster_file <CONNFILE>``
|
||||
Required. The backup data will be restored into this cluster.
|
||||
|
||||
|
||||
``-w``
|
||||
Wait for the restore to reach a final state (such as complete) before exiting. Prints a progress update every few seconds. Behavior is identical to that of the wait command.
|
||||
|
||||
|
@ -413,6 +419,12 @@ The ``start`` command will start a new restore on the specified (or default) tag
|
|||
``-v <VERSION>``
|
||||
Instead of the latest version the backup can be restored to, restore to VERSION.
|
||||
|
||||
``--timestamp <YYYY-MM-DD.HH:MI:SS>``
|
||||
Instead of the latest version the backup can be restored to, restore to a version from approximately the given timestamp. Requires orig_cluster_file to be specified.
|
||||
|
||||
``--orig_cluster_file <CONNFILE>``
|
||||
The cluster file for the original database from which the backup was created. The original database is only needed to convert a --timestamp argument to a database version.
|
||||
|
||||
.. program:: fdbrestore abort
|
||||
|
||||
``abort``
|
||||
|
|
|
@ -14,6 +14,8 @@ Improved replication mechanism, a new hierarchical replication technique that fu
|
|||
* Added configuration option to choose log spilling implementation `(PR #1160) <https://github.com/apple/foundationdb/pull/1160>`_
|
||||
* Added configuration option to choose log system implementation `(PR #1160) <https://github.com/apple/foundationdb/pull/1160>`_
|
||||
* Batch priority transactions are now limited separately by ratekeeper and will be throttled at lower levels of cluster saturation. This makes it possible to run a more intense background load at saturation without significantly affecting normal priority transactions. It is still recommended not to run excessive loads at batch priority. `(PR #1198) <https://github.com/apple/foundationdb/pull/1198>`_
|
||||
* Restore now requires the destnation cluster to be specified explicitly to avoid confusion. `(PR #1240) <https://github.com/apple/foundationdb/pull/1240>`_
|
||||
* Restore target version can now be specified by timestamp if the original cluster is available. `(PR #1240) <https://github.com/apple/foundationdb/pull/1240>`_
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
|
|
@ -100,7 +100,7 @@ enum {
|
|||
OPT_TAGNAME, OPT_BACKUPKEYS, OPT_WAITFORDONE,
|
||||
|
||||
// Restore constants
|
||||
OPT_RESTORECONTAINER, OPT_DBVERSION, OPT_PREFIX_ADD, OPT_PREFIX_REMOVE,
|
||||
OPT_RESTORECONTAINER, OPT_RESTORE_VERSION, OPT_RESTORE_TIMESTAMP, OPT_PREFIX_ADD, OPT_PREFIX_REMOVE, OPT_RESTORE_CLUSTERFILE_DEST, OPT_RESTORE_CLUSTERFILE_ORIG,
|
||||
|
||||
// Shared constants
|
||||
OPT_CLUSTERFILE, OPT_QUIET, OPT_DRYRUN, OPT_FORCE,
|
||||
|
@ -504,7 +504,9 @@ CSimpleOpt::SOption g_rgRestoreOptions[] = {
|
|||
#ifdef _WIN32
|
||||
{ OPT_PARENTPID, "--parentpid", SO_REQ_SEP },
|
||||
#endif
|
||||
{ OPT_CLUSTERFILE, "-C", SO_REQ_SEP },
|
||||
{ OPT_RESTORE_CLUSTERFILE_DEST, "--dest_cluster_file", SO_REQ_SEP },
|
||||
{ OPT_RESTORE_CLUSTERFILE_ORIG, "--orig_cluster_file", SO_REQ_SEP },
|
||||
{ OPT_RESTORE_TIMESTAMP, "--timestamp", SO_REQ_SEP },
|
||||
{ OPT_KNOB, "--knob_", SO_REQ_SEP },
|
||||
{ OPT_RESTORECONTAINER,"-r", SO_REQ_SEP },
|
||||
{ OPT_PREFIX_ADD, "-add_prefix", SO_REQ_SEP },
|
||||
|
@ -513,11 +515,10 @@ CSimpleOpt::SOption g_rgRestoreOptions[] = {
|
|||
{ OPT_TAGNAME, "--tagname", SO_REQ_SEP },
|
||||
{ OPT_BACKUPKEYS, "-k", SO_REQ_SEP },
|
||||
{ OPT_BACKUPKEYS, "--keys", SO_REQ_SEP },
|
||||
{ OPT_WAITFORDONE, "-w", SO_NONE },
|
||||
{ OPT_WAITFORDONE, "--waitfordone", SO_NONE },
|
||||
{ OPT_CLUSTERFILE, "--cluster_file", SO_REQ_SEP },
|
||||
{ OPT_DBVERSION, "--version", SO_REQ_SEP },
|
||||
{ OPT_DBVERSION, "-v", SO_REQ_SEP },
|
||||
{ OPT_WAITFORDONE, "-w", SO_NONE },
|
||||
{ OPT_WAITFORDONE, "--waitfordone", SO_NONE },
|
||||
{ OPT_RESTORE_VERSION, "--version", SO_REQ_SEP },
|
||||
{ OPT_RESTORE_VERSION, "-v", SO_REQ_SEP },
|
||||
{ OPT_TRACE, "--log", SO_NONE },
|
||||
{ OPT_TRACE_DIR, "--logdir", SO_REQ_SEP },
|
||||
{ OPT_TRACE_FORMAT, "--trace_format", SO_REQ_SEP },
|
||||
|
@ -891,25 +892,30 @@ static void printRestoreUsage(bool devhelp ) {
|
|||
printf("Usage: %s (start | status | abort | wait) [OPTIONS]\n\n", exeRestore.toString().c_str());
|
||||
//printf(" FOLDERS Paths to folders containing the backup files.\n");
|
||||
printf("Options for all commands:\n\n");
|
||||
printf(" -C CONNFILE The path of a file containing the connection string for the\n"
|
||||
" FoundationDB cluster. The default is first the value of the\n"
|
||||
" FDB_CLUSTER_FILE environment variable, then `./fdb.cluster',\n"
|
||||
" then `%s'.\n", platform::getDefaultClusterFilePath().c_str());
|
||||
printf(" -t TAGNAME The restore tag to act on. Default is 'default'\n");
|
||||
printf(" --tagname TAGNAME\n\n");
|
||||
printf(" Options for start:\n\n");
|
||||
printf(" --dest_cluster_file CONNFILE\n");
|
||||
printf(" The cluster file to restore data into.\n");
|
||||
printf(" -t, --tagname TAGNAME\n");
|
||||
printf(" The restore tag to act on. Default is 'default'\n");
|
||||
printf("Options for start:\n\n");
|
||||
printf(" -r URL The Backup URL for the restore to read from.\n");
|
||||
printBackupContainerInfo();
|
||||
printf(" -w Wait for the restore to complete before exiting. Prints progress updates.\n");
|
||||
printf(" --waitfordone\n");
|
||||
printf(" -k KEYS List of key ranges from the backup to restore\n");
|
||||
printf(" --remove_prefix PREFIX prefix to remove from the restored keys\n");
|
||||
printf(" --add_prefix PREFIX prefix to add to the restored keys\n");
|
||||
printf(" -n, --dryrun Perform a trial run with no changes made.\n");
|
||||
printf(" -w, --waitfordone\n");
|
||||
printf(" Wait for the restore to complete before exiting. Prints progress updates.\n");
|
||||
printf(" -k KEYS List of key ranges from the backup to restore.\n");
|
||||
printf(" --remove_prefix PREFIX\n");
|
||||
printf(" Prefix to remove from the restored keys.\n");
|
||||
printf(" --add_prefix PREFIX\n");
|
||||
printf(" Prefix to add to the restored keys\n");
|
||||
printf(" -n, --dryrun Perform a trial run with no changes made.\n");
|
||||
#ifndef TLS_DISABLED
|
||||
printf(TLS_HELP);
|
||||
#endif
|
||||
printf(" -v DBVERSION The version at which the database will be restored.\n");
|
||||
printf(" --timestamp Instead of a numeric version, use this to specify a timestamp in YYYY-MM-DD.HH:MI:SS format (UTC)\n");
|
||||
printf(" and it will be converted to a version from that time using metadata in orig_cluster_file.\n");
|
||||
printf(" --orig_cluster_file CONNFILE\n");
|
||||
printf(" The cluster file for the original database from which the backup was created. The original database\n");
|
||||
printf(" is only needed to convert a --timestamp argument to a database version.\n");
|
||||
printf(" -h, --help Display this help and exit.\n");
|
||||
|
||||
if( devhelp ) {
|
||||
|
@ -1868,9 +1874,73 @@ ACTOR Future<Void> changeDBBackupResumed(Database src, Database dest, bool pause
|
|||
return Void();
|
||||
}
|
||||
|
||||
ACTOR Future<Void> runRestore(Database db, std::string tagName, std::string container, Standalone<VectorRef<KeyRangeRef>> ranges, Version targetVersion, bool performRestore, bool verbose, bool waitForDone, std::string addPrefix, std::string removePrefix) {
|
||||
try
|
||||
{
|
||||
Reference<IBackupContainer> openBackupContainer(const char *name, std::string destinationContainer) {
|
||||
// Error, if no dest container was specified
|
||||
if (destinationContainer.empty()) {
|
||||
fprintf(stderr, "ERROR: No backup destination was specified.\n");
|
||||
printHelpTeaser(name);
|
||||
throw backup_error();
|
||||
}
|
||||
|
||||
Reference<IBackupContainer> c;
|
||||
try {
|
||||
c = IBackupContainer::openContainer(destinationContainer);
|
||||
}
|
||||
catch (Error& e) {
|
||||
std::string msg = format("ERROR: '%s' on URL '%s'", e.what(), destinationContainer.c_str());
|
||||
if(e.code() == error_code_backup_invalid_url && !IBackupContainer::lastOpenError.empty()) {
|
||||
msg += format(": %s", IBackupContainer::lastOpenError.c_str());
|
||||
}
|
||||
fprintf(stderr, "%s\n", msg.c_str());
|
||||
printHelpTeaser(name);
|
||||
throw;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ACTOR Future<Void> runRestore(std::string destClusterFile, std::string originalClusterFile, std::string tagName, std::string container, Standalone<VectorRef<KeyRangeRef>> ranges, Version targetVersion, std::string targetTimestamp, bool performRestore, bool verbose, bool waitForDone, std::string addPrefix, std::string removePrefix) {
|
||||
if(ranges.empty()) {
|
||||
ranges.push_back_deep(ranges.arena(), normalKeys);
|
||||
}
|
||||
|
||||
if(targetVersion != invalidVersion && !targetTimestamp.empty()) {
|
||||
fprintf(stderr, "Restore target version and target timestamp cannot both be specified\n");
|
||||
throw restore_error();
|
||||
}
|
||||
|
||||
if(destClusterFile.empty()) {
|
||||
fprintf(stderr, "Restore destination cluster file must be specified explicitly.\n");
|
||||
throw restore_error();
|
||||
}
|
||||
|
||||
if(!fileExists(destClusterFile)) {
|
||||
fprintf(stderr, "Restore destination cluster file '%s' does not exist.\n", destClusterFile.c_str());
|
||||
throw restore_error();
|
||||
}
|
||||
|
||||
state Optional<Database> origDb;
|
||||
|
||||
// Resolve targetTimestamp if given
|
||||
if(!targetTimestamp.empty()) {
|
||||
if(originalClusterFile.empty()) {
|
||||
fprintf(stderr, "An original cluster file must be given in order to resolve restore target timestamp '%s'\n", targetTimestamp.c_str());
|
||||
throw restore_error();
|
||||
}
|
||||
|
||||
if(!fileExists(originalClusterFile)) {
|
||||
fprintf(stderr, "Original source database cluster file '%s' does not exist.\n", originalClusterFile.c_str());
|
||||
throw restore_error();
|
||||
}
|
||||
|
||||
origDb = Database::createDatabase(originalClusterFile, Database::API_VERSION_LATEST);
|
||||
Version v = wait(timeKeeperVersionFromDatetime(targetTimestamp, origDb.get()));
|
||||
printf("Timestamp '%s' resolves to version %lld\n", targetTimestamp.c_str(), v);
|
||||
targetVersion = v;
|
||||
}
|
||||
|
||||
try {
|
||||
state Database db = Database::createDatabase(destClusterFile, Database::API_VERSION_LATEST);
|
||||
state FileBackupAgent backupAgent;
|
||||
|
||||
state Reference<IBackupContainer> bc = IBackupContainer::openContainer(container);
|
||||
|
@ -1894,7 +1964,7 @@ ACTOR Future<Void> runRestore(Database db, std::string tagName, std::string cont
|
|||
}
|
||||
|
||||
if (performRestore) {
|
||||
Version restoredVersion = wait(backupAgent.restore(db, KeyRef(tagName), KeyRef(container), ranges, waitForDone, targetVersion, verbose, KeyRef(addPrefix), KeyRef(removePrefix)));
|
||||
Version restoredVersion = wait(backupAgent.restore(db, origDb, KeyRef(tagName), KeyRef(container), ranges, waitForDone, targetVersion, verbose, KeyRef(addPrefix), KeyRef(removePrefix)));
|
||||
|
||||
if(waitForDone && verbose) {
|
||||
// If restore is now complete then report version restored
|
||||
|
@ -1923,30 +1993,6 @@ ACTOR Future<Void> runRestore(Database db, std::string tagName, std::string cont
|
|||
return Void();
|
||||
}
|
||||
|
||||
Reference<IBackupContainer> openBackupContainer(const char *name, std::string destinationContainer) {
|
||||
// Error, if no dest container was specified
|
||||
if (destinationContainer.empty()) {
|
||||
fprintf(stderr, "ERROR: No backup destination was specified.\n");
|
||||
printHelpTeaser(name);
|
||||
throw backup_error();
|
||||
}
|
||||
|
||||
std::string error;
|
||||
Reference<IBackupContainer> c;
|
||||
try {
|
||||
c = IBackupContainer::openContainer(destinationContainer);
|
||||
}
|
||||
catch (Error& e) {
|
||||
if(!error.empty())
|
||||
error = std::string("[") + error + "]";
|
||||
fprintf(stderr, "ERROR (%s) on %s %s\n", e.what(), destinationContainer.c_str(), error.c_str());
|
||||
printHelpTeaser(name);
|
||||
throw;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ACTOR Future<Void> dumpBackupData(const char *name, std::string destinationContainer, Version beginVersion, Version endVersion) {
|
||||
state Reference<IBackupContainer> c = openBackupContainer(name, destinationContainer);
|
||||
|
||||
|
@ -2478,7 +2524,8 @@ int main(int argc, char* argv[]) {
|
|||
std::string removePrefix;
|
||||
Standalone<VectorRef<KeyRangeRef>> backupKeys;
|
||||
int maxErrors = 20;
|
||||
Version dbVersion = invalidVersion;
|
||||
Version restoreVersion = invalidVersion;
|
||||
std::string restoreTimestamp;
|
||||
bool waitForDone = false;
|
||||
bool stopWhenDone = true;
|
||||
bool forceAction = false;
|
||||
|
@ -2498,6 +2545,8 @@ int main(int argc, char* argv[]) {
|
|||
std::string tlsCertPath, tlsKeyPath, tlsCAPath, tlsPassword, tlsVerifyPeers;
|
||||
Version dumpBegin = 0;
|
||||
Version dumpEnd = std::numeric_limits<Version>::max();
|
||||
std::string restoreClusterFileDest;
|
||||
std::string restoreClusterFileOrig;
|
||||
|
||||
if( argc == 1 ) {
|
||||
printUsage(programExe, false);
|
||||
|
@ -2634,9 +2683,18 @@ int main(int argc, char* argv[]) {
|
|||
expireRestorableAfterVersion = ver;
|
||||
break;
|
||||
}
|
||||
case OPT_RESTORE_TIMESTAMP:
|
||||
restoreTimestamp = args->OptionArg();
|
||||
break;
|
||||
case OPT_BASEURL:
|
||||
baseUrl = args->OptionArg();
|
||||
break;
|
||||
case OPT_RESTORE_CLUSTERFILE_DEST:
|
||||
restoreClusterFileDest = args->OptionArg();
|
||||
break;
|
||||
case OPT_RESTORE_CLUSTERFILE_ORIG:
|
||||
restoreClusterFileOrig = args->OptionArg();
|
||||
break;
|
||||
case OPT_CLUSTERFILE:
|
||||
clusterFile = args->OptionArg();
|
||||
break;
|
||||
|
@ -2716,15 +2774,15 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case OPT_DBVERSION: {
|
||||
case OPT_RESTORE_VERSION: {
|
||||
const char* a = args->OptionArg();
|
||||
long long dbVersionValue = 0;
|
||||
if (!sscanf(a, "%lld", &dbVersionValue)) {
|
||||
long long ver = 0;
|
||||
if (!sscanf(a, "%lld", &ver)) {
|
||||
fprintf(stderr, "ERROR: Could not parse database version `%s'\n", a);
|
||||
printHelpTeaser(argv[0]);
|
||||
return FDB_EXIT_ERROR;
|
||||
}
|
||||
dbVersion = dbVersionValue;
|
||||
restoreVersion = ver;
|
||||
break;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
|
@ -3168,13 +3226,13 @@ int main(int argc, char* argv[]) {
|
|||
if(dryRun) {
|
||||
initTraceFile();
|
||||
}
|
||||
else if(!initCluster()) {
|
||||
else if(restoreType != RESTORE_START && !initCluster()) {
|
||||
return FDB_EXIT_ERROR;
|
||||
}
|
||||
|
||||
switch(restoreType) {
|
||||
case RESTORE_START:
|
||||
f = stopAfter( runRestore(db, tagName, restoreContainer, backupKeys, dbVersion, !dryRun, !quietDisplay, waitForDone, addPrefix, removePrefix) );
|
||||
f = stopAfter( runRestore(restoreClusterFileDest, restoreClusterFileOrig, tagName, restoreContainer, backupKeys, restoreVersion, restoreTimestamp, !dryRun, !quietDisplay, waitForDone, addPrefix, removePrefix) );
|
||||
break;
|
||||
case RESTORE_WAIT:
|
||||
f = stopAfter( success(ba.waitRestore(db, KeyRef(tagName), true)) );
|
||||
|
@ -3186,7 +3244,6 @@ int main(int argc, char* argv[]) {
|
|||
}) );
|
||||
break;
|
||||
case RESTORE_STATUS:
|
||||
|
||||
// If no tag is specifically provided then print all tag status, don't just use "default"
|
||||
if(tagProvided)
|
||||
tag = tagName;
|
||||
|
|
|
@ -233,11 +233,11 @@ public:
|
|||
// - submit a restore on the given tagName
|
||||
// - Optionally wait for the restore's completion. Will restore_error if restore fails or is aborted.
|
||||
// restore() will return the targetVersion which will be either the valid version passed in or the max restorable version for the given url.
|
||||
Future<Version> restore(Database cx, Key tagName, Key url, Standalone<VectorRef<KeyRangeRef>> ranges, bool waitForComplete = true, Version targetVersion = -1, bool verbose = true, Key addPrefix = Key(), Key removePrefix = Key(), bool lockDB = true);
|
||||
Future<Version> restore(Database cx, Key tagName, Key url, bool waitForComplete = true, Version targetVersion = -1, bool verbose = true, KeyRange range = normalKeys, Key addPrefix = Key(), Key removePrefix = Key(), bool lockDB = true) {
|
||||
Future<Version> restore(Database cx, Optional<Database> cxOrig, Key tagName, Key url, Standalone<VectorRef<KeyRangeRef>> ranges, bool waitForComplete = true, Version targetVersion = -1, bool verbose = true, Key addPrefix = Key(), Key removePrefix = Key(), bool lockDB = true);
|
||||
Future<Version> restore(Database cx, Optional<Database> cxOrig, Key tagName, Key url, bool waitForComplete = true, Version targetVersion = -1, bool verbose = true, KeyRange range = normalKeys, Key addPrefix = Key(), Key removePrefix = Key(), bool lockDB = true) {
|
||||
Standalone<VectorRef<KeyRangeRef>> rangeRef;
|
||||
rangeRef.push_back_deep(rangeRef.arena(), range);
|
||||
return restore(cx, tagName, url, rangeRef, waitForComplete, targetVersion, verbose, addPrefix, removePrefix, lockDB);
|
||||
return restore(cx, cxOrig, tagName, url, rangeRef, waitForComplete, targetVersion, verbose, addPrefix, removePrefix, lockDB);
|
||||
}
|
||||
Future<Version> atomicRestore(Database cx, Key tagName, Standalone<VectorRef<KeyRangeRef>> ranges, Key addPrefix = Key(), Key removePrefix = Key());
|
||||
Future<Version> atomicRestore(Database cx, Key tagName, KeyRange range = normalKeys, Key addPrefix = Key(), Key removePrefix = Key()) {
|
||||
|
|
|
@ -3983,10 +3983,13 @@ public:
|
|||
return r;
|
||||
}
|
||||
|
||||
ACTOR static Future<Version> restore(FileBackupAgent* backupAgent, Database cx, Key tagName, Key url, Standalone<VectorRef<KeyRangeRef>> ranges, bool waitForComplete, Version targetVersion, bool verbose, Key addPrefix, Key removePrefix, bool lockDB, UID randomUid) {
|
||||
ACTOR static Future<Version> restore(FileBackupAgent* backupAgent, Database cx, Optional<Database> cxOrig, Key tagName, Key url, Standalone<VectorRef<KeyRangeRef>> ranges, bool waitForComplete, Version targetVersion, bool verbose, Key addPrefix, Key removePrefix, bool lockDB, UID randomUid) {
|
||||
state Reference<IBackupContainer> bc = IBackupContainer::openContainer(url.toString());
|
||||
|
||||
state BackupDescription desc = wait(bc->describeBackup());
|
||||
wait(desc.resolveVersionTimes(cx));
|
||||
if(cxOrig.present()) {
|
||||
wait(desc.resolveVersionTimes(cxOrig.get()));
|
||||
}
|
||||
|
||||
printf("Backup Description\n%s", desc.toString().c_str());
|
||||
if(targetVersion == invalidVersion && desc.maxRestorableVersion.present())
|
||||
|
@ -4127,7 +4130,7 @@ public:
|
|||
Reference<IBackupContainer> bc = wait(backupConfig.backupContainer().getOrThrow(cx));
|
||||
|
||||
TraceEvent("AS_StartRestore");
|
||||
Version ver = wait( restore(backupAgent, cx, tagName, KeyRef(bc->getURL()), ranges, true, -1, true, addPrefix, removePrefix, true, randomUid) );
|
||||
Version ver = wait( restore(backupAgent, cx, cx, tagName, KeyRef(bc->getURL()), ranges, true, -1, true, addPrefix, removePrefix, true, randomUid) );
|
||||
return ver;
|
||||
}
|
||||
};
|
||||
|
@ -4136,8 +4139,8 @@ const std::string BackupAgentBase::defaultTagName = "default";
|
|||
const int BackupAgentBase::logHeaderSize = 12;
|
||||
const int FileBackupAgent::dataFooterSize = 20;
|
||||
|
||||
Future<Version> FileBackupAgent::restore(Database cx, Key tagName, Key url, Standalone<VectorRef<KeyRangeRef>> ranges, bool waitForComplete, Version targetVersion, bool verbose, Key addPrefix, Key removePrefix, bool lockDB) {
|
||||
return FileBackupAgentImpl::restore(this, cx, tagName, url, ranges, waitForComplete, targetVersion, verbose, addPrefix, removePrefix, lockDB, g_random->randomUniqueID());
|
||||
Future<Version> FileBackupAgent::restore(Database cx, Optional<Database> cxOrig, Key tagName, Key url, Standalone<VectorRef<KeyRangeRef>> ranges, bool waitForComplete, Version targetVersion, bool verbose, Key addPrefix, Key removePrefix, bool lockDB) {
|
||||
return FileBackupAgentImpl::restore(this, cx, cxOrig, tagName, url, ranges, waitForComplete, targetVersion, verbose, addPrefix, removePrefix, lockDB, g_random->randomUniqueID());
|
||||
}
|
||||
|
||||
Future<Version> FileBackupAgent::atomicRestore(Database cx, Key tagName, Standalone<VectorRef<KeyRangeRef>> ranges, Key addPrefix, Key removePrefix) {
|
||||
|
|
|
@ -344,7 +344,7 @@ struct BackupAndRestoreCorrectnessWorkload : TestWorkload {
|
|||
// Try doing a restore without clearing the keys
|
||||
if (rowCount > 0) {
|
||||
try {
|
||||
wait(success(backupAgent->restore(cx, self->backupTag, KeyRef(lastBackupContainer), true, -1, true, normalKeys, Key(), Key(), self->locked)));
|
||||
wait(success(backupAgent->restore(cx, cx, self->backupTag, KeyRef(lastBackupContainer), true, -1, true, normalKeys, Key(), Key(), self->locked)));
|
||||
TraceEvent(SevError, "BARW_RestoreAllowedOverwrittingDatabase", randomID);
|
||||
ASSERT(false);
|
||||
}
|
||||
|
@ -464,14 +464,14 @@ struct BackupAndRestoreCorrectnessWorkload : TestWorkload {
|
|||
auto range = self->restoreRanges[restoreIndex];
|
||||
Standalone<StringRef> restoreTag(self->backupTag.toString() + "_" + std::to_string(restoreIndex));
|
||||
restoreTags.push_back(restoreTag);
|
||||
restores.push_back(backupAgent.restore(cx, restoreTag, KeyRef(lastBackupContainer->getURL()), true, targetVersion, true, range, Key(), Key(), self->locked));
|
||||
restores.push_back(backupAgent.restore(cx, cx, restoreTag, KeyRef(lastBackupContainer->getURL()), true, targetVersion, true, range, Key(), Key(), self->locked));
|
||||
}
|
||||
}
|
||||
else {
|
||||
multipleRangesInOneTag = true;
|
||||
Standalone<StringRef> restoreTag(self->backupTag.toString() + "_" + std::to_string(restoreIndex));
|
||||
restoreTags.push_back(restoreTag);
|
||||
restores.push_back(backupAgent.restore(cx, restoreTag, KeyRef(lastBackupContainer->getURL()), self->restoreRanges, true, targetVersion, true, Key(), Key(), self->locked));
|
||||
restores.push_back(backupAgent.restore(cx, cx, restoreTag, KeyRef(lastBackupContainer->getURL()), self->restoreRanges, true, targetVersion, true, Key(), Key(), self->locked));
|
||||
}
|
||||
|
||||
// Sometimes kill and restart the restore
|
||||
|
@ -487,7 +487,7 @@ struct BackupAndRestoreCorrectnessWorkload : TestWorkload {
|
|||
tr->clear(range);
|
||||
return Void();
|
||||
}));
|
||||
restores[restoreIndex] = backupAgent.restore(cx, restoreTags[restoreIndex], KeyRef(lastBackupContainer->getURL()), self->restoreRanges, true, -1, true, Key(), Key(), self->locked);
|
||||
restores[restoreIndex] = backupAgent.restore(cx, cx, restoreTags[restoreIndex], KeyRef(lastBackupContainer->getURL()), self->restoreRanges, true, -1, true, Key(), Key(), self->locked);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -500,7 +500,7 @@ struct BackupAndRestoreCorrectnessWorkload : TestWorkload {
|
|||
tr->clear(self->restoreRanges[restoreIndex]);
|
||||
return Void();
|
||||
}));
|
||||
restores[restoreIndex] = backupAgent.restore(cx, restoreTags[restoreIndex], KeyRef(lastBackupContainer->getURL()), true, -1, true, self->restoreRanges[restoreIndex], Key(), Key(), self->locked);
|
||||
restores[restoreIndex] = backupAgent.restore(cx, cx, restoreTags[restoreIndex], KeyRef(lastBackupContainer->getURL()), true, -1, true, self->restoreRanges[restoreIndex], Key(), Key(), self->locked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue