summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@10gen.com>2018-12-20 11:06:04 -0500
committerDianna Hohensee <dianna.hohensee@10gen.com>2019-01-22 21:44:13 -0500
commitb89d1cb056f82af22a5bef211bd2680f3784e7c2 (patch)
tree52f4b91a50c351e250f9d61b93e635c6ebabd508 /src
parentaa0d93a714f84bf6a29b42390cc51c79963cf725 (diff)
downloadmongo-b89d1cb056f82af22a5bef211bd2680f3784e7c2.tar.gz
SERVER-39066 Add OpObservers and oplog handling for startIndexBuild and commitIndexBuild
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/auth/auth_op_observer.h19
-rw-r--r--src/mongo/db/catalog/uuid_catalog.h20
-rw-r--r--src/mongo/db/free_mon/free_mon_op_observer.h19
-rw-r--r--src/mongo/db/index_builds_coordinator.h9
-rw-r--r--src/mongo/db/index_builds_coordinator_mongod.cpp7
-rw-r--r--src/mongo/db/index_builds_coordinator_mongod.h7
-rw-r--r--src/mongo/db/op_observer.h21
-rw-r--r--src/mongo/db/op_observer_impl.cpp81
-rw-r--r--src/mongo/db/op_observer_impl.h20
-rw-r--r--src/mongo/db/op_observer_impl_test.cpp84
-rw-r--r--src/mongo/db/op_observer_noop.h20
-rw-r--r--src/mongo/db/op_observer_registry.h34
-rw-r--r--src/mongo/db/repl/oplog.cpp167
-rw-r--r--src/mongo/db/s/config_server_op_observer.h19
-rw-r--r--src/mongo/db/s/shard_server_op_observer.h19
-rw-r--r--src/mongo/embedded/index_builds_coordinator_embedded.cpp6
-rw-r--r--src/mongo/embedded/index_builds_coordinator_embedded.h3
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;