diff options
author | Dianna Hohensee <dianna.hohensee@10gen.com> | 2018-12-20 11:06:04 -0500 |
---|---|---|
committer | Dianna Hohensee <dianna.hohensee@10gen.com> | 2019-01-22 21:44:13 -0500 |
commit | b89d1cb056f82af22a5bef211bd2680f3784e7c2 (patch) | |
tree | 52f4b91a50c351e250f9d61b93e635c6ebabd508 /src | |
parent | aa0d93a714f84bf6a29b42390cc51c79963cf725 (diff) | |
download | mongo-b89d1cb056f82af22a5bef211bd2680f3784e7c2.tar.gz |
SERVER-39066 Add OpObservers and oplog handling for startIndexBuild and commitIndexBuild
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_op_observer.h | 19 | ||||
-rw-r--r-- | src/mongo/db/catalog/uuid_catalog.h | 20 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_op_observer.h | 19 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator.h | 9 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator_mongod.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator_mongod.h | 7 | ||||
-rw-r--r-- | src/mongo/db/op_observer.h | 21 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl.cpp | 81 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl.h | 20 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl_test.cpp | 84 | ||||
-rw-r--r-- | src/mongo/db/op_observer_noop.h | 20 | ||||
-rw-r--r-- | src/mongo/db/op_observer_registry.h | 34 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 167 | ||||
-rw-r--r-- | src/mongo/db/s/config_server_op_observer.h | 19 | ||||
-rw-r--r-- | src/mongo/db/s/shard_server_op_observer.h | 19 | ||||
-rw-r--r-- | src/mongo/embedded/index_builds_coordinator_embedded.cpp | 6 | ||||
-rw-r--r-- | src/mongo/embedded/index_builds_coordinator_embedded.h | 3 |
18 files changed, 556 insertions, 0 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index aa53f6d31d7..b3c8b2ab9a4 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -986,6 +986,7 @@ env.Library( LIBDEPS=[ 'db_raii', 'index/index_access_methods', + '$BUILD_DIR/mongo/db/index_builds_coordinator_interface', '$BUILD_DIR/mongo/db/catalog/index_catalog', '$BUILD_DIR/mongo/db/catalog/multi_index_block', ], diff --git a/src/mongo/db/auth/auth_op_observer.h b/src/mongo/db/auth/auth_op_observer.h index 28646565929..ea4e6430c95 100644 --- a/src/mongo/db/auth/auth_op_observer.h +++ b/src/mongo/db/auth/auth_op_observer.h @@ -51,6 +51,25 @@ public: BSONObj indexDoc, bool fromMigrate) final {} + void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) final {} + + void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) final {} + + void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) final {} + void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/catalog/uuid_catalog.h b/src/mongo/db/catalog/uuid_catalog.h index ec0adbdae7e..8e6a72114fe 100644 --- a/src/mongo/db/catalog/uuid_catalog.h +++ b/src/mongo/db/catalog/uuid_catalog.h @@ -50,6 +50,26 @@ public: CollectionUUID uuid, BSONObj indexDoc, bool fromMigrate) override {} + + void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) override {} + void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/free_mon/free_mon_op_observer.h b/src/mongo/db/free_mon/free_mon_op_observer.h index be29495b4ef..2b52ce4fe34 100644 --- a/src/mongo/db/free_mon/free_mon_op_observer.h +++ b/src/mongo/db/free_mon/free_mon_op_observer.h @@ -52,6 +52,25 @@ public: BSONObj indexDoc, bool fromMigrate) final {} + void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) final {} + + void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) final {} + + void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) final {} + void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h index d7e90547e11..d61f4c946db 100644 --- a/src/mongo/db/index_builds_coordinator.h +++ b/src/mongo/db/index_builds_coordinator.h @@ -109,6 +109,15 @@ public: const std::vector<BSONObj>& indexSpecs); /** + * Commits the index build identified by 'buildUUID'. + * + * TODO: not yet implemented. + */ + virtual Status commitIndexBuild(OperationContext* opCtx, + const std::vector<BSONObj>& specs, + const UUID& buildUUID) = 0; + + /** * Signals all the index builds to stop and then waits for them to finish. Leaves the index * builds in a recoverable state. * diff --git a/src/mongo/db/index_builds_coordinator_mongod.cpp b/src/mongo/db/index_builds_coordinator_mongod.cpp index d74647a5dae..38418ef8f67 100644 --- a/src/mongo/db/index_builds_coordinator_mongod.cpp +++ b/src/mongo/db/index_builds_coordinator_mongod.cpp @@ -127,6 +127,13 @@ IndexBuildsCoordinatorMongod::buildIndex(OperationContext* opCtx, return replIndexBuildState->sharedPromise.getFuture(); } +Status IndexBuildsCoordinatorMongod::commitIndexBuild(OperationContext* opCtx, + const std::vector<BSONObj>& specs, + const UUID& buildUUID) { + // TODO: not yet implemented. + return Status::OK(); +} + void IndexBuildsCoordinatorMongod::signalChangeToPrimaryMode() { stdx::unique_lock<stdx::mutex> lk(_mutex); _replMode = ReplState::Primary; diff --git a/src/mongo/db/index_builds_coordinator_mongod.h b/src/mongo/db/index_builds_coordinator_mongod.h index a3fc80d90a7..15f4995d1c5 100644 --- a/src/mongo/db/index_builds_coordinator_mongod.h +++ b/src/mongo/db/index_builds_coordinator_mongod.h @@ -75,6 +75,13 @@ public: const std::vector<BSONObj>& specs, const UUID& buildUUID) override; + /** + * TODO: not yet implemented. + */ + Status commitIndexBuild(OperationContext* opCtx, + const std::vector<BSONObj>& specs, + const UUID& buildUUID) override; + void signalChangeToPrimaryMode() override; void signalChangeToSecondaryMode() override; void signalChangeToInitialSyncMode() override; diff --git a/src/mongo/db/op_observer.h b/src/mongo/db/op_observer.h index 91c66abb603..ef1fb9903e3 100644 --- a/src/mongo/db/op_observer.h +++ b/src/mongo/db/op_observer.h @@ -90,11 +90,32 @@ public: }; virtual ~OpObserver() = default; + virtual void onCreateIndex(OperationContext* opCtx, const NamespaceString& nss, CollectionUUID uuid, BSONObj indexDoc, bool fromMigrate) = 0; + + virtual void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) = 0; + + virtual void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) = 0; + + virtual void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) = 0; + virtual void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index 34709f9bc19..3a6f75eba1f 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -360,6 +360,87 @@ void OpObserverImpl::onCreateIndex(OperationContext* opCtx, OplogSlot()); } +void OpObserverImpl::onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) { + BSONObjBuilder oplogEntryBuilder; + oplogEntryBuilder.append("startIndexBuild", nss.coll()); + + indexBuildUUID.appendToBuilder(&oplogEntryBuilder, "indexBuildUUID"); + + BSONArrayBuilder indexesArr(oplogEntryBuilder.subarrayStart("indexes")); + for (auto indexDoc : indexes) { + BSONObjBuilder builder; + for (const auto& e : indexDoc) { + if (e.fieldNameStringData() != "ns"_sd) + builder.append(e); + } + indexesArr.append(builder.obj()); + } + indexesArr.done(); + + logOperation(opCtx, + "c", + nss.getCommandNS(), + collUUID, + oplogEntryBuilder.done(), + nullptr, + fromMigrate, + getWallClockTimeForOpLog(opCtx), + {}, + kUninitializedStmtId, + {}, + false /* prepare */, + OplogSlot()); +} + +void OpObserverImpl::onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) { + BSONObjBuilder oplogEntryBuilder; + oplogEntryBuilder.append("commitIndexBuild", nss.coll()); + + indexBuildUUID.appendToBuilder(&oplogEntryBuilder, "indexBuildUUID"); + + BSONArrayBuilder indexesArr(oplogEntryBuilder.subarrayStart("indexes")); + for (auto indexDoc : indexes) { + BSONObjBuilder builder; + for (const auto& e : indexDoc) { + if (e.fieldNameStringData() != "ns"_sd) + builder.append(e); + } + indexesArr.append(builder.obj()); + } + indexesArr.done(); + + logOperation(opCtx, + "c", + nss.getCommandNS(), + collUUID, + oplogEntryBuilder.done(), + nullptr, + fromMigrate, + getWallClockTimeForOpLog(opCtx), + {}, + kUninitializedStmtId, + {}, + false /* prepare */, + OplogSlot()); +} + +void OpObserverImpl::onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) { + // TODO (SERVER-39067): Not yet implemented. +} + void OpObserverImpl::onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/op_observer_impl.h b/src/mongo/db/op_observer_impl.h index 989b7d8075e..fb1b6bd5264 100644 --- a/src/mongo/db/op_observer_impl.h +++ b/src/mongo/db/op_observer_impl.h @@ -46,6 +46,26 @@ public: CollectionUUID uuid, BSONObj indexDoc, bool fromMigrate) final; + + void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) final; + + void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) final; + + void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) final; + void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/op_observer_impl_test.cpp b/src/mongo/db/op_observer_impl_test.cpp index c8bd4509843..6d2af2aee90 100644 --- a/src/mongo/db/op_observer_impl_test.cpp +++ b/src/mongo/db/op_observer_impl_test.cpp @@ -101,6 +101,90 @@ private: } }; +TEST_F(OpObserverTest, StartIndexBuildExpectedOplogEntry) { + OpObserverImpl opObserver; + auto opCtx = cc().makeOperationContext(); + auto uuid = CollectionUUID::gen(); + NamespaceString nss("test.coll"); + UUID indexBuildUUID = UUID::gen(); + + BSONObj specX = BSON("key" << BSON("x" << 1) << "name" + << "x_1" + << "v" + << 2); + BSONObj specA = BSON("key" << BSON("a" << 1) << "name" + << "a_1" + << "v" + << 2); + std::vector<BSONObj> specs = {specX, specA}; + + // Write to the oplog. + { + AutoGetDb autoDb(opCtx.get(), nss.db(), MODE_X); + WriteUnitOfWork wunit(opCtx.get()); + opObserver.onStartIndexBuild( + opCtx.get(), nss, uuid, indexBuildUUID, specs, false /*fromMigrate*/); + wunit.commit(); + } + + // Create expected startIndexBuild command. + BSONObjBuilder startIndexBuildBuilder; + startIndexBuildBuilder.append("startIndexBuild", nss.coll()); + indexBuildUUID.appendToBuilder(&startIndexBuildBuilder, "indexBuildUUID"); + BSONArrayBuilder indexesArr(startIndexBuildBuilder.subarrayStart("indexes")); + indexesArr.append(specX); + indexesArr.append(specA); + indexesArr.done(); + BSONObj startIndexBuildCmd = startIndexBuildBuilder.done(); + + // Ensure the startIndexBuild fields were correctly set. + auto oplogEntry = getSingleOplogEntry(opCtx.get()); + auto o = oplogEntry.getObjectField("o"); + ASSERT_BSONOBJ_EQ(startIndexBuildCmd, o); +} + +TEST_F(OpObserverTest, CommitIndexBuildExpectedOplogEntry) { + OpObserverImpl opObserver; + auto opCtx = cc().makeOperationContext(); + auto uuid = CollectionUUID::gen(); + NamespaceString nss("test.coll"); + UUID indexBuildUUID = UUID::gen(); + + BSONObj specX = BSON("key" << BSON("x" << 1) << "name" + << "x_1" + << "v" + << 2); + BSONObj specA = BSON("key" << BSON("a" << 1) << "name" + << "a_1" + << "v" + << 2); + std::vector<BSONObj> specs = {specX, specA}; + + // Write to the oplog. + { + AutoGetDb autoDb(opCtx.get(), nss.db(), MODE_X); + WriteUnitOfWork wunit(opCtx.get()); + opObserver.onCommitIndexBuild( + opCtx.get(), nss, uuid, indexBuildUUID, specs, false /*fromMigrate*/); + wunit.commit(); + } + + // Create expected commitIndexBuild command. + BSONObjBuilder commitIndexBuildBuilder; + commitIndexBuildBuilder.append("commitIndexBuild", nss.coll()); + indexBuildUUID.appendToBuilder(&commitIndexBuildBuilder, "indexBuildUUID"); + BSONArrayBuilder indexesArr(commitIndexBuildBuilder.subarrayStart("indexes")); + indexesArr.append(specX); + indexesArr.append(specA); + indexesArr.done(); + BSONObj commitIndexBuildCmd = commitIndexBuildBuilder.done(); + + // Ensure the commitIndexBuild fields were correctly set. + auto oplogEntry = getSingleOplogEntry(opCtx.get()); + auto o = oplogEntry.getObjectField("o"); + ASSERT_BSONOBJ_EQ(commitIndexBuildCmd, o); +} + TEST_F(OpObserverTest, CollModWithCollectionOptionsAndTTLInfo) { OpObserverImpl opObserver; auto opCtx = cc().makeOperationContext(); diff --git a/src/mongo/db/op_observer_noop.h b/src/mongo/db/op_observer_noop.h index 469043de57f..951389c1c5c 100644 --- a/src/mongo/db/op_observer_noop.h +++ b/src/mongo/db/op_observer_noop.h @@ -41,6 +41,26 @@ public: CollectionUUID uuid, BSONObj indexDoc, bool fromMigrate) override {} + + void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) override {} + void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/op_observer_registry.h b/src/mongo/db/op_observer_registry.h index c64537f5104..a9630eafb42 100644 --- a/src/mongo/db/op_observer_registry.h +++ b/src/mongo/db/op_observer_registry.h @@ -68,6 +68,40 @@ public: o->onCreateIndex(opCtx, nss, uuid, indexDoc, fromMigrate); } + virtual void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override { + ReservedTimes times{opCtx}; + for (auto& o : _observers) { + o->onStartIndexBuild(opCtx, nss, collUUID, indexBuildUUID, indexes, fromMigrate); + } + } + + virtual void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override { + ReservedTimes times{opCtx}; + for (auto& o : _observers) { + o->onCommitIndexBuild(opCtx, nss, collUUID, indexBuildUUID, indexes, fromMigrate); + } + } + + virtual void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) override { + ReservedTimes times{opCtx}; + for (auto& o : _observers) { + o->onAbortIndexBuild(opCtx, collUUID, indexInfo, fromMigrate); + } + } + void onInserts(OperationContext* const opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 03bc09fd04b..6eac921e114 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -65,6 +65,7 @@ #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index_builder.h" +#include "mongo/db/index_builds_coordinator.h" #include "mongo/db/keypattern.h" #include "mongo/db/logical_clock.h" #include "mongo/db/logical_time.h" @@ -256,6 +257,52 @@ void setOplogCollectionName(ServiceContext* service) { } } +/** + * Parse the given BSON array of BSON into a vector of BSON. + */ +StatusWith<std::vector<BSONObj>> parseBSONArrayIntoVector(const BSONElement& bsonArrayElem) { + invariant(bsonArrayElem.type() == Array); + std::vector<BSONObj> vec; + for (auto& bsonElem : bsonArrayElem.Obj()) { + if (bsonElem.type() != BSONType::Object) { + return {ErrorCodes::TypeMismatch, + str::stream() << "The elements of '" << bsonArrayElem.fieldName() + << "' array must be objects, but found " + << typeName(bsonElem.type())}; + } + BSONObjBuilder builder; + builder.append(bsonElem); + vec.emplace_back(builder.obj()); + } + return vec; +} + +Status startIndexBuild(OperationContext* opCtx, + const UUID& collUUID, + const UUID& indexBuildUUID, + const BSONElement& indexesElem, + OplogApplication::Mode mode) { + auto statusWithIndexes = parseBSONArrayIntoVector(indexesElem); + if (!statusWithIndexes.isOK()) { + return statusWithIndexes.getStatus(); + } + return IndexBuildsCoordinator::get(opCtx) + ->buildIndex(opCtx, collUUID, statusWithIndexes.getValue(), indexBuildUUID) + .getStatus(); +} + +Status commitIndexBuild(OperationContext* opCtx, + const UUID& indexBuildUUID, + const BSONElement& indexesElem, + OplogApplication::Mode mode) { + auto statusWithIndexes = parseBSONArrayIntoVector(indexesElem); + if (!statusWithIndexes.isOK()) { + return statusWithIndexes.getStatus(); + } + return IndexBuildsCoordinator::get(opCtx)->commitIndexBuild( + opCtx, statusWithIndexes.getValue(), indexBuildUUID); +} + void createIndexForApplyOps(OperationContext* opCtx, const BSONObj& indexSpec, const NamespaceString& indexNss, @@ -890,6 +937,126 @@ std::map<std::string, ApplyOpMetadata> opsMap = { return Status::OK(); }, {ErrorCodes::IndexAlreadyExists, ErrorCodes::NamespaceNotFound}}}, + {"startIndexBuild", + {[](OperationContext* opCtx, + const char* ns, + const BSONElement& ui, + BSONObj& cmd, + const OpTime& opTime, + const OplogEntry& entry, + OplogApplication::Mode mode) -> Status { + // { + // "startIndexBuild" : "coll", + // "indexBuildUUID" : <UUID>, + // "indexes" : [ + // { + // "key" : { + // "x" : 1 + // }, + // "name" : "x_1", + // "v" : 2 + // }, + // { + // "key" : { + // "k" : 1 + // }, + // "name" : "k_1", + // "v" : 2 + // } + // ] + // } + + // TODO (SERVER-38701): this must do nothing for applyOps. Pivot can be made on 'mode' to + // identify applyOps requests and take no action. + + const NamespaceString nss(parseUUIDorNs(opCtx, ns, ui, cmd)); + + auto buildUUIDElem = cmd.getField("indexBuildUUID"); + uassert(ErrorCodes::BadValue, + "Error parsing 'startIndexBuild' oplog entry, missing required field " + "'indexBuildUUID'.", + buildUUIDElem.eoo()); + UUID indexBuildUUID = uassertStatusOK(UUID::parse(buildUUIDElem)); + + auto indexesElem = cmd.getField("indexes"); + uassert(ErrorCodes::BadValue, + "Error parsing 'startIndexBuild' oplog entry, missing required field 'indexes'.", + indexesElem.eoo()); + uassert(ErrorCodes::BadValue, + "Error parsing 'startIndexBuild' oplog entry, field 'indexes' must be an array.", + indexesElem.type() == Array); + + auto collUUID = uassertStatusOK(UUID::parse(ui)); + + return startIndexBuild(opCtx, collUUID, indexBuildUUID, indexesElem, mode); + }}}, + {"commitIndexBuild", + {[](OperationContext* opCtx, + const char* ns, + const BSONElement& ui, + BSONObj& cmd, + const OpTime& opTime, + const OplogEntry& entry, + OplogApplication::Mode mode) -> Status { + // { + // "commitIndexBuild" : "coll", + // "indexBuildUUID" : <UUID>, + // "indexes" : [ + // { + // "key" : { + // "x" : 1 + // }, + // "name" : "x_1", + // "v" : 2 + // }, + // { + // "key" : { + // "k" : 1 + // }, + // "name" : "k_1", + // "v" : 2 + // } + // ] + // } + + // TODO this must work for applyOps, which doesn't provide collection or build UUIDs. Pivot + // can be made on 'mode' to identify applyOps requests. (SERVER-38701). + + // Ensure the collection name is specified + BSONElement first = cmd.firstElement(); + invariant(first.fieldNameStringData() == "commitIndexBuild"); + uassert(ErrorCodes::InvalidNamespace, + "createIndexes value must be a string", + first.type() == mongo::String); + + auto buildUUIDElem = cmd.getField("indexBuildUUID"); + uassert(ErrorCodes::BadValue, + "Error parsing 'commitIndexBuild' oplog entry, missing required field " + "'indexBuildUUID'.", + buildUUIDElem.eoo()); + UUID indexBuildUUID = uassertStatusOK(UUID::parse(buildUUIDElem)); + + auto indexesElem = cmd.getField("indexes"); + uassert(ErrorCodes::BadValue, + "Error parsing 'commitIndexBuild' oplog entry, missing required field 'indexes'.", + indexesElem.eoo()); + uassert(ErrorCodes::BadValue, + "Error parsing 'commitIndexBuild' oplog entry, field 'indexes' must be an array.", + indexesElem.type() == Array); + + return commitIndexBuild(opCtx, indexBuildUUID, indexesElem, mode); + }}}, + {"abortIndexBuild", + {[](OperationContext* opCtx, + const char* ns, + const BSONElement& ui, + BSONObj& cmd, + const OpTime& opTme, + const OplogEntry& entry, + OplogApplication::Mode mode) -> Status { + // TODO (SERVER-39067): Not yet implemented. + return Status::OK(); + }}}, {"collMod", {[](OperationContext* opCtx, const char* ns, diff --git a/src/mongo/db/s/config_server_op_observer.h b/src/mongo/db/s/config_server_op_observer.h index 3b128534f3d..192e7e091ef 100644 --- a/src/mongo/db/s/config_server_op_observer.h +++ b/src/mongo/db/s/config_server_op_observer.h @@ -52,6 +52,25 @@ public: BSONObj indexDoc, bool fromMigrate) override {} + void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) override {} + void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/db/s/shard_server_op_observer.h b/src/mongo/db/s/shard_server_op_observer.h index 5261851bbb3..0e737cd66d6 100644 --- a/src/mongo/db/s/shard_server_op_observer.h +++ b/src/mongo/db/s/shard_server_op_observer.h @@ -53,6 +53,25 @@ public: BSONObj indexDoc, bool fromMigrate) override {} + void onStartIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onCommitIndexBuild(OperationContext* opCtx, + const NamespaceString& nss, + CollectionUUID collUUID, + const UUID& indexBuildUUID, + const std::vector<BSONObj>& indexes, + bool fromMigrate) override {} + + void onAbortIndexBuild(OperationContext* opCtx, + CollectionUUID collUUID, + const BSONObj& indexInfo, + bool fromMigrate) override {} + void onInserts(OperationContext* opCtx, const NamespaceString& nss, OptionalCollectionUUID uuid, diff --git a/src/mongo/embedded/index_builds_coordinator_embedded.cpp b/src/mongo/embedded/index_builds_coordinator_embedded.cpp index aa161e947e1..12c1dc62487 100644 --- a/src/mongo/embedded/index_builds_coordinator_embedded.cpp +++ b/src/mongo/embedded/index_builds_coordinator_embedded.cpp @@ -73,6 +73,12 @@ IndexBuildsCoordinatorEmbedded::buildIndex(OperationContext* opCtx, return replIndexBuildState->sharedPromise.getFuture(); } +Status IndexBuildsCoordinatorEmbedded::commitIndexBuild(OperationContext* opCtx, + const std::vector<BSONObj>& specs, + const UUID& buildUUID) { + MONGO_UNREACHABLE; +} + void IndexBuildsCoordinatorEmbedded::signalChangeToPrimaryMode() { MONGO_UNREACHABLE; } diff --git a/src/mongo/embedded/index_builds_coordinator_embedded.h b/src/mongo/embedded/index_builds_coordinator_embedded.h index a5d2b9b207a..8b1df3ee0ff 100644 --- a/src/mongo/embedded/index_builds_coordinator_embedded.h +++ b/src/mongo/embedded/index_builds_coordinator_embedded.h @@ -65,6 +65,9 @@ public: /** * None of the following functions should ever be called on an embedded server node. */ + Status commitIndexBuild(OperationContext* opCtx, + const std::vector<BSONObj>& specs, + const UUID& buildUUID) override; void signalChangeToPrimaryMode() override; void signalChangeToSecondaryMode() override; void signalChangeToInitialSyncMode() override; |