summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingzhi Deng <lingzhi.deng@mongodb.com>2020-10-13 15:08:52 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-10-15 19:16:42 +0000
commit9f52be8cf511d4fe0b2aa8eb20e18c47a5bf097d (patch)
tree9e6a7afee6b444d9f760f7133154bda041235276
parentbef72de45709f2e1e6874e9b5f29a01e3fa8c413 (diff)
downloadmongo-9f52be8cf511d4fe0b2aa8eb20e18c47a5bf097d.tar.gz
SERVER-50949: Return empty JournalListener token during rollback
-rw-r--r--src/mongo/db/repl/replication_coordinator.h7
-rw-r--r--src/mongo/db/repl/replication_coordinator_external_state_impl.cpp15
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp6
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.h3
-rw-r--r--src/mongo/db/repl/replication_coordinator_mock.cpp7
-rw-r--r--src/mongo/db/repl/replication_coordinator_mock.h2
-rw-r--r--src/mongo/db/repl/replication_coordinator_noop.cpp3
-rw-r--r--src/mongo/db/repl/replication_coordinator_noop.h2
-rw-r--r--src/mongo/embedded/replication_coordinator_embedded.cpp3
-rw-r--r--src/mongo/embedded/replication_coordinator_embedded.h3
10 files changed, 39 insertions, 12 deletions
diff --git a/src/mongo/db/repl/replication_coordinator.h b/src/mongo/db/repl/replication_coordinator.h
index e4f9db71181..5338ab09abd 100644
--- a/src/mongo/db/repl/replication_coordinator.h
+++ b/src/mongo/db/repl/replication_coordinator.h
@@ -408,8 +408,13 @@ public:
/*
* Returns the same as getMyLastAppliedOpTime() and additionally returns the wall clock time
* corresponding to that OpTime.
+ *
+ * When rollbackSafe is true, this returns an empty OpTimeAndWallTime if the node is in ROLLBACK
+ * state. The lastAppliedOpTime during ROLLBACK might be temporarily pointing to an oplog entry
+ * in the divergent branch of history which would become invalid after the rollback finishes.
*/
- virtual OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime() const = 0;
+ virtual OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime(
+ bool rollbackSafe = false) const = 0;
/**
* Returns the last optime recorded by setMyLastDurableOpTime.
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 feef90d04e8..5ecb4f7297b 100644
--- a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
@@ -1079,8 +1079,19 @@ JournalListener::Token ReplicationCoordinatorExternalStateImpl::getToken(Operati
}
}
- // All other repl states use the last applied.
- return repl::ReplicationCoordinator::get(_service)->getMyLastAppliedOpTimeAndWallTime();
+ // All other repl states use the 'lastApplied'.
+ //
+ // Setting 'rollbackSafe' will ensure that a safe lastApplied value is returned if we're in
+ // ROLLBACK state. 'lastApplied' may be momentarily set to an opTime from a divergent branch of
+ // history during rollback, so a benign default value will be returned instead to prevent a
+ // divergent 'lastApplied' from being used to forward the 'lastDurable' after rollback.
+ //
+ // No concurrency control is necessary and it is still safe if the node goes into ROLLBACK after
+ // getting the token because the JournalFlusher is shut down during rollback, before a divergent
+ // 'lastApplied' value is present. The JournalFlusher will start up again in ROLLBACK and never
+ // transition from non-ROLLBACK to ROLLBACK with a divergent 'lastApplied' value.
+ return repl::ReplicationCoordinator::get(_service)->getMyLastAppliedOpTimeAndWallTime(
+ /*rollbackSafe=*/true);
}
void ReplicationCoordinatorExternalStateImpl::onDurable(const JournalListener::Token& token) {
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 564744ca4dd..8db38fa5803 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -1413,8 +1413,12 @@ OpTime ReplicationCoordinatorImpl::getMyLastAppliedOpTime() const {
return _getMyLastAppliedOpTime_inlock();
}
-OpTimeAndWallTime ReplicationCoordinatorImpl::getMyLastAppliedOpTimeAndWallTime() const {
+OpTimeAndWallTime ReplicationCoordinatorImpl::getMyLastAppliedOpTimeAndWallTime(
+ bool rollbackSafe) const {
stdx::lock_guard<Latch> lock(_mutex);
+ if (rollbackSafe && _getMemberState_inlock().rollback()) {
+ return {};
+ }
return _getMyLastAppliedOpTimeAndWallTime_inlock();
}
diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h
index dac623362a5..10437a4467f 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.h
+++ b/src/mongo/db/repl/replication_coordinator_impl.h
@@ -184,7 +184,8 @@ public:
virtual void setMyHeartbeatMessage(const std::string& msg);
virtual OpTime getMyLastAppliedOpTime() const override;
- virtual OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime() const override;
+ virtual OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime(
+ bool rollbackSafe = false) const override;
virtual OpTime getMyLastDurableOpTime() const override;
virtual OpTimeAndWallTime getMyLastDurableOpTimeAndWallTime() const override;
diff --git a/src/mongo/db/repl/replication_coordinator_mock.cpp b/src/mongo/db/repl/replication_coordinator_mock.cpp
index d55e79b67b5..c77cfbe570e 100644
--- a/src/mongo/db/repl/replication_coordinator_mock.cpp
+++ b/src/mongo/db/repl/replication_coordinator_mock.cpp
@@ -274,9 +274,12 @@ void ReplicationCoordinatorMock::resetMyLastOpTimes() {
_myLastDurableWallTime = Date_t();
}
-OpTimeAndWallTime ReplicationCoordinatorMock::getMyLastAppliedOpTimeAndWallTime() const {
+OpTimeAndWallTime ReplicationCoordinatorMock::getMyLastAppliedOpTimeAndWallTime(
+ bool rollbackSafe) const {
stdx::lock_guard<Mutex> lk(_mutex);
-
+ if (rollbackSafe && _memberState.rollback()) {
+ return {};
+ }
return {_myLastAppliedOpTime, _myLastAppliedWallTime};
}
diff --git a/src/mongo/db/repl/replication_coordinator_mock.h b/src/mongo/db/repl/replication_coordinator_mock.h
index 13d85b97ed1..d7d74471e45 100644
--- a/src/mongo/db/repl/replication_coordinator_mock.h
+++ b/src/mongo/db/repl/replication_coordinator_mock.h
@@ -149,7 +149,7 @@ public:
virtual void setMyHeartbeatMessage(const std::string& msg);
- virtual OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime() const;
+ virtual OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime(bool rollbackSafe) const;
virtual OpTime getMyLastAppliedOpTime() const;
virtual OpTimeAndWallTime getMyLastDurableOpTimeAndWallTime() const;
diff --git a/src/mongo/db/repl/replication_coordinator_noop.cpp b/src/mongo/db/repl/replication_coordinator_noop.cpp
index ac3433eff02..e23efe39bd9 100644
--- a/src/mongo/db/repl/replication_coordinator_noop.cpp
+++ b/src/mongo/db/repl/replication_coordinator_noop.cpp
@@ -135,7 +135,8 @@ bool ReplicationCoordinatorNoOp::buildsIndexes() {
MONGO_UNREACHABLE;
}
-OpTimeAndWallTime ReplicationCoordinatorNoOp::getMyLastAppliedOpTimeAndWallTime() const {
+OpTimeAndWallTime ReplicationCoordinatorNoOp::getMyLastAppliedOpTimeAndWallTime(
+ bool rollbackSafe) const {
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/db/repl/replication_coordinator_noop.h b/src/mongo/db/repl/replication_coordinator_noop.h
index 6cc54cb6664..22a91e840e9 100644
--- a/src/mongo/db/repl/replication_coordinator_noop.h
+++ b/src/mongo/db/repl/replication_coordinator_noop.h
@@ -131,7 +131,7 @@ public:
void setMyHeartbeatMessage(const std::string&) final;
OpTime getMyLastAppliedOpTime() const final;
- OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime() const final;
+ OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime(bool rollbackSafe = false) const final;
OpTime getMyLastDurableOpTime() const final;
OpTimeAndWallTime getMyLastDurableOpTimeAndWallTime() const final;
diff --git a/src/mongo/embedded/replication_coordinator_embedded.cpp b/src/mongo/embedded/replication_coordinator_embedded.cpp
index 72b956887ca..b92deb55c45 100644
--- a/src/mongo/embedded/replication_coordinator_embedded.cpp
+++ b/src/mongo/embedded/replication_coordinator_embedded.cpp
@@ -228,7 +228,8 @@ void ReplicationCoordinatorEmbedded::resetMyLastOpTimes() {
UASSERT_NOT_IMPLEMENTED;
}
-OpTimeAndWallTime ReplicationCoordinatorEmbedded::getMyLastAppliedOpTimeAndWallTime() const {
+OpTimeAndWallTime ReplicationCoordinatorEmbedded::getMyLastAppliedOpTimeAndWallTime(
+ bool rollbackSafe) const {
UASSERT_NOT_IMPLEMENTED;
}
diff --git a/src/mongo/embedded/replication_coordinator_embedded.h b/src/mongo/embedded/replication_coordinator_embedded.h
index 502333a0b6b..15ab7521b1b 100644
--- a/src/mongo/embedded/replication_coordinator_embedded.h
+++ b/src/mongo/embedded/replication_coordinator_embedded.h
@@ -139,7 +139,8 @@ public:
void setMyHeartbeatMessage(const std::string&) override;
repl::OpTime getMyLastAppliedOpTime() const override;
- repl::OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime() const override;
+ repl::OpTimeAndWallTime getMyLastAppliedOpTimeAndWallTime(
+ bool rollbackSafe = false) const override;
repl::OpTime getMyLastDurableOpTime() const override;
repl::OpTimeAndWallTime getMyLastDurableOpTimeAndWallTime() const override;