diff --git a/arangod/RocksDBEngine/RocksDBCollection.cpp b/arangod/RocksDBEngine/RocksDBCollection.cpp index d1b97c6c8a..689ce19afe 100644 --- a/arangod/RocksDBEngine/RocksDBCollection.cpp +++ b/arangod/RocksDBEngine/RocksDBCollection.cpp @@ -335,29 +335,114 @@ std::shared_ptr RocksDBCollection::createIndex( addIndex(idx); { - bool const doSync = - application_features::ApplicationServer::getFeature( - "Database") - ->forceSyncProperties(); VPackBuilder builder = _logicalCollection->toVelocyPackIgnore( {"path", "statusString"}, true, /*forPersistence*/ false); - auto rtrx = rocksTransaction(trx); - rtrx->PutLogData( - RocksDBLogValue::IndexCreate(_logicalCollection->vocbase()->id(), - _logicalCollection->cid(), info) - .slice()); - _logicalCollection->updateProperties(builder.slice(), doSync); + int res = + static_cast(engine)->writeCreateCollectionMarker( + _logicalCollection->vocbase()->id(), _logicalCollection->cid(), + builder.slice(), + RocksDBLogValue::IndexCreate(_logicalCollection->vocbase()->id(), + _logicalCollection->cid(), info)); + if (res != TRI_ERROR_NO_ERROR) { + // We could not persist the index creation. Better abort + // Remove the Index in the local list again. + size_t i = 0; + // TODO: need to protect _indexes with an RW-lock!! + for (auto index : getIndexes()) { + if (index == idx) { + _indexes.erase(_indexes.begin() + i); + break; + } + ++i; + } + THROW_ARANGO_EXCEPTION(res); + } } created = true; return idx; } /// @brief Restores an index from VelocyPack. -int RocksDBCollection::restoreIndex(transaction::Methods*, - velocypack::Slice const&, - std::shared_ptr&) { - THROW_ARANGO_NOT_YET_IMPLEMENTED(); - return 0; +int RocksDBCollection::restoreIndex(transaction::Methods* trx, + velocypack::Slice const& info, + std::shared_ptr& idx) { + // The coordinator can never get into this state! + TRI_ASSERT(!ServerState::instance()->isCoordinator()); + idx.reset(); // Clear it to make sure. + if (!info.isObject()) { + return TRI_ERROR_INTERNAL; + } + + // We create a new Index object to make sure that the index + // is not handed out except for a successful case. + std::shared_ptr newIdx; + try { + StorageEngine* engine = EngineSelectorFeature::ENGINE; + IndexFactory const* idxFactory = engine->indexFactory(); + TRI_ASSERT(idxFactory != nullptr); + newIdx = idxFactory->prepareIndexFromSlice(info, false, _logicalCollection, + false); + } catch (arangodb::basics::Exception const& e) { + // Something with index creation went wrong. + // Just report. + return e.code(); + } + TRI_ASSERT(newIdx != nullptr); + + + auto const id = newIdx->id(); + + TRI_UpdateTickServer(id); + + for (auto& it : _indexes) { + if (it->id() == id) { + // index already exists + idx = it; + return TRI_ERROR_NO_ERROR; + } + } + + TRI_ASSERT(newIdx.get()->type() != + Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX); + + Result res = fillIndexes(trx, newIdx); + + if (!res.ok()) { + return res.errorNumber(); + } + + addIndex(newIdx); + { + VPackBuilder builder = _logicalCollection->toVelocyPackIgnore( + {"path", "statusString"}, true, /*forPersistence*/ false); + RocksDBEngine* engine = + static_cast(EngineSelectorFeature::ENGINE); + TRI_ASSERT(engine != nullptr); + int res = engine->writeCreateCollectionMarker( + _logicalCollection->vocbase()->id(), _logicalCollection->cid(), + builder.slice(), + RocksDBLogValue::IndexCreate(_logicalCollection->vocbase()->id(), + _logicalCollection->cid(), info)); + if (res != TRI_ERROR_NO_ERROR) { + // We could not persist the index creation. Better abort + // Remove the Index in the local list again. + size_t i = 0; + // TODO: need to protect _indexes with an RW-lock!! + for (auto index : getIndexes()) { + if (index == newIdx) { + _indexes.erase(_indexes.begin() + i); + break; + } + ++i; + } + return res; + } + } + + idx = newIdx; + // We need to write the IndexMarker + + return TRI_ERROR_NO_ERROR; } /// @brief Drop an index with the given iid. diff --git a/arangod/RocksDBEngine/RocksDBEngine.cpp b/arangod/RocksDBEngine/RocksDBEngine.cpp index 5067e9c99a..3ba7ae361a 100644 --- a/arangod/RocksDBEngine/RocksDBEngine.cpp +++ b/arangod/RocksDBEngine/RocksDBEngine.cpp @@ -380,13 +380,19 @@ void RocksDBEngine::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid, // dump index information VPackSlice indexes = fullParameters.get("indexes"); builder.add(VPackValue("indexes")); + builder.openArray(); if (indexes.isArray()) { - builder.add(indexes); - } else { - // Insert an empty array instead - builder.openArray(); - builder.close(); + for (auto const idx : VPackArrayIterator(indexes)) { + // This is only allowed to contain user-defined indexes. + // So we have to exclude Primary + Edge Types + VPackSlice type = idx.get("type"); + TRI_ASSERT(type.isString()); + if (!type.isEqualString("primary") && !type.isEqualString("edge")) { + builder.add(idx); + } + } } + builder.close(); } builder.close(); diff --git a/arangod/RocksDBEngine/RocksDBIndexFactory.cpp b/arangod/RocksDBEngine/RocksDBIndexFactory.cpp index 3a49cc6215..1f3b253fba 100644 --- a/arangod/RocksDBEngine/RocksDBIndexFactory.cpp +++ b/arangod/RocksDBEngine/RocksDBIndexFactory.cpp @@ -355,6 +355,9 @@ std::shared_ptr RocksDBIndexFactory::prepareIndexFromSlice( } if (iid == 0 && !isClusterConstructor) { + if (!generateKey) { + LOG_TOPIC(ERR, arangodb::Logger::FIXME) << info.toJson(); + } // Restore is not allowed to generate an id TRI_ASSERT(generateKey); iid = arangodb::Index::generateId(); diff --git a/arangod/RocksDBEngine/RocksDBReplicationContext.cpp b/arangod/RocksDBEngine/RocksDBReplicationContext.cpp index c0ae60ec4d..08f5117257 100644 --- a/arangod/RocksDBEngine/RocksDBReplicationContext.cpp +++ b/arangod/RocksDBEngine/RocksDBReplicationContext.cpp @@ -26,6 +26,7 @@ #include "Basics/StringBuffer.h" #include "Basics/StringRef.h" #include "Basics/VPackStringBufferAdapter.h" +#include "VocBase/replication-common.h" #include "RocksDBEngine/RocksDBCollection.h" #include "RocksDBEngine/RocksDBCommon.h" #include "RocksDBEngine/RocksDBPrimaryIndex.h" @@ -140,10 +141,7 @@ RocksDBReplicationResult RocksDBReplicationContext::dump( } // set type - int type = 2300; // documents - if (_collection->type() == TRI_COL_TYPE_EDGE) { - type = 2301; // edge documents - } + int type = REPLICATION_MARKER_DOCUMENT; // documents arangodb::basics::VPackStringBufferAdapter adapter(buff.stringBuffer()); @@ -167,8 +165,9 @@ RocksDBReplicationResult RocksDBReplicationContext::dump( } builder.add(VPackValue("data")); + auto key = VPackSlice(_mdr.vpack()).get(StaticStrings::KeyString); _mdr.addToBuilder(builder, false); - builder.add("key", builder.slice().get(StaticStrings::KeyString)); + builder.add("key", key); builder.close(); VPackDumper dumper( diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e74a696f42..19ea30b286 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,7 +59,6 @@ add_executable( target_link_libraries( arangodbtests arangoserver - rocksdblib ) target_include_directories(arangodbtests PRIVATE