summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierlauro Sciarelli <pierlauro.sciarelli@mongodb.com>2022-02-24 15:16:55 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-02-24 16:36:25 +0000
commit62b2ea1b5cd6c67303f0dcf2eee53fc1c5922a36 (patch)
treef1bca487e50dc778edb4ae73c2639fd30cd11ac8
parentdeabbd397ee55c94c88cfbc3ab1f8edbbe76aa6e (diff)
downloadmongo-62b2ea1b5cd6c67303f0dcf2eee53fc1c5922a36.tar.gz
SERVER-60109 Ensure vector clock is recovered on step-up
-rw-r--r--src/mongo/db/repl/replication_coordinator_external_state_impl.cpp2
-rw-r--r--src/mongo/db/s/vector_clock_shard_server_test.cpp6
-rw-r--r--src/mongo/db/vector_clock_mongod.cpp50
-rw-r--r--src/mongo/db/vector_clock_mutable.h2
-rw-r--r--src/mongo/db/vector_clock_trivial.cpp2
5 files changed, 29 insertions, 33 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
index b3177b71eba..7f0baac36b0 100644
--- a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
@@ -98,6 +98,7 @@
#include "mongo/db/system_index.h"
#include "mongo/db/vector_clock.h"
#include "mongo/db/vector_clock_metadata_hook.h"
+#include "mongo/db/vector_clock_mutable.h"
#include "mongo/executor/network_connection_hook.h"
#include "mongo/executor/network_interface.h"
#include "mongo/executor/network_interface_factory.h"
@@ -941,6 +942,7 @@ void ReplicationCoordinatorExternalStateImpl::_shardingOnTransitionToPrimaryHook
TransactionCoordinatorService::get(_service)->onStepUp(opCtx);
} else if (ShardingState::get(opCtx)->enabled()) {
Status status = ShardingStateRecovery::recover(opCtx);
+ VectorClockMutable::get(opCtx)->recoverDirect(opCtx);
// If the node is shutting down or it lost quorum just as it was becoming primary, don't
// run the sharding onStepUp machinery. The onStepDown counterpart to these methods is
diff --git a/src/mongo/db/s/vector_clock_shard_server_test.cpp b/src/mongo/db/s/vector_clock_shard_server_test.cpp
index 8e244c1f157..503136e4fd0 100644
--- a/src/mongo/db/s/vector_clock_shard_server_test.cpp
+++ b/src/mongo/db/s/vector_clock_shard_server_test.cpp
@@ -326,7 +326,7 @@ TEST_F(VectorClockPersistenceTest, PrimaryRecoverWithoutExistingVectorClockDocum
PersistentTaskStore<VectorClockDocument> store(NamespaceString::kVectorClockNamespace);
ASSERT_EQ(store.count(opCtx, kVectorClockQuery), 0);
- vc->recover().get();
+ vc->recoverDirect(opCtx);
auto time = vc->getTime();
ASSERT_EQ(Timestamp(0), time.configTime().asTimestamp());
@@ -343,7 +343,7 @@ TEST_F(VectorClockPersistenceTest, PrimaryRecoverWithExistingVectorClockDocument
ASSERT_EQ(store.count(opCtx, kVectorClockQuery), 0);
store.add(opCtx, VectorClockDocument(Timestamp(100), Timestamp(50)));
- vc->recover().get();
+ vc->recoverDirect(opCtx);
auto time = vc->getTime();
ASSERT_EQ(Timestamp(100), time.configTime().asTimestamp());
@@ -366,7 +366,7 @@ TEST_F(VectorClockPersistenceTest, PrimaryRecoverWithIllegalVectorClockDocument)
<< "IllegalValue"));
const int kParseErrorCode = 40414;
- ASSERT_THROWS_CODE(vc->recover().get(), DBException, ErrorCodes::Error(kParseErrorCode));
+ ASSERT_THROWS_CODE(vc->recoverDirect(opCtx), DBException, ErrorCodes::Error(kParseErrorCode));
}
} // namespace
diff --git a/src/mongo/db/vector_clock_mongod.cpp b/src/mongo/db/vector_clock_mongod.cpp
index 37825beb200..5afbb1946d9 100644
--- a/src/mongo/db/vector_clock_mongod.cpp
+++ b/src/mongo/db/vector_clock_mongod.cpp
@@ -84,7 +84,7 @@ private:
SharedSemiFuture<void> waitForDurableConfigTime() override;
SharedSemiFuture<void> waitForDurableTopologyTime() override;
SharedSemiFuture<void> waitForDurable() override;
- SharedSemiFuture<void> recover() override;
+ VectorClock::VectorTime recoverDirect(OperationContext* opCtx) override;
LogicalTime _tick(Component component, uint64_t nTicks) override;
void _tickTo(Component component, LogicalTime newTime) override;
@@ -231,12 +231,27 @@ SharedSemiFuture<void> VectorClockMongoD::waitForDurable() {
return _enqueueWaiterAndScheduleLoopIfNeeded(std::move(ul), std::move(time));
}
-SharedSemiFuture<void> VectorClockMongoD::recover() {
- stdx::unique_lock ul(_mutex);
- if (_durableTime)
- return SharedSemiFuture<void>();
+VectorClock::VectorTime VectorClockMongoD::recoverDirect(OperationContext* opCtx) {
+ VectorClockDocument durableVectorClock;
+
+ PersistentTaskStore<VectorClockDocument> store(NamespaceString::kVectorClockNamespace);
+ store.forEach(opCtx,
+ BSON(VectorClockDocument::k_idFieldName << durableVectorClock.get_id()),
+ [&, numDocsFound = 0](const auto& doc) mutable {
+ invariant(++numDocsFound == 1);
+ durableVectorClock = doc;
+ return true;
+ });
- return _enqueueWaiterAndScheduleLoopIfNeeded(std::move(ul), VectorTime());
+ const auto newDurableTime = VectorTime({LogicalTime(Timestamp(0)),
+ LogicalTime(durableVectorClock.getConfigTime()),
+ LogicalTime(durableVectorClock.getTopologyTime())});
+
+ // Make sure the VectorClock advances at least up to the just recovered durable time
+ _advanceTime(
+ {newDurableTime.clusterTime(), newDurableTime.configTime(), newDurableTime.topologyTime()});
+
+ return newDurableTime;
}
SharedSemiFuture<void> VectorClockMongoD::_enqueueWaiterAndScheduleLoopIfNeeded(
@@ -276,12 +291,6 @@ Future<void> VectorClockMongoD::_doWhileQueueNotEmptyOrError(ServiceContext* ser
}
ul.unlock();
- // Make sure the VectorClock advances at least up to the just recovered
- // durable time
- _advanceTime({newDurableTime.clusterTime(),
- newDurableTime.configTime(),
- newDurableTime.topologyTime()});
-
for (auto& p : promises)
p->emplaceValue();
})
@@ -327,22 +336,7 @@ Future<void> VectorClockMongoD::_doWhileQueueNotEmptyOrError(ServiceContext* ser
auto* const opCtx = opCtxHolder.get();
if (mustRecoverDurableTime) {
- VectorClockDocument durableVectorClock;
-
- PersistentTaskStore<VectorClockDocument> store(
- NamespaceString::kVectorClockNamespace);
- store.forEach(
- opCtx,
- BSON(VectorClockDocument::k_idFieldName << durableVectorClock.get_id()),
- [&, numDocsFound = 0](const auto& doc) mutable {
- invariant(++numDocsFound == 1);
- durableVectorClock = doc;
- return true;
- });
-
- return VectorTime({LogicalTime(Timestamp(0)),
- LogicalTime(durableVectorClock.getConfigTime()),
- LogicalTime(durableVectorClock.getTopologyTime())});
+ return recoverDirect(opCtx);
}
auto vectorTime = getTime();
diff --git a/src/mongo/db/vector_clock_mutable.h b/src/mongo/db/vector_clock_mutable.h
index 15ca97f5e68..fb586f037b8 100644
--- a/src/mongo/db/vector_clock_mutable.h
+++ b/src/mongo/db/vector_clock_mutable.h
@@ -92,7 +92,7 @@ public:
* Ensures that the values of the vector clock are at least equal to those from the last
* successfully persisted ones.
*/
- virtual SharedSemiFuture<void> recover() = 0;
+ virtual VectorClock::VectorTime recoverDirect(OperationContext* opCtx) = 0;
protected:
VectorClockMutable();
diff --git a/src/mongo/db/vector_clock_trivial.cpp b/src/mongo/db/vector_clock_trivial.cpp
index 479948cf82a..8b8b154a728 100644
--- a/src/mongo/db/vector_clock_trivial.cpp
+++ b/src/mongo/db/vector_clock_trivial.cpp
@@ -79,7 +79,7 @@ private:
MONGO_UNREACHABLE;
}
- SharedSemiFuture<void> recover() override {
+ VectorClock::VectorTime recoverDirect(OperationContext* opCtx) override {
// VectorClockTrivial does not support persistence
MONGO_UNREACHABLE;
}