diff --git a/arangod/GeneralServer/VstCommTask.cpp b/arangod/GeneralServer/VstCommTask.cpp index 7de408f5c4..8f027c85f5 100644 --- a/arangod/GeneralServer/VstCommTask.cpp +++ b/arangod/GeneralServer/VstCommTask.cpp @@ -379,7 +379,9 @@ void VstCommTask::doWrite() { } else { thisPtr->doWrite(); // write next one } - rsp->stat->release(); + if (rsp->stat != nullptr) { + rsp->stat->release(); + } }); break; // done } diff --git a/arangosh/Backup/BackupFeature.cpp b/arangosh/Backup/BackupFeature.cpp index a13478c6cf..45355de93c 100644 --- a/arangosh/Backup/BackupFeature.cpp +++ b/arangosh/Backup/BackupFeature.cpp @@ -277,10 +277,13 @@ arangodb::Result executeCreate(arangodb::httpclient::SimpleHttpClient& client, { VPackObjectBuilder guard(&bodyBuilder); bodyBuilder.add("timeout", VPackValue(options.maxWaitForLock)); - bodyBuilder.add("allowInconsistent", VPackValue(options.force)); + bodyBuilder.add("allowInconsistent", VPackValue(options.allowInconsistent)); if (!options.label.empty()) { bodyBuilder.add("label", VPackValue(options.label)); } + if (options.abortTransactionsIfNeeded) { + bodyBuilder.add("force", VPackValue(true)); + } } std::string const body = bodyBuilder.slice().toJson(); std::unique_ptr response( @@ -361,8 +364,7 @@ arangodb::Result executeRestore(arangodb::httpclient::SimpleHttpClient& client, { VPackObjectBuilder guard(&bodyBuilder); bodyBuilder.add("id", VPackValue(options.identifier)); - bodyBuilder.add("saveCurrent", VPackValue(options.saveCurrent)); - if (options.force) { + if (options.ignoreVersion) { bodyBuilder.add("ignoreVersion", VPackValue(true)); } } @@ -383,33 +385,6 @@ arangodb::Result executeRestore(arangodb::httpclient::SimpleHttpClient& client, return result; } - if (options.saveCurrent) { - VPackSlice const resBody = parsedBody->slice(); - if (!resBody.isObject()) { - result.reset(TRI_ERROR_INTERNAL, "expected response to be an object"); - return result; - } - TRI_ASSERT(resBody.isObject()); - - VPackSlice const resultObject = resBody.get("result"); - if (!resultObject.isObject()) { - result.reset(TRI_ERROR_INTERNAL, "expected 'result' to be an object"); - return result; - } - TRI_ASSERT(resultObject.isObject()); - - VPackSlice const previous = resultObject.get("previous"); - if (!previous.isString()) { - result.reset(TRI_ERROR_INTERNAL, "expected previous to be a string"); - return result; - } - TRI_ASSERT(previous.isString()); - - LOG_TOPIC("08c95", INFO, arangodb::Logger::BACKUP) - << "current state was saved as backup with identifier '" - << previous.copyString() << "'"; - } - LOG_TOPIC("b6d4c", INFO, arangodb::Logger::BACKUP) << "Successfully restored '" << options.identifier << "'"; @@ -706,7 +681,12 @@ void BackupFeature::collectOptions(std::shared_ptr opti options->addOption("--allow-inconsistent", "whether to attempt to continue in face of errors; " "may result in inconsistent backup state (create operation)", - new BooleanParameter(&_options.force)); + new BooleanParameter(&_options.allowInconsistent)); + + options->addOption("--ignore-version", + "ignore stored version of a backup" + "restore may not work if version mismatch (restore operation)", + new BooleanParameter(&_options.ignoreVersion)); options->addOption("--identifier", "a unique identifier for a backup " @@ -734,10 +714,6 @@ void BackupFeature::collectOptions(std::shared_ptr opti "result of the restore request (restore operation)", new DoubleParameter(&_options.maxWaitForRestart)); - options->addOption("--save-current", - "whether to save the current state as a backup before " - "restoring to another state (restore operation)", - new BooleanParameter(&_options.saveCurrent)); #ifdef USE_ENTERPRISE options->addOption("--status-id", "returns the status of a transfer process " @@ -758,6 +734,11 @@ void BackupFeature::collectOptions(std::shared_ptr opti "abort transfer with given status-id " "(upload/download operation)", new BooleanParameter(&_options.abort)); + + options->addOption("--force", + "abort transactions if needed to ensure a consistent snapshot" + "(create operation)", + new BooleanParameter(&_options.abortTransactionsIfNeeded)); #endif /* options->addSection( diff --git a/arangosh/Backup/BackupFeature.h b/arangosh/Backup/BackupFeature.h index fc4b42bd69..b82d4646d6 100644 --- a/arangosh/Backup/BackupFeature.h +++ b/arangosh/Backup/BackupFeature.h @@ -56,7 +56,7 @@ class BackupFeature : public application_features::ApplicationFeature { public: struct Options { - bool force = false; + bool allowInconsistent = false; std::string identifier = ""; std::string label = ""; std::string statusId = ""; @@ -65,8 +65,9 @@ class BackupFeature : public application_features::ApplicationFeature { double maxWaitForLock = 60.0; double maxWaitForRestart = 0.0; std::string operation = "list"; - bool saveCurrent = false; bool abort = false; + bool abortTransactionsIfNeeded = false; + bool ignoreVersion = false; }; private: diff --git a/lib/Basics/files.cpp b/lib/Basics/files.cpp index 909ff22778..4836285978 100644 --- a/lib/Basics/files.cpp +++ b/lib/Basics/files.cpp @@ -684,7 +684,7 @@ int TRI_RemoveDirectoryDeterministic(char const* filename) { std::string TRI_Dirname(std::string const& path) { size_t n = path.size(); - + if (n == 0) { // "" => "." return std::string("."); @@ -766,6 +766,10 @@ std::string TRI_Basename(char const* path) { } } +std::string TRI_Basename(std::string const& path) { + return TRI_Basename(path.c_str()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief returns a list of files in path //////////////////////////////////////////////////////////////////////////////// @@ -1124,7 +1128,7 @@ bool TRI_ProcessFile(char const* filename, char* TRI_SlurpGzipFile(char const* filename, size_t* length) { TRI_set_errno(TRI_ERROR_NO_ERROR); gzFile gzFd = gzopen(filename,"rb"); - auto fdGuard = arangodb::scopeGuard([&gzFd]() { + auto fdGuard = arangodb::scopeGuard([&gzFd]() { if (nullptr != gzFd) { gzclose(gzFd); } @@ -1181,7 +1185,7 @@ char* TRI_SlurpDecryptFile(EncryptionFeature& encryptionFeature, char const* fil TRI_set_errno(TRI_ERROR_NO_ERROR); encryptionFeature.setKeyFile(keyfile); - auto keyGuard = arangodb::scopeGuard([&encryptionFeature]() { + auto keyGuard = arangodb::scopeGuard([&encryptionFeature]() { encryptionFeature.clearKey(); }); @@ -2320,7 +2324,7 @@ std::string TRI_GetTempPath() { // no --temp.path was specified // fill template and create directory tries = 9; - + // create base directories of the new directory (but ignore any failures // if they already exist. if this fails, the following mkDTemp will either // succeed or fail and return an error diff --git a/lib/Basics/files.h b/lib/Basics/files.h index b3e3b8db04..3b4c09efde 100644 --- a/lib/Basics/files.h +++ b/lib/Basics/files.h @@ -144,6 +144,12 @@ std::string TRI_Dirname(std::string const& path); std::string TRI_Basename(char const* path); +//////////////////////////////////////////////////////////////////////////////// +/// @brief extracts the basename +//////////////////////////////////////////////////////////////////////////////// + +std::string TRI_Basename(std::string const& path); + //////////////////////////////////////////////////////////////////////////////// /// @brief returns a list of files in path ////////////////////////////////////////////////////////////////////////////////