summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2019-01-29 16:15:30 -0500
committerGregory Wlodarek <gregory.wlodarek@mongodb.com>2019-02-01 08:59:20 -0500
commitec1a376c2e7203a2aef8c2153f5ec8741dba565e (patch)
treeac212ab2ce0d341318fb8d595873c089d9767814
parentc8a044450030909a0a0f5e07c619d0c2c8418ead (diff)
downloadmongo-ec1a376c2e7203a2aef8c2153f5ec8741dba565e.tar.gz
SERVER-39067 Implement new simultaneous index builds abortIndexBuild oplog entry in OpObserver and oplog.cpp
-rw-r--r--src/mongo/db/auth/auth_op_observer.h4
-rw-r--r--src/mongo/db/catalog/uuid_catalog.h4
-rw-r--r--src/mongo/db/free_mon/free_mon_op_observer.h4
-rw-r--r--src/mongo/db/index_builds_coordinator.cpp4
-rw-r--r--src/mongo/db/index_builds_coordinator.h2
-rw-r--r--src/mongo/db/op_observer.h4
-rw-r--r--src/mongo/db/op_observer_impl.cpp34
-rw-r--r--src/mongo/db/op_observer_impl.h4
-rw-r--r--src/mongo/db/op_observer_impl_test.cpp42
-rw-r--r--src/mongo/db/op_observer_noop.h4
-rw-r--r--src/mongo/db/op_observer_registry.h6
-rw-r--r--src/mongo/db/repl/oplog.cpp60
-rw-r--r--src/mongo/db/s/config_server_op_observer.h4
-rw-r--r--src/mongo/db/s/shard_server_op_observer.h4
14 files changed, 162 insertions, 18 deletions
diff --git a/src/mongo/db/auth/auth_op_observer.h b/src/mongo/db/auth/auth_op_observer.h
index ea4e6430c95..93fd54cc7de 100644
--- a/src/mongo/db/auth/auth_op_observer.h
+++ b/src/mongo/db/auth/auth_op_observer.h
@@ -66,8 +66,10 @@ public:
bool fromMigrate) final {}
void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) final {}
void onInserts(OperationContext* opCtx,
diff --git a/src/mongo/db/catalog/uuid_catalog.h b/src/mongo/db/catalog/uuid_catalog.h
index 8e6a72114fe..e7db04647fe 100644
--- a/src/mongo/db/catalog/uuid_catalog.h
+++ b/src/mongo/db/catalog/uuid_catalog.h
@@ -66,8 +66,10 @@ public:
bool fromMigrate) override {}
void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) override {}
void onInserts(OperationContext* opCtx,
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 2b52ce4fe34..d11fbf00099 100644
--- a/src/mongo/db/free_mon/free_mon_op_observer.h
+++ b/src/mongo/db/free_mon/free_mon_op_observer.h
@@ -67,8 +67,10 @@ public:
bool fromMigrate) final {}
void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) final {}
void onInserts(OperationContext* opCtx,
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp
index d0ccfa9ef41..98ddd272158 100644
--- a/src/mongo/db/index_builds_coordinator.cpp
+++ b/src/mongo/db/index_builds_coordinator.cpp
@@ -176,8 +176,8 @@ Future<void> IndexBuildsCoordinator::abortIndexBuildByName(
return std::move(pf.future);
}
-Future<void> IndexBuildsCoordinator::abortIndexBuildByUUID(const UUID& buildUUID,
- const std::string& reason) {
+Future<void> IndexBuildsCoordinator::abortIndexBuildByBuildUUID(const UUID& buildUUID,
+ const std::string& reason) {
// TODO: not yet implemented. Some code to make it compile.
auto pf = makePromiseFuture<void>();
auto promise = std::move(pf.promise);
diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h
index ec61577268c..ff49ec539cb 100644
--- a/src/mongo/db/index_builds_coordinator.h
+++ b/src/mongo/db/index_builds_coordinator.h
@@ -188,7 +188,7 @@ public:
*
* TODO: This is not yet implemented.
*/
- Future<void> abortIndexBuildByUUID(const UUID& buildUUID, const std::string& reason);
+ Future<void> abortIndexBuildByBuildUUID(const UUID& buildUUID, const std::string& reason);
/**
* Signal replica set member state changes that affect cross replica set index building.
diff --git a/src/mongo/db/op_observer.h b/src/mongo/db/op_observer.h
index ef1fb9903e3..682a6f0311d 100644
--- a/src/mongo/db/op_observer.h
+++ b/src/mongo/db/op_observer.h
@@ -112,8 +112,10 @@ public:
bool fromMigrate) = 0;
virtual void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) = 0;
virtual void onInserts(OperationContext* opCtx,
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp
index 3a6f75eba1f..05820684dbc 100644
--- a/src/mongo/db/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer_impl.cpp
@@ -435,10 +435,40 @@ void OpObserverImpl::onCommitIndexBuild(OperationContext* opCtx,
}
void OpObserverImpl::onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) {
- // TODO (SERVER-39067): Not yet implemented.
+ BSONObjBuilder oplogEntryBuilder;
+ oplogEntryBuilder.append("abortIndexBuild", 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::onInserts(OperationContext* opCtx,
diff --git a/src/mongo/db/op_observer_impl.h b/src/mongo/db/op_observer_impl.h
index fb1b6bd5264..86ced3d6f81 100644
--- a/src/mongo/db/op_observer_impl.h
+++ b/src/mongo/db/op_observer_impl.h
@@ -62,8 +62,10 @@ public:
bool fromMigrate) final;
void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) final;
void onInserts(OperationContext* opCtx,
diff --git a/src/mongo/db/op_observer_impl_test.cpp b/src/mongo/db/op_observer_impl_test.cpp
index 6d2af2aee90..fff623af6ea 100644
--- a/src/mongo/db/op_observer_impl_test.cpp
+++ b/src/mongo/db/op_observer_impl_test.cpp
@@ -185,6 +185,48 @@ TEST_F(OpObserverTest, CommitIndexBuildExpectedOplogEntry) {
ASSERT_BSONOBJ_EQ(commitIndexBuildCmd, o);
}
+TEST_F(OpObserverTest, AbortIndexBuildExpectedOplogEntry) {
+ 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.onAbortIndexBuild(
+ opCtx.get(), nss, uuid, indexBuildUUID, specs, false /*fromMigrate*/);
+ wunit.commit();
+ }
+
+ // Create expected abortIndexBuild command.
+ BSONObjBuilder abortIndexBuildBuilder;
+ abortIndexBuildBuilder.append("abortIndexBuild", nss.coll());
+ indexBuildUUID.appendToBuilder(&abortIndexBuildBuilder, "indexBuildUUID");
+ BSONArrayBuilder indexesArr(abortIndexBuildBuilder.subarrayStart("indexes"));
+ indexesArr.append(specX);
+ indexesArr.append(specA);
+ indexesArr.done();
+ BSONObj abortIndexBuildCmd = abortIndexBuildBuilder.done();
+
+ // Ensure the abortIndexBuild fields were correctly set.
+ auto oplogEntry = getSingleOplogEntry(opCtx.get());
+ auto o = oplogEntry.getObjectField("o");
+ ASSERT_BSONOBJ_EQ(abortIndexBuildCmd, 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 951389c1c5c..3a1ad19e848 100644
--- a/src/mongo/db/op_observer_noop.h
+++ b/src/mongo/db/op_observer_noop.h
@@ -57,8 +57,10 @@ public:
bool fromMigrate) override {}
void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) override {}
void onInserts(OperationContext* opCtx,
diff --git a/src/mongo/db/op_observer_registry.h b/src/mongo/db/op_observer_registry.h
index a9630eafb42..e3cd4b642d7 100644
--- a/src/mongo/db/op_observer_registry.h
+++ b/src/mongo/db/op_observer_registry.h
@@ -93,12 +93,14 @@ public:
}
virtual void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) override {
ReservedTimes times{opCtx};
for (auto& o : _observers) {
- o->onAbortIndexBuild(opCtx, collUUID, indexInfo, fromMigrate);
+ o->onAbortIndexBuild(opCtx, nss, collUUID, indexBuildUUID, indexes, fromMigrate);
}
}
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index e669040ed0a..41b4eaed621 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -303,6 +303,15 @@ Status commitIndexBuild(OperationContext* opCtx,
opCtx, statusWithIndexes.getValue(), indexBuildUUID);
}
+Status abortIndexBuild(OperationContext* opCtx,
+ const UUID& indexBuildUUID,
+ OplogApplication::Mode mode) {
+ // Wait until the index build finishes aborting.
+ Future<void> abort = IndexBuildsCoordinator::get(opCtx)->abortIndexBuildByBuildUUID(
+ indexBuildUUID, "abortIndexBuild oplog entry encountered");
+ return abort.waitNoThrow();
+}
+
void createIndexForApplyOps(OperationContext* opCtx,
const BSONObj& indexSpec,
const NamespaceString& indexNss,
@@ -1026,7 +1035,7 @@ std::map<std::string, ApplyOpMetadata> opsMap = {
BSONElement first = cmd.firstElement();
invariant(first.fieldNameStringData() == "commitIndexBuild");
uassert(ErrorCodes::InvalidNamespace,
- "createIndexes value must be a string",
+ "commitIndexBuild value must be a string",
first.type() == mongo::String);
auto buildUUIDElem = cmd.getField("indexBuildUUID");
@@ -1054,8 +1063,53 @@ std::map<std::string, ApplyOpMetadata> opsMap = {
const OpTime& opTme,
const OplogEntry& entry,
OplogApplication::Mode mode) -> Status {
- // TODO (SERVER-39067): Not yet implemented.
- return Status::OK();
+ // {
+ // "abortIndexBuild" : "coll",
+ // "indexBuildUUID" : <UUID>,
+ // "indexes" : [
+ // {
+ // "key" : {
+ // "x" : 1
+ // },
+ // "name" : "x_1",
+ // "v" : 2
+ // },
+ // {
+ // "key" : {
+ // "k" : 1
+ // },
+ // "name" : "k_1",
+ // "v" : 2
+ // }
+ // ]
+ // }
+
+ // Ensure that the first element is the 'abortIndexBuild' field.
+ BSONElement first = cmd.firstElement();
+ invariant(first.fieldNameStringData() == "abortIndexBuild");
+ uassert(ErrorCodes::InvalidNamespace,
+ "abortIndexBuild value must be a string specifying the collection name",
+ first.type() == mongo::String);
+
+ auto buildUUIDElem = cmd.getField("indexBuildUUID");
+ uassert(ErrorCodes::BadValue,
+ "Error parsing 'abortIndexBuild' oplog entry, missing required field "
+ "'indexBuildUUID'.",
+ buildUUIDElem.eoo());
+ UUID indexBuildUUID = uassertStatusOK(UUID::parse(buildUUIDElem));
+
+ // We require the indexes field to ensure that rollback via refetch knows the appropriate
+ // indexes to rebuild.
+ auto indexesElem = cmd.getField("indexes");
+ uassert(ErrorCodes::BadValue,
+ "Error parsing 'abortIndexBuild' oplog entry, missing required field 'indexes'.",
+ indexesElem.eoo());
+ uassert(ErrorCodes::BadValue,
+ "Error parsing 'abortIndexBuild' oplog entry, field 'indexes' must be an array of "
+ "index names.",
+ indexesElem.type() == Array);
+
+ return abortIndexBuild(opCtx, indexBuildUUID, mode);
}}},
{"collMod",
{[](OperationContext* opCtx,
diff --git a/src/mongo/db/s/config_server_op_observer.h b/src/mongo/db/s/config_server_op_observer.h
index 192e7e091ef..be9b1b54c56 100644
--- a/src/mongo/db/s/config_server_op_observer.h
+++ b/src/mongo/db/s/config_server_op_observer.h
@@ -67,8 +67,10 @@ public:
bool fromMigrate) override {}
void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) override {}
void onInserts(OperationContext* opCtx,
diff --git a/src/mongo/db/s/shard_server_op_observer.h b/src/mongo/db/s/shard_server_op_observer.h
index 0e737cd66d6..6459ba2747a 100644
--- a/src/mongo/db/s/shard_server_op_observer.h
+++ b/src/mongo/db/s/shard_server_op_observer.h
@@ -68,8 +68,10 @@ public:
bool fromMigrate) override {}
void onAbortIndexBuild(OperationContext* opCtx,
+ const NamespaceString& nss,
CollectionUUID collUUID,
- const BSONObj& indexInfo,
+ const UUID& indexBuildUUID,
+ const std::vector<BSONObj>& indexes,
bool fromMigrate) override {}
void onInserts(OperationContext* opCtx,