mirror of https://gitee.com/bigwinds/arangodb
make arangorestore not report errors about the target database not found (#5286)
* make arangorestore not report errors about the target database not found when it is invoked with option `--create-database true`. In this case, arangorestore should not print an error but simply create the target database. This patch implements this change. Additionally, it aborts the startup of arangorestore in case there are any errors. Previously, the startup phase went on even when no connection could be established, which led to useless follow-up errors being printed. * simplify error handling a bit
This commit is contained in:
parent
e1da502c67
commit
3c39337d34
|
@ -911,14 +911,14 @@ void DumpFeature::start() {
|
||||||
auto dbName = client->databaseName();
|
auto dbName = client->databaseName();
|
||||||
|
|
||||||
// get a client to use in main thread
|
// get a client to use in main thread
|
||||||
auto httpClient = _clientManager.getConnectedClient(_options.force, true);
|
auto httpClient = _clientManager.getConnectedClient(_options.force, true, true);
|
||||||
|
|
||||||
// check if we are in cluster or single-server mode
|
// check if we are in cluster or single-server mode
|
||||||
Result result{TRI_ERROR_NO_ERROR};
|
Result result{TRI_ERROR_NO_ERROR};
|
||||||
std::tie(result, _options.clusterMode) =
|
std::tie(result, _options.clusterMode) =
|
||||||
_clientManager.getArangoIsCluster(*httpClient);
|
_clientManager.getArangoIsCluster(*httpClient);
|
||||||
if (result.fail()) {
|
if (result.fail()) {
|
||||||
LOG_TOPIC(ERR, Logger::FIXME)
|
LOG_TOPIC(FATAL, Logger::FIXME)
|
||||||
<< "Error: could not detect ArangoDB instance type";
|
<< "Error: could not detect ArangoDB instance type";
|
||||||
FATAL_ERROR_EXIT();
|
FATAL_ERROR_EXIT();
|
||||||
}
|
}
|
||||||
|
|
|
@ -771,7 +771,7 @@ void RestoreFeature::validateOptions(
|
||||||
if (1 == n) {
|
if (1 == n) {
|
||||||
_options.inputPath = positionals[0];
|
_options.inputPath = positionals[0];
|
||||||
} else if (1 < n) {
|
} else if (1 < n) {
|
||||||
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
|
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
|
||||||
<< "expecting at most one directory, got " + join(positionals, ", ");
|
<< "expecting at most one directory, got " + join(positionals, ", ");
|
||||||
FATAL_ERROR_EXIT();
|
FATAL_ERROR_EXIT();
|
||||||
}
|
}
|
||||||
|
@ -784,7 +784,7 @@ void RestoreFeature::validateOptions(
|
||||||
auto clamped = boost::algorithm::clamp(_options.threadCount, 1,
|
auto clamped = boost::algorithm::clamp(_options.threadCount, 1,
|
||||||
4 * TRI_numberProcessors());
|
4 * TRI_numberProcessors());
|
||||||
if (_options.threadCount != clamped) {
|
if (_options.threadCount != clamped) {
|
||||||
LOG_TOPIC(WARN, Logger::FIXME) << "capping --threads value to " << clamped;
|
LOG_TOPIC(WARN, Logger::RESTORE) << "capping --threads value to " << clamped;
|
||||||
_options.threadCount = clamped;
|
_options.threadCount = clamped;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -799,7 +799,7 @@ void RestoreFeature::prepare() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_options.importStructure && !_options.importData) {
|
if (!_options.importStructure && !_options.importData) {
|
||||||
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
|
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
|
||||||
<< "Error: must specify either --create-collection or --import-data";
|
<< "Error: must specify either --create-collection or --import-data";
|
||||||
FATAL_ERROR_EXIT();
|
FATAL_ERROR_EXIT();
|
||||||
}
|
}
|
||||||
|
@ -816,11 +816,11 @@ void RestoreFeature::start() {
|
||||||
if (_directory->status().fail()) {
|
if (_directory->status().fail()) {
|
||||||
switch (_directory->status().errorNumber()) {
|
switch (_directory->status().errorNumber()) {
|
||||||
case TRI_ERROR_FILE_NOT_FOUND:
|
case TRI_ERROR_FILE_NOT_FOUND:
|
||||||
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
|
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
|
||||||
<< "input directory '" << _options.inputPath << "' does not exist";
|
<< "input directory '" << _options.inputPath << "' does not exist";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
|
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
|
||||||
<< _directory->status().errorMessage();
|
<< _directory->status().errorMessage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -835,7 +835,7 @@ void RestoreFeature::start() {
|
||||||
|
|
||||||
std::unique_ptr<SimpleHttpClient> httpClient;
|
std::unique_ptr<SimpleHttpClient> httpClient;
|
||||||
Result result =
|
Result result =
|
||||||
_clientManager.getConnectedClient(httpClient, _options.force, true);
|
_clientManager.getConnectedClient(httpClient, _options.force, true, !_options.createDatabase);
|
||||||
if (result.is(TRI_SIMPLE_CLIENT_COULD_NOT_CONNECT)) {
|
if (result.is(TRI_SIMPLE_CLIENT_COULD_NOT_CONNECT)) {
|
||||||
LOG_TOPIC(FATAL, Logger::RESTORE)
|
LOG_TOPIC(FATAL, Logger::RESTORE)
|
||||||
<< "cannot create server connection, giving up!";
|
<< "cannot create server connection, giving up!";
|
||||||
|
@ -861,13 +861,12 @@ void RestoreFeature::start() {
|
||||||
|
|
||||||
// re-check connection and version
|
// re-check connection and version
|
||||||
result =
|
result =
|
||||||
_clientManager.getConnectedClient(httpClient, _options.force, true);
|
_clientManager.getConnectedClient(httpClient, _options.force, true, true);
|
||||||
if (result.fail() &&
|
}
|
||||||
!(_options.force && result.is(TRI_ERROR_INCOMPATIBLE_VERSION))) {
|
|
||||||
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
|
if (result.fail() && !_options.force) {
|
||||||
<< "cannot create server connection, giving up!";
|
LOG_TOPIC(FATAL, Logger::RESTORE) << "cannot create server connection: " << result.errorMessage();
|
||||||
FATAL_ERROR_EXIT();
|
FATAL_ERROR_EXIT();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read encryption info
|
// read encryption info
|
||||||
|
@ -876,7 +875,7 @@ void RestoreFeature::start() {
|
||||||
// read dump info
|
// read dump info
|
||||||
result = ::checkDumpDatabase(*_directory, _options.forceSameDatabase);
|
result = ::checkDumpDatabase(*_directory, _options.forceSameDatabase);
|
||||||
if (result.fail()) {
|
if (result.fail()) {
|
||||||
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << result.errorMessage();
|
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE) << result.errorMessage();
|
||||||
FATAL_ERROR_EXIT();
|
FATAL_ERROR_EXIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,7 +883,7 @@ void RestoreFeature::start() {
|
||||||
std::tie(result, _options.clusterMode) =
|
std::tie(result, _options.clusterMode) =
|
||||||
_clientManager.getArangoIsCluster(*httpClient);
|
_clientManager.getArangoIsCluster(*httpClient);
|
||||||
if (result.fail()) {
|
if (result.fail()) {
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << result.errorMessage();
|
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << result.errorMessage();
|
||||||
_exitCode = EXIT_FAILURE;
|
_exitCode = EXIT_FAILURE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -892,7 +891,7 @@ void RestoreFeature::start() {
|
||||||
std::tie(result, _options.indexesFirst) =
|
std::tie(result, _options.indexesFirst) =
|
||||||
_clientManager.getArangoIsUsingEngine(*httpClient, "rocksdb");
|
_clientManager.getArangoIsUsingEngine(*httpClient, "rocksdb");
|
||||||
if (result.fail()) {
|
if (result.fail()) {
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << result.errorMessage();
|
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << result.errorMessage();
|
||||||
_exitCode = EXIT_FAILURE;
|
_exitCode = EXIT_FAILURE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -911,16 +910,16 @@ void RestoreFeature::start() {
|
||||||
result = ::processInputDirectory(*httpClient, _clientTaskQueue, *this,
|
result = ::processInputDirectory(*httpClient, _clientTaskQueue, *this,
|
||||||
_options, *_directory, _stats);
|
_options, *_directory, _stats);
|
||||||
} catch (std::exception const& ex) {
|
} catch (std::exception const& ex) {
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "caught exception " << ex.what();
|
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << "caught exception " << ex.what();
|
||||||
result = {TRI_ERROR_INTERNAL};
|
result = {TRI_ERROR_INTERNAL};
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
|
LOG_TOPIC(ERR, arangodb::Logger::RESTORE)
|
||||||
<< "Error: caught unknown exception";
|
<< "Error: caught unknown exception";
|
||||||
result = {TRI_ERROR_INTERNAL};
|
result = {TRI_ERROR_INTERNAL};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.fail()) {
|
if (result.fail()) {
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << result.errorMessage();
|
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << result.errorMessage();
|
||||||
_exitCode = EXIT_FAILURE;
|
_exitCode = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ ClientManager::~ClientManager() {}
|
||||||
|
|
||||||
Result ClientManager::getConnectedClient(
|
Result ClientManager::getConnectedClient(
|
||||||
std::unique_ptr<httpclient::SimpleHttpClient>& httpClient, bool force,
|
std::unique_ptr<httpclient::SimpleHttpClient>& httpClient, bool force,
|
||||||
bool verbose) {
|
bool logServerVersion, bool logDatabaseNotFound) {
|
||||||
ClientFeature* client =
|
ClientFeature* client =
|
||||||
application_features::ApplicationServer::getFeature<ClientFeature>(
|
application_features::ApplicationServer::getFeature<ClientFeature>(
|
||||||
"Client");
|
"Client");
|
||||||
|
@ -104,16 +104,20 @@ Result ClientManager::getConnectedClient(
|
||||||
int errorCode;
|
int errorCode;
|
||||||
std::string const versionString = httpClient->getServerVersion(&errorCode);
|
std::string const versionString = httpClient->getServerVersion(&errorCode);
|
||||||
if (TRI_ERROR_NO_ERROR != errorCode) {
|
if (TRI_ERROR_NO_ERROR != errorCode) {
|
||||||
LOG_TOPIC(ERR, _topic) << "Could not connect to endpoint '"
|
if (TRI_ERROR_ARANGO_DATABASE_NOT_FOUND != errorCode || logDatabaseNotFound) {
|
||||||
<< client->endpoint() << "', database: '" << dbName
|
// arangorestore does not log "database not found" errors in case
|
||||||
<< "', username: '" << client->username() << "'";
|
// it tries to create the database...
|
||||||
LOG_TOPIC(FATAL, _topic)
|
LOG_TOPIC(ERR, _topic) << "Could not connect to endpoint '"
|
||||||
<< "Error message: '" << httpClient->getErrorMessage() << "'";
|
<< client->endpoint() << "', database: '" << dbName
|
||||||
|
<< "', username: '" << client->username() << "'";
|
||||||
|
LOG_TOPIC(ERR, _topic)
|
||||||
|
<< "Error message: '" << httpClient->getErrorMessage() << "'";
|
||||||
|
}
|
||||||
|
|
||||||
return {errorCode};
|
return {errorCode};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (logServerVersion) {
|
||||||
// successfully connected
|
// successfully connected
|
||||||
LOG_TOPIC(INFO, _topic) << "Server version: " << versionString;
|
LOG_TOPIC(INFO, _topic) << "Server version: " << versionString;
|
||||||
}
|
}
|
||||||
|
@ -135,10 +139,10 @@ Result ClientManager::getConnectedClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<httpclient::SimpleHttpClient> ClientManager::getConnectedClient(
|
std::unique_ptr<httpclient::SimpleHttpClient> ClientManager::getConnectedClient(
|
||||||
bool force, bool verbose) {
|
bool force, bool logServerVersion, bool logDatabaseNotFound) {
|
||||||
std::unique_ptr<httpclient::SimpleHttpClient> httpClient;
|
std::unique_ptr<httpclient::SimpleHttpClient> httpClient;
|
||||||
|
|
||||||
Result result = getConnectedClient(httpClient, force, verbose);
|
Result result = getConnectedClient(httpClient, force, logServerVersion, logDatabaseNotFound);
|
||||||
if (result.fail() && !(force && result.is(TRI_ERROR_INCOMPATIBLE_VERSION))) {
|
if (result.fail() && !(force && result.is(TRI_ERROR_INCOMPATIBLE_VERSION))) {
|
||||||
FATAL_ERROR_EXIT();
|
FATAL_ERROR_EXIT();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,12 +58,13 @@ class ClientManager {
|
||||||
* @param httpclient Output pointer will be set on success
|
* @param httpclient Output pointer will be set on success
|
||||||
* @param force If true, an incompatible version will not result in an
|
* @param force If true, an incompatible version will not result in an
|
||||||
* error result
|
* error result
|
||||||
* @param verbose If true, output the server version to logs
|
* @param logServerVersion If true, output the server version to logs
|
||||||
|
* @param logDatabaseNotFound If true, log errors when database was not found
|
||||||
* @return Status code and possible error message
|
* @return Status code and possible error message
|
||||||
*/
|
*/
|
||||||
Result getConnectedClient(std::unique_ptr<httpclient::SimpleHttpClient>&
|
Result getConnectedClient(std::unique_ptr<httpclient::SimpleHttpClient>&
|
||||||
httpClient, bool force = false,
|
httpClient, bool force, bool logServerVersion,
|
||||||
bool verbose = false);
|
bool logDatabaseNotFound);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes a client, connects to server, and verifies version
|
* @brief Initializes a client, connects to server, and verifies version
|
||||||
|
@ -74,11 +75,12 @@ class ClientManager {
|
||||||
*
|
*
|
||||||
* @param force If true, an incompatible version will not result in a fatal
|
* @param force If true, an incompatible version will not result in a fatal
|
||||||
* error exit condition
|
* error exit condition
|
||||||
* @param verbose If true, output the server version to logs
|
* @param logServerVersion If true, output the server version to logs
|
||||||
|
* @param logDatabaseNotFound If true, log errors when database was not found
|
||||||
* @return A connected `SimpleHttpClient`
|
* @return A connected `SimpleHttpClient`
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<httpclient::SimpleHttpClient> getConnectedClient(
|
std::unique_ptr<httpclient::SimpleHttpClient> getConnectedClient(
|
||||||
bool force = false, bool verbose = false);
|
bool force, bool logServerVersion, bool logDatabaseNotFound);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Conditionally prefixes a relative URI with database-specific path
|
* @brief Conditionally prefixes a relative URI with database-specific path
|
||||||
|
|
|
@ -216,7 +216,7 @@ inline bool ClientTaskQueue<JobData>::spawnWorkers(
|
||||||
try {
|
try {
|
||||||
MUTEX_LOCKER(lock, _workersLock);
|
MUTEX_LOCKER(lock, _workersLock);
|
||||||
for (; spawned < numWorkers; spawned++) {
|
for (; spawned < numWorkers; spawned++) {
|
||||||
auto client = manager.getConnectedClient();
|
auto client = manager.getConnectedClient(false, false, true);
|
||||||
auto worker = std::make_unique<Worker>(*this, std::move(client));
|
auto worker = std::make_unique<Worker>(*this, std::move(client));
|
||||||
_workers.emplace_back(std::move(worker));
|
_workers.emplace_back(std::move(worker));
|
||||||
_workers.back()->start();
|
_workers.back()->start();
|
||||||
|
|
Loading…
Reference in New Issue