1
0
Fork 0

storage engine selection at server start

This commit is contained in:
jsteemann 2016-07-15 12:26:40 +02:00
parent bff23ecd06
commit 7742e709a3
9 changed files with 568 additions and 47 deletions

View File

@ -268,7 +268,9 @@ add_executable(${BIN_ARANGOD}
Scheduler/TimerTask.cpp Scheduler/TimerTask.cpp
Statistics/StatisticsFeature.cpp Statistics/StatisticsFeature.cpp
Statistics/statistics.cpp Statistics/statistics.cpp
StorageEngine/ArangoEngine.cpp StorageEngine/EngineSelectorFeature.cpp
StorageEngine/MMFilesEngine.cpp
StorageEngine/OtherEngine.cpp
Utils/AqlTransaction.cpp Utils/AqlTransaction.cpp
Utils/CollectionExport.cpp Utils/CollectionExport.cpp
Utils/CollectionKeys.cpp Utils/CollectionKeys.cpp

View File

@ -67,6 +67,9 @@
#include "Ssl/SslFeature.h" #include "Ssl/SslFeature.h"
#include "Ssl/SslServerFeature.h" #include "Ssl/SslServerFeature.h"
#include "Statistics/StatisticsFeature.h" #include "Statistics/StatisticsFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/MMFilesEngine.h"
#include "StorageEngine/OtherEngine.h"
#include "V8Server/FoxxQueuesFeature.h" #include "V8Server/FoxxQueuesFeature.h"
#include "V8Server/V8DealerFeature.h" #include "V8Server/V8DealerFeature.h"
#include "Wal/LogfileManager.h" #include "Wal/LogfileManager.h"
@ -116,6 +119,7 @@ static int runServer(int argc, char** argv) {
server.addFeature(new DatabaseServerFeature(&server)); server.addFeature(new DatabaseServerFeature(&server));
server.addFeature(new DispatcherFeature(&server)); server.addFeature(new DispatcherFeature(&server));
server.addFeature(new EndpointFeature(&server)); server.addFeature(new EndpointFeature(&server));
server.addFeature(new EngineSelectorFeature(&server));
server.addFeature(new FileDescriptorsFeature(&server)); server.addFeature(new FileDescriptorsFeature(&server));
server.addFeature(new FoxxQueuesFeature(&server)); server.addFeature(new FoxxQueuesFeature(&server));
server.addFeature(new FrontendFeature(&server)); server.addFeature(new FrontendFeature(&server));
@ -158,15 +162,21 @@ static int runServer(int argc, char** argv) {
server.addFeature(supervisor.release()); server.addFeature(supervisor.release());
#endif #endif
// storage engines
server.addFeature(new MMFilesEngine(&server));
server.addFeature(new OtherEngine(&server));
try { try {
server.run(argc, argv); server.run(argc, argv);
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangod terminated because of an unhandled exception: " LOG(ERR) << "arangod terminated because of an unhandled exception: "
<< ex.what(); << ex.what();
Logger::flush();
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
} catch (...) { } catch (...) {
LOG(ERR) << "arangod terminated because of an unhandled exception of " LOG(ERR) << "arangod terminated because of an unhandled exception of "
"unknown type"; "unknown type";
Logger::flush();
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
} }

View File

@ -0,0 +1,71 @@
////////////////////////////////////////////////////////////////////////////////
/// 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 Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#include "EngineSelectorFeature.h"
#include "ApplicationFeatures/ApplicationServer.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "StorageEngine/MMFilesEngine.h"
#include "StorageEngine/OtherEngine.h"
#include "StorageEngine/StorageEngine.h"
using namespace arangodb;
using namespace arangodb::options;
EngineSelectorFeature::EngineSelectorFeature(
application_features::ApplicationServer* server)
: ApplicationFeature(server, "EngineSelector"), _engine(MMFilesEngine::EngineName) {
setOptional(false);
requiresElevatedPrivileges(false);
startsAfter("Logger");
}
void EngineSelectorFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
options->addOption("--server.storage-engine",
"storage engine type",
new DiscreteValuesParameter<StringParameter>(&_engine, availableEngines()));
}
void EngineSelectorFeature::prepare() {
// deactivate all engines but the selected one
for (auto& engine : availableEngines()) {
StorageEngine* e = application_features::ApplicationServer::getFeature<StorageEngine>(engine + "Engine");
if (engine == _engine) {
// this is the selected engine
LOG(TRACE) << "enabling storage engine " << engine;
e->enable();
} else {
// turn off all other storage engines
LOG(TRACE) << "disabling storage engine " << engine;
e->disable();
}
}
}
// all available storage engines
std::unordered_set<std::string> EngineSelectorFeature::availableEngines() {
return std::unordered_set<std::string>{
MMFilesEngine::EngineName,
OtherEngine::EngineName
};
}

View File

@ -0,0 +1,45 @@
////////////////////////////////////////////////////////////////////////////////
/// 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 Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_STORAGE_ENGINE_ENGINE_SELECTOR_FEATURE_H
#define ARANGODB_STORAGE_ENGINE_ENGINE_SELECTOR_FEATURE_H 1
#include "ApplicationFeatures/ApplicationFeature.h"
#include "ProgramOptions/ProgramOptions.h"
namespace arangodb {
class EngineSelectorFeature final : public application_features::ApplicationFeature {
public:
explicit EngineSelectorFeature(application_features::ApplicationServer* server);
public:
void collectOptions(std::shared_ptr<options::ProgramOptions>) override final;
void prepare() override final;
static std::unordered_set<std::string> availableEngines();
private:
std::string _engine;
};
}
#endif

View File

@ -0,0 +1,193 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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 "MMFilesEngine.h"
using namespace arangodb;
std::string const MMFilesEngine::EngineName("mmfiles");
// create the storage engine
MMFilesEngine::MMFilesEngine(application_features::ApplicationServer* server)
: StorageEngine(server, "mmfilesEngine") {
}
MMFilesEngine::~MMFilesEngine() {
}
// add the storage engine's specifc options to the global list of options
void MMFilesEngine::collectOptions(std::shared_ptr<options::ProgramOptions>) {
}
// validate the storage engine's specific options
void MMFilesEngine::validateOptions(std::shared_ptr<options::ProgramOptions>) {
}
// preparation phase for storage engine. can be used for internal setup.
// the storage engine must not start any threads here or write any files
void MMFilesEngine::prepare() {
}
// start the engine. now it's allowed to start engine-specific threads,
// write files etc.
void MMFilesEngine::start() {
}
// stop the storage engine. this can be used to flush all data to disk,
// shutdown threads etc. it is guaranteed that there will be no read and
// write requests to the storage engine after this call
void MMFilesEngine::stop() {
}
// fill the Builder object with an array of databases that were detected
// by the storage engine. this method must sort out databases that were not
// fully created (see "createDatabase" below). called at server start only
void MMFilesEngine::getDatabases(arangodb::velocypack::Builder& result) {
}
// fill the Builder object with an array of collections (and their corresponding
// indexes) that were detected by the storage engine. called at server start only
void MMFilesEngine::getCollectionsAndIndexes(arangodb::velocypack::Builder& result) {
}
// determine the maximum revision id previously handed out by the storage
// engine. this value is used as a lower bound for further HLC values handed out by
// the server. called at server start only, after getDatabases() and getCollectionsAndIndexes()
uint64_t MMFilesEngine::getMaxRevision() {
return 0; // TODO
}
// asks the storage engine to create a database as specified in the VPack
// Slice object and persist the creation info. It is guaranteed by the server that
// no other active database with the same name and id exists when this function
// is called. If this operation fails somewhere in the middle, the storage
// engine is required to fully clean up the creation and throw only then,
// so that subsequent database creation requests will not fail.
// the WAL entry for the database creation will be written *after* the call
// to "createDatabase" returns
void MMFilesEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) {
}
// asks the storage engine to drop the specified database and persist the
// deletion info. Note that physical deletion of the database data must not
// be carried out by this call, as there may
// still be readers of the database's data. It is recommended that this operation
// only sets a deletion flag for the database but let's an async task perform
// the actual deletion. The async task can later call the callback function to
// check whether the physical deletion of the database is possible.
// the WAL entry for database deletion will be written *after* the call
// to "dropDatabase" returns
void MMFilesEngine::dropDatabase(TRI_voc_tick_t id, std::function<bool()> const& canRemovePhysically) {
}
// asks the storage engine to create a collection as specified in the VPack
// Slice object and persist the creation info. It is guaranteed by the server
// that no other active collection with the same name and id exists in the same
// database when this function is called. If this operation fails somewhere in
// the middle, the storage engine is required to fully clean up the creation
// and throw only then, so that subsequent collection creation requests will not fail.
// the WAL entry for the collection creation will be written *after* the call
// to "createCollection" returns
void MMFilesEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) {
}
// asks the storage engine to drop the specified collection and persist the
// deletion info. Note that physical deletion of the collection data must not
// be carried out by this call, as there may
// still be readers of the collection's data. It is recommended that this operation
// only sets a deletion flag for the collection but let's an async task perform
// the actual deletion.
// the WAL entry for collection deletion will be written *after* the call
// to "dropCollection" returns
void MMFilesEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
std::function<bool()> const& canRemovePhysically) {
}
// asks the storage engine to rename the collection as specified in the VPack
// Slice object and persist the renaming info. It is guaranteed by the server
// that no other active collection with the same name and id exists in the same
// database when this function is called. If this operation fails somewhere in
// the middle, the storage engine is required to fully revert the rename operation
// and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns
void MMFilesEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) {
}
// asks the storage engine to change properties of the collection as specified in
// the VPack Slice object and persist them. If this operation fails
// somewhere in the middle, the storage engine is required to fully revert the
// property changes and throw only then, so that subsequent operations will not fail.
// the WAL entry for the propery change will be written *after* the call
// to "changeCollection" returns
void MMFilesEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) {
}
// asks the storage engine to create an index as specified in the VPack
// Slice object and persist the creation info. The database id, collection id
// and index data are passed in the Slice object. Note that this function
// is not responsible for inserting the individual documents into the index.
// If this operation fails somewhere in the middle, the storage engine is required
// to fully clean up the creation and throw only then, so that subsequent index
// creation requests will not fail.
// the WAL entry for the index creation will be written *after* the call
// to "createIndex" returns
void MMFilesEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) {
}
// asks the storage engine to drop the specified index and persist the deletion
// info. Note that physical deletion of the index must not be carried out by this call,
// as there may still be users of the index. It is recommended that this operation
// only sets a deletion flag for the index but let's an async task perform
// the actual deletion.
// the WAL entry for index deletion will be written *after* the call
// to "dropIndex" returns
void MMFilesEngine::dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
TRI_idx_iid_t id) {
}
// iterate all documents of the underlying collection
// this is called when a collection is openend, and all its documents need to be added to
// indexes etc.
void MMFilesEngine::iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
std::function<void(arangodb::velocypack::Slice const&)> const& cb) {
}
// adds a document to the storage engine
// this will be called by the WAL collector when surviving documents are being moved
// into the storage engine's realm
void MMFilesEngine::addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
arangodb::velocypack::Slice const& document) {
}
// removes a document from the storage engine
// this will be called by the WAL collector when non-surviving documents are being removed
// from the storage engine's realm
void MMFilesEngine::removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
arangodb::velocypack::Slice const& document) {
}

View File

@ -21,21 +21,21 @@
/// @author Jan Steemann /// @author Jan Steemann
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGOD_STORAGE_ENGINE_ARANGO_ENGINE_H #ifndef ARANGOD_STORAGE_ENGINE_MMFILES_ENGINE_H
#define ARANGOD_STORAGE_ENGINE_ARANGO_ENGINE_H 1 #define ARANGOD_STORAGE_ENGINE_MMFILES_ENGINE_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "StorageEngine/StorageEngine.h" #include "StorageEngine/StorageEngine.h"
namespace arangodb { namespace arangodb {
class ArangoEngine final : public StorageEngine { class MMFilesEngine final : public StorageEngine {
public: public:
// create the storage engine // create the storage engine
explicit ArangoEngine(application_features::ApplicationServer*); explicit MMFilesEngine(application_features::ApplicationServer*);
~ArangoEngine(); ~MMFilesEngine();
// inherited from ApplicationFeature // inherited from ApplicationFeature
// --------------------------------- // ---------------------------------
@ -63,10 +63,7 @@ class ArangoEngine final : public StorageEngine {
// -------------------- // --------------------
// return the name of the storage engine // return the name of the storage engine
char const* typeName() const override { return "arango"; } char const* typeName() const override { return EngineName.c_str(); }
// return the version string of the storage engine
char const* versionString() const override { return "arango-0.0.1"; }
// inventory functionality // inventory functionality
// ----------------------- // -----------------------
@ -194,6 +191,9 @@ class ArangoEngine final : public StorageEngine {
// from the storage engine's realm // from the storage engine's realm
void removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, void removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
arangodb::velocypack::Slice const& document) override; arangodb::velocypack::Slice const& document) override;
public:
static std::string const EngineName;
}; };
} }

View File

@ -21,57 +21,59 @@
/// @author Jan Steemann /// @author Jan Steemann
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "ArangoEngine.h" #include "OtherEngine.h"
using namespace arangodb; using namespace arangodb;
std::string const OtherEngine::EngineName("other");
// create the storage engine // create the storage engine
ArangoEngine::ArangoEngine(application_features::ApplicationServer* server) OtherEngine::OtherEngine(application_features::ApplicationServer* server)
: StorageEngine(server, "ArangoEngine") { : StorageEngine(server, "otherEngine") {
} }
ArangoEngine::~ArangoEngine() { OtherEngine::~OtherEngine() {
} }
// add the storage engine's specifc options to the global list of options // add the storage engine's specifc options to the global list of options
void ArangoEngine::collectOptions(std::shared_ptr<options::ProgramOptions>) { void OtherEngine::collectOptions(std::shared_ptr<options::ProgramOptions>) {
} }
// validate the storage engine's specific options // validate the storage engine's specific options
void ArangoEngine::validateOptions(std::shared_ptr<options::ProgramOptions>) { void OtherEngine::validateOptions(std::shared_ptr<options::ProgramOptions>) {
} }
// preparation phase for storage engine. can be used for internal setup. // preparation phase for storage engine. can be used for internal setup.
// the storage engine must not start any threads here or write any files // the storage engine must not start any threads here or write any files
void ArangoEngine::prepare() { void OtherEngine::prepare() {
} }
// start the engine. now it's allowed to start engine-specific threads, // start the engine. now it's allowed to start engine-specific threads,
// write files etc. // write files etc.
void ArangoEngine::start() { void OtherEngine::start() {
} }
// stop the storage engine. this can be used to flush all data to disk, // stop the storage engine. this can be used to flush all data to disk,
// shutdown threads etc. it is guaranteed that there will be no read and // shutdown threads etc. it is guaranteed that there will be no read and
// write requests to the storage engine after this call // write requests to the storage engine after this call
void ArangoEngine::stop() { void OtherEngine::stop() {
} }
// fill the Builder object with an array of databases that were detected // fill the Builder object with an array of databases that were detected
// by the storage engine. this method must sort out databases that were not // by the storage engine. this method must sort out databases that were not
// fully created (see "createDatabase" below). called at server start only // fully created (see "createDatabase" below). called at server start only
void ArangoEngine::getDatabases(arangodb::velocypack::Builder& result) { void OtherEngine::getDatabases(arangodb::velocypack::Builder& result) {
} }
// fill the Builder object with an array of collections (and their corresponding // fill the Builder object with an array of collections (and their corresponding
// indexes) that were detected by the storage engine. called at server start only // indexes) that were detected by the storage engine. called at server start only
void ArangoEngine::getCollectionsAndIndexes(arangodb::velocypack::Builder& result) { void OtherEngine::getCollectionsAndIndexes(arangodb::velocypack::Builder& result) {
} }
// determine the maximum revision id previously handed out by the storage // determine the maximum revision id previously handed out by the storage
// engine. this value is used as a lower bound for further HLC values handed out by // engine. this value is used as a lower bound for further HLC values handed out by
// the server. called at server start only, after getDatabases() and getCollectionsAndIndexes() // the server. called at server start only, after getDatabases() and getCollectionsAndIndexes()
uint64_t ArangoEngine::getMaxRevision() { uint64_t OtherEngine::getMaxRevision() {
return 0; // TODO return 0; // TODO
} }
@ -83,7 +85,7 @@ uint64_t ArangoEngine::getMaxRevision() {
// so that subsequent database creation requests will not fail. // so that subsequent database creation requests will not fail.
// the WAL entry for the database creation will be written *after* the call // the WAL entry for the database creation will be written *after* the call
// to "createDatabase" returns // to "createDatabase" returns
void ArangoEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) { void OtherEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) {
} }
// asks the storage engine to drop the specified database and persist the // asks the storage engine to drop the specified database and persist the
@ -95,7 +97,7 @@ void ArangoEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice
// check whether the physical deletion of the database is possible. // check whether the physical deletion of the database is possible.
// the WAL entry for database deletion will be written *after* the call // the WAL entry for database deletion will be written *after* the call
// to "dropDatabase" returns // to "dropDatabase" returns
void ArangoEngine::dropDatabase(TRI_voc_tick_t id, std::function<bool()> const& canRemovePhysically) { void OtherEngine::dropDatabase(TRI_voc_tick_t id, std::function<bool()> const& canRemovePhysically) {
} }
// asks the storage engine to create a collection as specified in the VPack // asks the storage engine to create a collection as specified in the VPack
@ -106,8 +108,8 @@ void ArangoEngine::dropDatabase(TRI_voc_tick_t id, std::function<bool()> const&
// and throw only then, so that subsequent collection creation requests will not fail. // and throw only then, so that subsequent collection creation requests will not fail.
// the WAL entry for the collection creation will be written *after* the call // the WAL entry for the collection creation will be written *after* the call
// to "createCollection" returns // to "createCollection" returns
void ArangoEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, void OtherEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) { arangodb::velocypack::Slice const& data) {
} }
// asks the storage engine to drop the specified collection and persist the // asks the storage engine to drop the specified collection and persist the
@ -118,8 +120,8 @@ void ArangoEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
// the actual deletion. // the actual deletion.
// the WAL entry for collection deletion will be written *after* the call // the WAL entry for collection deletion will be written *after* the call
// to "dropCollection" returns // to "dropCollection" returns
void ArangoEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, void OtherEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
std::function<bool()> const& canRemovePhysically) { std::function<bool()> const& canRemovePhysically) {
} }
// asks the storage engine to rename the collection as specified in the VPack // asks the storage engine to rename the collection as specified in the VPack
@ -130,8 +132,8 @@ void ArangoEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
// and throw only then, so that subsequent collection creation/rename requests will // and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call // not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns // to "renameCollection" returns
void ArangoEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, void OtherEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) { arangodb::velocypack::Slice const& data) {
} }
// asks the storage engine to change properties of the collection as specified in // asks the storage engine to change properties of the collection as specified in
@ -140,8 +142,8 @@ void ArangoEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
// property changes and throw only then, so that subsequent operations will not fail. // property changes and throw only then, so that subsequent operations will not fail.
// the WAL entry for the propery change will be written *after* the call // the WAL entry for the propery change will be written *after* the call
// to "changeCollection" returns // to "changeCollection" returns
void ArangoEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, void OtherEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) { arangodb::velocypack::Slice const& data) {
} }
// asks the storage engine to create an index as specified in the VPack // asks the storage engine to create an index as specified in the VPack
@ -153,8 +155,8 @@ void ArangoEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
// creation requests will not fail. // creation requests will not fail.
// the WAL entry for the index creation will be written *after* the call // the WAL entry for the index creation will be written *after* the call
// to "createIndex" returns // to "createIndex" returns
void ArangoEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, void OtherEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) { TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) {
} }
// asks the storage engine to drop the specified index and persist the deletion // asks the storage engine to drop the specified index and persist the deletion
@ -164,28 +166,28 @@ void ArangoEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collecti
// the actual deletion. // the actual deletion.
// the WAL entry for index deletion will be written *after* the call // the WAL entry for index deletion will be written *after* the call
// to "dropIndex" returns // to "dropIndex" returns
void ArangoEngine::dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, void OtherEngine::dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
TRI_idx_iid_t id) { TRI_idx_iid_t id) {
} }
// iterate all documents of the underlying collection // iterate all documents of the underlying collection
// this is called when a collection is openend, and all its documents need to be added to // this is called when a collection is openend, and all its documents need to be added to
// indexes etc. // indexes etc.
void ArangoEngine::iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, void OtherEngine::iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
std::function<void(arangodb::velocypack::Slice const&)> const& cb) { std::function<void(arangodb::velocypack::Slice const&)> const& cb) {
} }
// adds a document to the storage engine // adds a document to the storage engine
// this will be called by the WAL collector when surviving documents are being moved // this will be called by the WAL collector when surviving documents are being moved
// into the storage engine's realm // into the storage engine's realm
void ArangoEngine::addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, void OtherEngine::addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
arangodb::velocypack::Slice const& document) { arangodb::velocypack::Slice const& document) {
} }
// removes a document from the storage engine // removes a document from the storage engine
// this will be called by the WAL collector when non-surviving documents are being removed // this will be called by the WAL collector when non-surviving documents are being removed
// from the storage engine's realm // from the storage engine's realm
void ArangoEngine::removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, void OtherEngine::removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
arangodb::velocypack::Slice const& document) { arangodb::velocypack::Slice const& document) {
} }

View File

@ -0,0 +1,201 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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 ARANGOD_STORAGE_ENGINE_OTHER_ENGINE_H
#define ARANGOD_STORAGE_ENGINE_OTHER_ENGINE_H 1
#include "Basics/Common.h"
#include "StorageEngine/StorageEngine.h"
namespace arangodb {
class OtherEngine final : public StorageEngine {
public:
// create the storage engine
explicit OtherEngine(application_features::ApplicationServer*);
~OtherEngine();
// inherited from ApplicationFeature
// ---------------------------------
// add the storage engine's specifc options to the global list of options
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
// validate the storage engine's specific options
void validateOptions(std::shared_ptr<options::ProgramOptions>) override;
// preparation phase for storage engine. can be used for internal setup.
// the storage engine must not start any threads here or write any files
void prepare() override;
// start the engine. now it's allowed to start engine-specific threads,
// write files etc.
void start() override;
// stop the storage engine. this can be used to flush all data to disk,
// shutdown threads etc. it is guaranteed that there will be no read and
// write requests to the storage engine after this call
void stop() override;
// status functionality
// --------------------
// return the name of the storage engine
char const* typeName() const override { return EngineName.c_str(); }
// inventory functionality
// -----------------------
// fill the Builder object with an array of databases that were detected
// by the storage engine. this method must sort out databases that were not
// fully created (see "createDatabase" below). called at server start only
void getDatabases(arangodb::velocypack::Builder& result) override;
// fill the Builder object with an array of collections (and their corresponding
// indexes) that were detected by the storage engine. called at server start only
void getCollectionsAndIndexes(arangodb::velocypack::Builder& result) override;
// determine the maximum revision id previously handed out by the storage
// engine. this value is used as a lower bound for further HLC values handed out by
// the server. called at server start only, after getDatabases() and getCollectionsAndIndexes()
uint64_t getMaxRevision() override;
// database, collection and index management
// -----------------------------------------
// asks the storage engine to create a database as specified in the VPack
// Slice object and persist the creation info. It is guaranteed by the server that
// no other active database with the same name and id exists when this function
// is called. If this operation fails somewhere in the middle, the storage
// engine is required to fully clean up the creation and throw only then,
// so that subsequent database creation requests will not fail.
// the WAL entry for the database creation will be written *after* the call
// to "createDatabase" returns
void createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) override;
// asks the storage engine to drop the specified database and persist the
// deletion info. Note that physical deletion of the database data must not
// be carried out by this call, as there may
// still be readers of the database's data. It is recommended that this operation
// only sets a deletion flag for the database but let's an async task perform
// the actual deletion. The async task can later call the callback function to
// check whether the physical deletion of the database is possible.
// the WAL entry for database deletion will be written *after* the call
// to "dropDatabase" returns
void dropDatabase(TRI_voc_tick_t id, std::function<bool()> const& canRemovePhysically) override;
// asks the storage engine to create a collection as specified in the VPack
// Slice object and persist the creation info. It is guaranteed by the server
// that no other active collection with the same name and id exists in the same
// database when this function is called. If this operation fails somewhere in
// the middle, the storage engine is required to fully clean up the creation
// and throw only then, so that subsequent collection creation requests will not fail.
// the WAL entry for the collection creation will be written *after* the call
// to "createCollection" returns
void createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) override;
// asks the storage engine to drop the specified collection and persist the
// deletion info. Note that physical deletion of the collection data must not
// be carried out by this call, as there may
// still be readers of the collection's data. It is recommended that this operation
// only sets a deletion flag for the collection but let's an async task perform
// the actual deletion.
// the WAL entry for collection deletion will be written *after* the call
// to "dropCollection" returns
void dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
std::function<bool()> const& canRemovePhysically) override;
// asks the storage engine to rename the collection as specified in the VPack
// Slice object and persist the renaming info. It is guaranteed by the server
// that no other active collection with the same name and id exists in the same
// database when this function is called. If this operation fails somewhere in
// the middle, the storage engine is required to fully revert the rename operation
// and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns
void renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) override;
// asks the storage engine to change properties of the collection as specified in
// the VPack Slice object and persist them. If this operation fails
// somewhere in the middle, the storage engine is required to fully revert the
// property changes and throw only then, so that subsequent operations will not fail.
// the WAL entry for the propery change will be written *after* the call
// to "changeCollection" returns
void changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) override;
// asks the storage engine to create an index as specified in the VPack
// Slice object and persist the creation info. The database id, collection id
// and index data are passed in the Slice object. Note that this function
// is not responsible for inserting the individual documents into the index.
// If this operation fails somewhere in the middle, the storage engine is required
// to fully clean up the creation and throw only then, so that subsequent index
// creation requests will not fail.
// the WAL entry for the index creation will be written *after* the call
// to "createIndex" returns
void createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) override;
// asks the storage engine to drop the specified index and persist the deletion
// info. Note that physical deletion of the index must not be carried out by this call,
// as there may still be users of the index. It is recommended that this operation
// only sets a deletion flag for the index but let's an async task perform
// the actual deletion.
// the WAL entry for index deletion will be written *after* the call
// to "dropIndex" returns
void dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
TRI_idx_iid_t id) override;
// document operations
// -------------------
// iterate all documents of the underlying collection
// this is called when a collection is openend, and all its documents need to be added to
// indexes etc.
void iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
std::function<void(arangodb::velocypack::Slice const&)> const& cb) override;
// adds a document to the storage engine
// this will be called by the WAL collector when surviving documents are being moved
// into the storage engine's realm
void addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
arangodb::velocypack::Slice const& document) override;
// removes a document from the storage engine
// this will be called by the WAL collector when non-surviving documents are being removed
// from the storage engine's realm
void removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
arangodb::velocypack::Slice const& document) override;
public:
static std::string const EngineName;
};
}
#endif

View File

@ -45,8 +45,8 @@ class StorageEngine : public application_features::ApplicationFeature {
setOptional(true); setOptional(true);
// storage engines must not use elevated privileges for files etc // storage engines must not use elevated privileges for files etc
requiresElevatedPrivileges(false); requiresElevatedPrivileges(false);
// TODO: determine sensible startup order for storage engine // TODO: determine more sensible startup order for storage engine
startsAfter("Logger"); startsAfter("EngineSelector");
} }
// status functionality // status functionality
@ -55,9 +55,6 @@ class StorageEngine : public application_features::ApplicationFeature {
// return the name of the storage engine // return the name of the storage engine
virtual char const* typeName() const = 0; virtual char const* typeName() const = 0;
// return the version string of the storage engine
virtual char const* versionString() const = 0;
// inventory functionality // inventory functionality
// ----------------------- // -----------------------