diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2017-10-20 17:03:18 -0400 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2017-10-23 17:54:51 -0400 |
commit | aa95387d1a8fb475c267a3ca0e84a1b4a18a7ace (patch) | |
tree | f258c7c961e7577d35b49080cfe1abe660889ab9 /src/mongo/db/ops | |
parent | dbe347e2ec54858a39a2b4c59d5812214b4b94cd (diff) | |
download | mongo-aa95387d1a8fb475c267a3ca0e84a1b4a18a7ace.tar.gz |
SERVER-31328 Don't fetch oplog entries for retries of executed inserts or deletes
Diffstat (limited to 'src/mongo/db/ops')
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_retryability.cpp | 42 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_retryability.h | 10 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_retryability_test.cpp | 92 |
4 files changed, 16 insertions, 146 deletions
diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index d3a9813039b..4cf25eafbad 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -424,6 +424,13 @@ StmtId getStmtIdForWriteOp(OperationContext* opCtx, const T& wholeOp, size_t opI : kUninitializedStmtId; } +SingleWriteResult makeWriteResultForInsertOrDeleteRetry() { + SingleWriteResult res; + res.setN(1); + res.setNModified(0); + return res; +} + } // namespace WriteResult performInserts(OperationContext* opCtx, const write_ops::Insert& wholeOp) { @@ -482,9 +489,9 @@ WriteResult performInserts(OperationContext* opCtx, const write_ops::Insert& who const auto stmtId = getStmtIdForWriteOp(opCtx, wholeOp, stmtIdIndex++); if (opCtx->getTxnNumber()) { auto session = OperationContextSession::get(opCtx); - if (auto entry = - session->checkStatementExecuted(opCtx, *opCtx->getTxnNumber(), stmtId)) { - out.results.emplace_back(parseOplogEntryForInsert(*entry)); + if (session->checkStatementExecutedNoOplogEntryFetch(*opCtx->getTxnNumber(), + stmtId)) { + out.results.emplace_back(makeWriteResultForInsertOrDeleteRetry()); continue; } } @@ -758,9 +765,8 @@ WriteResult performDeletes(OperationContext* opCtx, const write_ops::Delete& who const auto stmtId = getStmtIdForWriteOp(opCtx, wholeOp, stmtIdIndex++); if (opCtx->getTxnNumber()) { auto session = OperationContextSession::get(opCtx); - if (auto entry = - session->checkStatementExecuted(opCtx, *opCtx->getTxnNumber(), stmtId)) { - out.results.emplace_back(parseOplogEntryForDelete(*entry)); + if (session->checkStatementExecutedNoOplogEntryFetch(*opCtx->getTxnNumber(), stmtId)) { + out.results.emplace_back(makeWriteResultForInsertOrDeleteRetry()); continue; } } diff --git a/src/mongo/db/ops/write_ops_retryability.cpp b/src/mongo/db/ops/write_ops_retryability.cpp index 28ce5bed8be..10e5c8701a2 100644 --- a/src/mongo/db/ops/write_ops_retryability.cpp +++ b/src/mongo/db/ops/write_ops_retryability.cpp @@ -173,27 +173,6 @@ repl::OplogEntry getInnerNestedOplogEntry(const repl::OplogEntry& entry) { } // namespace -SingleWriteResult parseOplogEntryForInsert(const repl::OplogEntry& entry) { - if (entry.getOpType() == repl::OpTypeEnum::kNoop) { - return parseOplogEntryForInsert(getInnerNestedOplogEntry(entry)); - } - - uassert(40636, - str::stream() << "insert retry request is not compatible with previous write in the " - "transaction of type: " - << OpType_serializer(entry.getOpType()) - << ", oplogTs: " - << entry.getTimestamp().toString() - << ", oplog: " - << redact(entry.toBSON()), - entry.getOpType() == repl::OpTypeEnum::kInsert); - - SingleWriteResult res; - res.setN(1); - res.setNModified(0); - return res; -} - SingleWriteResult parseOplogEntryForUpdate(const repl::OplogEntry& entry) { SingleWriteResult res; // Upserts are stored as inserts. @@ -223,27 +202,6 @@ SingleWriteResult parseOplogEntryForUpdate(const repl::OplogEntry& entry) { return res; } -SingleWriteResult parseOplogEntryForDelete(const repl::OplogEntry& entry) { - if (entry.getOpType() == repl::OpTypeEnum::kNoop) { - return parseOplogEntryForDelete(getInnerNestedOplogEntry(entry)); - } - - uassert(40637, - str::stream() << "delete retry request is not compatible with previous write in the " - "transaction of type: " - << OpType_serializer(entry.getOpType()) - << ", oplogTs: " - << entry.getTimestamp().toString() - << ", oplog: " - << redact(entry.toBSON()), - entry.getOpType() == repl::OpTypeEnum::kDelete); - - SingleWriteResult res; - res.setN(1); - res.setNModified(0); - return res; -} - void parseOplogEntryForFindAndModify(OperationContext* opCtx, const FindAndModifyRequest& request, const repl::OplogEntry& oplogEntry, diff --git a/src/mongo/db/ops/write_ops_retryability.h b/src/mongo/db/ops/write_ops_retryability.h index fa73a4d34ed..55bd53bb804 100644 --- a/src/mongo/db/ops/write_ops_retryability.h +++ b/src/mongo/db/ops/write_ops_retryability.h @@ -39,14 +39,12 @@ class FindAndModifyRequest; class OperationContext; /** - * Returns the single write result corresponding to the given oplog entry for insert, update, and - * delete commands, i.e. the single write result that would have been returned by the statement that - * would have resulted in the given oplog entry. The oplog entries are assumed to be properly - * formed and have the correct op type. + * Returns the single write result corresponding to the given oplog entry for document update. I.e., + * the single write result that would have been returned by the statement that would have resulted + * in the given oplog entry. The oplog entries are assumed to be properly formed and have the + * correct op type. */ -SingleWriteResult parseOplogEntryForInsert(const repl::OplogEntry& entry); SingleWriteResult parseOplogEntryForUpdate(const repl::OplogEntry& entry); -SingleWriteResult parseOplogEntryForDelete(const repl::OplogEntry& entry); /** * Populates the passed-in builder with the result of a findAndModify based on the oplog entries diff --git a/src/mongo/db/ops/write_ops_retryability_test.cpp b/src/mongo/db/ops/write_ops_retryability_test.cpp index 4c6268c8c7f..7bf0ff72673 100644 --- a/src/mongo/db/ops/write_ops_retryability_test.cpp +++ b/src/mongo/db/ops/write_ops_retryability_test.cpp @@ -48,42 +48,6 @@ const BSONObj kNestedOplog(BSON("$sessionMigrateInfo" << 1)); using WriteOpsRetryability = ServiceContextMongoDTest; -TEST_F(WriteOpsRetryability, ParseOplogEntryForInsert) { - const auto entry = assertGet( - repl::OplogEntry::parse(BSON("ts" << Timestamp(50, 10) << "t" << 1LL << "h" << 0LL << "op" - << "i" - << "ns" - << "a.b" - << "o" - << BSON("_id" << 1 << "x" << 5)))); - - auto res = parseOplogEntryForInsert(entry); - - ASSERT_EQ(res.getN(), 1); - ASSERT_EQ(res.getNModified(), 0); - ASSERT_BSONOBJ_EQ(res.getUpsertedId(), BSONObj()); -} - -TEST_F(WriteOpsRetryability, ParseOplogEntryForNestedInsert) { - repl::OplogEntry innerOplog(repl::OpTime(Timestamp(50, 10), 1), - 0, - repl::OpTypeEnum::kInsert, - NamespaceString("a.b"), - BSON("_id" << 2)); - repl::OplogEntry insertOplog(repl::OpTime(Timestamp(60, 10), 1), - 0, - repl::OpTypeEnum::kNoop, - NamespaceString("a.b"), - kNestedOplog, - innerOplog.toBSON()); - - auto res = parseOplogEntryForInsert(insertOplog); - - ASSERT_EQ(res.getN(), 1); - ASSERT_EQ(res.getNModified(), 0); - ASSERT_BSONOBJ_EQ(res.getUpsertedId(), BSONObj()); -} - TEST_F(WriteOpsRetryability, ParseOplogEntryForUpdate) { const auto entry = assertGet( repl::OplogEntry::parse(BSON("ts" << Timestamp(50, 10) << "t" << 1LL << "h" << 0LL << "op" @@ -159,52 +123,6 @@ TEST_F(WriteOpsRetryability, ParseOplogEntryForNestedUpsert) { ASSERT_BSONOBJ_EQ(res.getUpsertedId(), BSON("_id" << 2)); } -TEST_F(WriteOpsRetryability, ParseOplogEntryForDelete) { - const auto entry = assertGet( - repl::OplogEntry::parse(BSON("ts" << Timestamp(50, 10) << "t" << 1LL << "h" << 0LL << "op" - << "d" - << "ns" - << "a.b" - << "o" - << BSON("_id" << 1 << "x" << 5)))); - - auto res = parseOplogEntryForDelete(entry); - - ASSERT_EQ(res.getN(), 1); - ASSERT_EQ(res.getNModified(), 0); - ASSERT_BSONOBJ_EQ(res.getUpsertedId(), BSONObj()); -} - -TEST_F(WriteOpsRetryability, ParseOplogEntryForNestedDelete) { - repl::OplogEntry innerOplog(repl::OpTime(Timestamp(50, 10), 1), - 0, - repl::OpTypeEnum::kDelete, - NamespaceString("a.b"), - BSON("_id" << 2)); - repl::OplogEntry deleteOplog(repl::OpTime(Timestamp(60, 10), 1), - 0, - repl::OpTypeEnum::kNoop, - NamespaceString("a.b"), - kNestedOplog, - innerOplog.toBSON()); - - auto res = parseOplogEntryForDelete(deleteOplog); - - ASSERT_EQ(res.getN(), 1); - ASSERT_EQ(res.getNModified(), 0); - ASSERT_BSONOBJ_EQ(res.getUpsertedId(), BSONObj()); -} - -TEST_F(WriteOpsRetryability, ShouldFailIfParsingDeleteOplogForInsert) { - repl::OplogEntry deleteOplog(repl::OpTime(Timestamp(50, 10), 1), - 0, - repl::OpTypeEnum::kDelete, - NamespaceString("a.b"), - BSON("_id" << 2)); - - ASSERT_THROWS(parseOplogEntryForInsert(deleteOplog), AssertionException); -} - TEST_F(WriteOpsRetryability, ShouldFailIfParsingDeleteOplogForUpdate) { repl::OplogEntry deleteOplog(repl::OpTime(Timestamp(50, 10), 1), 0, @@ -215,16 +133,6 @@ TEST_F(WriteOpsRetryability, ShouldFailIfParsingDeleteOplogForUpdate) { ASSERT_THROWS(parseOplogEntryForUpdate(deleteOplog), AssertionException); } -TEST_F(WriteOpsRetryability, ShouldFailIfParsingInsertOplogForDelete) { - repl::OplogEntry insertOplog(repl::OpTime(Timestamp(50, 10), 1), - 0, - repl::OpTypeEnum::kInsert, - NamespaceString("a.b"), - BSON("_id" << 2)); - - ASSERT_THROWS(parseOplogEntryForDelete(insertOplog), AssertionException); -} - class FindAndModifyRetryability : public MockReplCoordServerFixture { public: FindAndModifyRetryability() = default; |