0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-60774 Check every op in ReshardingDonorOplogIterator for final.

Changes the ReshardingDonorOplogIterator to not assume the
reshardFinalOp entry will always be the last document in resharding's
oplog buffer collection. The ReshardingOplogFetcher may end up inserting
no-op reshardProgressMark entries after the reshardFinalOp entry upon
resuming from a primary failover.
This commit is contained in:
Max Hirschhorn 2021-10-18 22:07:04 +00:00 committed by Evergreen Agent
parent ba4f3758c0
commit d3b36587bc
2 changed files with 45 additions and 0 deletions

View File

@ -188,6 +188,16 @@ std::vector<repl::OplogEntry> ReshardingDonorOplogIterator::_fillBatch(Pipeline&
}
numBytes += obj.objsize();
// The ReshardingOplogFetcher may end up inserting no-op reshardProgressMark entries *after*
// the reshardFinalOp entry. This can happen when the ReshardingOplogFetcher resumes after
// a primary failover and it had already written the reshardFinalOp entry. We check each
// oplog entry for being the reshardFinalOp and halt filling the batch so that an empty
// batch is returned to ReshardingOplogApplier to signal all oplog entries from the donor
// shard were applied.
if (isFinalOplog(entry)) {
break;
}
} while (numBytes < resharding::gReshardingOplogBatchLimitBytes.load() &&
batch.size() < std::size_t(resharding::gReshardingOplogBatchLimitOperations.load()));

View File

@ -503,5 +503,40 @@ TEST_F(ReshardingDonorOplogIterTest, BatchIncludesProgressMarkEntries) {
ASSERT_TRUE(next.empty());
}
TEST_F(ReshardingDonorOplogIterTest, IgnoresProgressMarkEntriesAfterFinalOp) {
RAIIServerParameterControllerForTest controller{"reshardingOplogBatchLimitOperations", 100};
const auto oplog1 = makeInsertOplog(Timestamp(2, 4), BSON("x" << 1));
const auto progressMarkOplog1 = makeProgressMarkOplogEntry(Timestamp(15, 3));
const auto finalOplog = makeFinalOplog(Timestamp(43, 24));
// reshardProgressMark entries inserted after the reshardFinalOp entry should be ignored.
const auto progressMarkOplog2 = makeProgressMarkOplogEntry(Timestamp(65, 2));
const auto progressMarkOplog3 = makeProgressMarkOplogEntry(Timestamp(65, 3));
const auto progressMarkOplog4 = makeProgressMarkOplogEntry(Timestamp(65, 4));
DBDirectClient client(operationContext());
const auto ns = oplogNss().ns();
client.insert(ns, oplog1.toBSON());
client.insert(ns, progressMarkOplog1.toBSON());
client.insert(ns, finalOplog.toBSON());
client.insert(ns, progressMarkOplog2.toBSON());
client.insert(ns, progressMarkOplog3.toBSON());
client.insert(ns, progressMarkOplog4.toBSON());
ReshardingDonorOplogIterator iter(oplogNss(), kResumeFromBeginning, &onInsertAlwaysReady);
auto executor = makeTaskExecutorForIterator();
auto factory = makeCancelableOpCtx();
auto altClient = makeKillableClient();
AlternativeClientRegion acr(altClient);
auto next = getNextBatch(&iter, executor, factory);
ASSERT_EQ(next.size(), 2U);
ASSERT_BSONOBJ_EQ(getId(oplog1), getId(next[0]));
ASSERT_BSONOBJ_EQ(getId(progressMarkOplog1), getId(next[1]));
next = getNextBatch(&iter, executor, factory);
ASSERT_TRUE(next.empty());
}
} // anonymous namespace
} // namespace mongo