mirror of https://gitee.com/bigwinds/arangodb
factored out lock-file handling into LockFileFeature
This commit is contained in:
parent
87a96ece67
commit
30d32bb70e
|
@ -247,6 +247,7 @@ add_executable(${BIN_ARANGOD}
|
||||||
RestServer/FileDescriptorsFeature.cpp
|
RestServer/FileDescriptorsFeature.cpp
|
||||||
RestServer/FrontendFeature.cpp
|
RestServer/FrontendFeature.cpp
|
||||||
RestServer/InitDatabaseFeature.cpp
|
RestServer/InitDatabaseFeature.cpp
|
||||||
|
RestServer/LockfileFeature.cpp
|
||||||
RestServer/QueryRegistryFeature.cpp
|
RestServer/QueryRegistryFeature.cpp
|
||||||
RestServer/RestServerFeature.cpp
|
RestServer/RestServerFeature.cpp
|
||||||
RestServer/ScriptFeature.cpp
|
RestServer/ScriptFeature.cpp
|
||||||
|
|
|
@ -43,7 +43,7 @@ class DatabaseFeature final : public application_features::ApplicationFeature {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TRI_vocbase_t* vocbase() const { return _vocbase; }
|
TRI_vocbase_t* vocbase() const { return _vocbase; }
|
||||||
|
std::string databasePath() const { return _databasePath; }
|
||||||
bool ignoreDatafileErrors() const { return _ignoreDatafileErrors; }
|
bool ignoreDatafileErrors() const { return _ignoreDatafileErrors; }
|
||||||
bool isInitiallyEmpty() const { return _isInitiallyEmpty; }
|
bool isInitiallyEmpty() const { return _isInitiallyEmpty; }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Jan Steemann
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "LockfileFeature.h"
|
||||||
|
#include "Basics/Exceptions.h"
|
||||||
|
#include "Basics/FileUtils.h"
|
||||||
|
#include "Basics/files.h"
|
||||||
|
#include "RestServer/DatabaseFeature.h"
|
||||||
|
|
||||||
|
using namespace arangodb;
|
||||||
|
using namespace arangodb::basics;
|
||||||
|
|
||||||
|
LockfileFeature::LockfileFeature(
|
||||||
|
application_features::ApplicationServer* server)
|
||||||
|
: ApplicationFeature(server, "Lockfile") {
|
||||||
|
setOptional(false);
|
||||||
|
requiresElevatedPrivileges(false);
|
||||||
|
startsAfter("Logger");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockfileFeature::prepare() {
|
||||||
|
// build lockfile name
|
||||||
|
DatabaseFeature* database = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
std::string databasePath = database->databasePath();
|
||||||
|
TRI_ASSERT(!databasePath.empty());
|
||||||
|
|
||||||
|
_lockFilename = basics::FileUtils::buildFilename(databasePath, "LOCK");
|
||||||
|
|
||||||
|
TRI_ASSERT(!_lockFilename.empty());
|
||||||
|
|
||||||
|
int res = TRI_VerifyLockFile(_lockFilename.c_str());
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
LOG(ERR) << "database is locked, please check the lock file '" << _lockFilename << "'";
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATADIR_LOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRI_ExistsFile(_lockFilename.c_str())) {
|
||||||
|
TRI_UnlinkFile(_lockFilename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
LOG(ERR)
|
||||||
|
<< "cannot lock the database directory, please check the lock file '"
|
||||||
|
<< _lockFilename << "': " << TRI_errno_string(res);
|
||||||
|
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATADIR_UNLOCKABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = TRI_CreateLockFile(_lockFilename.c_str());
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
LOG(ERR)
|
||||||
|
<< "cannot lock the database directory, please check the lock file '"
|
||||||
|
<< _lockFilename << "': " << TRI_errno_string(res);
|
||||||
|
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATADIR_UNLOCKABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockfileFeature::unprepare() {
|
||||||
|
TRI_DestroyLockFile(_lockFilename.c_str());
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Jan Steemann
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef ARANGODB_APPLICATION_FEATURES_LOCK_FILE_FEATURE_H
|
||||||
|
#define ARANGODB_APPLICATION_FEATURES_LOCL_FILE_FEATURE_H 1
|
||||||
|
|
||||||
|
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||||
|
|
||||||
|
namespace arangodb {
|
||||||
|
class LockfileFeature final : public application_features::ApplicationFeature {
|
||||||
|
public:
|
||||||
|
explicit LockfileFeature(application_features::ApplicationServer* server);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void prepare() override final;
|
||||||
|
void unprepare() override final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _lockFilename;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -57,6 +57,7 @@
|
||||||
#include "RestServer/FileDescriptorsFeature.h"
|
#include "RestServer/FileDescriptorsFeature.h"
|
||||||
#include "RestServer/FrontendFeature.h"
|
#include "RestServer/FrontendFeature.h"
|
||||||
#include "RestServer/InitDatabaseFeature.h"
|
#include "RestServer/InitDatabaseFeature.h"
|
||||||
|
#include "RestServer/LockfileFeature.h"
|
||||||
#include "RestServer/QueryRegistryFeature.h"
|
#include "RestServer/QueryRegistryFeature.h"
|
||||||
#include "RestServer/RestServerFeature.h"
|
#include "RestServer/RestServerFeature.h"
|
||||||
#include "RestServer/ScriptFeature.h"
|
#include "RestServer/ScriptFeature.h"
|
||||||
|
@ -125,6 +126,7 @@ static int runServer(int argc, char** argv) {
|
||||||
server.addFeature(new FrontendFeature(&server));
|
server.addFeature(new FrontendFeature(&server));
|
||||||
server.addFeature(new InitDatabaseFeature(&server, nonServerFeatures));
|
server.addFeature(new InitDatabaseFeature(&server, nonServerFeatures));
|
||||||
server.addFeature(new LanguageFeature(&server));
|
server.addFeature(new LanguageFeature(&server));
|
||||||
|
server.addFeature(new LockfileFeature(&server));
|
||||||
server.addFeature(new LogfileManager(&server));
|
server.addFeature(new LogfileManager(&server));
|
||||||
server.addFeature(new LoggerBufferFeature(&server));
|
server.addFeature(new LoggerBufferFeature(&server));
|
||||||
server.addFeature(new LoggerFeature(&server, true));
|
server.addFeature(new LoggerFeature(&server, true));
|
||||||
|
|
|
@ -38,7 +38,8 @@ EngineSelectorFeature::EngineSelectorFeature(
|
||||||
: ApplicationFeature(server, "EngineSelector"), _engine(MMFilesEngine::EngineName) {
|
: ApplicationFeature(server, "EngineSelector"), _engine(MMFilesEngine::EngineName) {
|
||||||
setOptional(false);
|
setOptional(false);
|
||||||
requiresElevatedPrivileges(false);
|
requiresElevatedPrivileges(false);
|
||||||
startsAfter("Logger");
|
startsAfter("Database");
|
||||||
|
startsAfter("LogfileManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineSelectorFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
void EngineSelectorFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
||||||
|
|
|
@ -306,19 +306,18 @@ static int CreateBaseApplicationDirectory(char const* basePath,
|
||||||
/// @brief create app subdirectory for a database
|
/// @brief create app subdirectory for a database
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int CreateApplicationDirectory(char const* name, char const* basePath) {
|
static int CreateApplicationDirectory(std::string const& name, std::string const& basePath) {
|
||||||
if (basePath == nullptr || strlen(basePath) == 0) {
|
if (basePath.empty()) {
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string const path = basics::FileUtils::buildFilename(basics::FileUtils::buildFilename(basePath, "db"), name);
|
||||||
int res = TRI_ERROR_NO_ERROR;
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
char* path = TRI_Concatenate3File(basePath, "_db", name);
|
|
||||||
|
|
||||||
if (path != nullptr) {
|
if (!TRI_IsDirectory(path.c_str())) {
|
||||||
if (!TRI_IsDirectory(path)) {
|
|
||||||
long systemError;
|
long systemError;
|
||||||
std::string errorMessage;
|
std::string errorMessage;
|
||||||
res = TRI_CreateRecursiveDirectory(path, systemError, errorMessage);
|
res = TRI_CreateRecursiveDirectory(path.c_str(), systemError, errorMessage);
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
if (arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
if (arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
||||||
|
@ -338,9 +337,6 @@ static int CreateApplicationDirectory(char const* name, char const* basePath) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +516,7 @@ static int OpenDatabases(TRI_server_t* server, bool isUpgrade) {
|
||||||
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
|
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
|
||||||
auto appPath = dealer->appPath();
|
auto appPath = dealer->appPath();
|
||||||
|
|
||||||
res = CreateApplicationDirectory(databaseName.c_str(), appPath.c_str());
|
res = CreateApplicationDirectory(databaseName, appPath);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
break;
|
break;
|
||||||
|
@ -1149,19 +1145,9 @@ int TRI_InitServer(TRI_server_t* server,
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
server->_lockFilename = TRI_Concatenate2File(server->_basePath, "LOCK");
|
|
||||||
|
|
||||||
if (server->_lockFilename == nullptr) {
|
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_databasePath);
|
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_basePath);
|
|
||||||
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
server->_serverIdFilename = TRI_Concatenate2File(server->_basePath, "SERVER");
|
server->_serverIdFilename = TRI_Concatenate2File(server->_basePath, "SERVER");
|
||||||
|
|
||||||
if (server->_serverIdFilename == nullptr) {
|
if (server->_serverIdFilename == nullptr) {
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_lockFilename);
|
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_databasePath);
|
TRI_Free(TRI_CORE_MEM_ZONE, server->_databasePath);
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_basePath);
|
TRI_Free(TRI_CORE_MEM_ZONE, server->_basePath);
|
||||||
|
|
||||||
|
@ -1208,11 +1194,8 @@ TRI_server_id_t TRI_GetIdServer() { return ServerId; }
|
||||||
|
|
||||||
int TRI_StartServer(TRI_server_t* server, bool checkVersion,
|
int TRI_StartServer(TRI_server_t* server, bool checkVersion,
|
||||||
bool performUpgrade) {
|
bool performUpgrade) {
|
||||||
int res;
|
|
||||||
|
|
||||||
if (!TRI_IsDirectory(server->_basePath)) {
|
if (!TRI_IsDirectory(server->_basePath)) {
|
||||||
LOG(ERR) << "database path '" << server->_basePath
|
LOG(ERR) << "database path '" << server->_basePath << "' is not a directory";
|
||||||
<< "' is not a directory";
|
|
||||||
|
|
||||||
return TRI_ERROR_ARANGO_DATADIR_INVALID;
|
return TRI_ERROR_ARANGO_DATADIR_INVALID;
|
||||||
}
|
}
|
||||||
|
@ -1225,33 +1208,6 @@ int TRI_StartServer(TRI_server_t* server, bool checkVersion,
|
||||||
return TRI_ERROR_ARANGO_DATADIR_NOT_WRITABLE;
|
return TRI_ERROR_ARANGO_DATADIR_NOT_WRITABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...........................................................................
|
|
||||||
// check that the database is not locked and lock it
|
|
||||||
// ...........................................................................
|
|
||||||
|
|
||||||
res = TRI_VerifyLockFile(server->_lockFilename);
|
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
|
||||||
LOG(ERR) << "database is locked, please check the lock file '"
|
|
||||||
<< server->_lockFilename << "'";
|
|
||||||
|
|
||||||
return TRI_ERROR_ARANGO_DATADIR_LOCKED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TRI_ExistsFile(server->_lockFilename)) {
|
|
||||||
TRI_UnlinkFile(server->_lockFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
res = TRI_CreateLockFile(server->_lockFilename);
|
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
|
||||||
LOG(ERR)
|
|
||||||
<< "cannot lock the database directory, please check the lock file '"
|
|
||||||
<< server->_lockFilename << "': " << TRI_errno_string(res);
|
|
||||||
|
|
||||||
return TRI_ERROR_ARANGO_DATADIR_UNLOCKABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
// read the server id
|
// read the server id
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
@ -1421,8 +1377,6 @@ int TRI_StopServer(TRI_server_t* server) {
|
||||||
|
|
||||||
CloseDatabases(server);
|
CloseDatabases(server);
|
||||||
|
|
||||||
TRI_DestroyLockFile(server->_lockFilename);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1628,7 +1582,7 @@ int TRI_CreateDatabaseServer(TRI_server_t* server, TRI_voc_tick_t databaseId,
|
||||||
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
|
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
|
||||||
auto appPath = dealer->appPath();
|
auto appPath = dealer->appPath();
|
||||||
|
|
||||||
CreateApplicationDirectory(vocbase->_name, appPath.c_str());
|
CreateApplicationDirectory(vocbase->_name, appPath);
|
||||||
|
|
||||||
if (!arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
if (!arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
||||||
TRI_StartCompactorVocBase(vocbase);
|
TRI_StartCompactorVocBase(vocbase);
|
||||||
|
@ -2155,7 +2109,6 @@ TRI_server_t::TRI_server_t()
|
||||||
_queryRegistry(nullptr),
|
_queryRegistry(nullptr),
|
||||||
_basePath(nullptr),
|
_basePath(nullptr),
|
||||||
_databasePath(nullptr),
|
_databasePath(nullptr),
|
||||||
_lockFilename(nullptr),
|
|
||||||
_serverIdFilename(nullptr),
|
_serverIdFilename(nullptr),
|
||||||
_disableReplicationAppliers(false),
|
_disableReplicationAppliers(false),
|
||||||
_disableCompactor(false),
|
_disableCompactor(false),
|
||||||
|
@ -2171,7 +2124,6 @@ TRI_server_t::~TRI_server_t() {
|
||||||
delete p;
|
delete p;
|
||||||
|
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, _serverIdFilename);
|
TRI_Free(TRI_CORE_MEM_ZONE, _serverIdFilename);
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, _lockFilename);
|
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, _databasePath);
|
TRI_Free(TRI_CORE_MEM_ZONE, _databasePath);
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, _basePath);
|
TRI_Free(TRI_CORE_MEM_ZONE, _basePath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,6 @@ struct TRI_server_t {
|
||||||
|
|
||||||
char* _basePath;
|
char* _basePath;
|
||||||
char* _databasePath;
|
char* _databasePath;
|
||||||
char* _lockFilename;
|
|
||||||
char* _serverIdFilename;
|
char* _serverIdFilename;
|
||||||
|
|
||||||
bool _disableReplicationAppliers;
|
bool _disableReplicationAppliers;
|
||||||
|
|
Loading…
Reference in New Issue