diff options
Diffstat (limited to 'src/mongo/db/repl/oplog.cpp')
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 60 |
1 files changed, 57 insertions, 3 deletions
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, |