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:
parent
ba4f3758c0
commit
d3b36587bc
@ -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()));
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user