diff options
author | Spencer T Brody <spencer@mongodb.com> | 2017-02-14 17:59:57 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2017-03-02 11:00:50 -0500 |
commit | 92d9fb1162f40e1feeb21c534f9e6b278e050d64 (patch) | |
tree | 2cc08a1a409c2615096f9a20fc2da50af53253a5 | |
parent | 633a7101f5c0c21ef895b92c695dee9f012bbefc (diff) | |
download | mongo-92d9fb1162f40e1feeb21c534f9e6b278e050d64.tar.gz |
SERVER-28013 Ensure that last op for client only moves forward
(cherry picked from commit 34c00f16a8890775c71c63c860e2086c6bb603aa)
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_client_info.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_client_info.h | 10 | ||||
-rw-r--r-- | src/mongo/dbtests/repltests.cpp | 6 |
4 files changed, 22 insertions, 7 deletions
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 833da2a2e86..24700262de6 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -375,10 +375,10 @@ void _logOpsInner(OperationContext* txn, checkOplogInsert(oplogCollection->insertDocumentsForOplog(txn, writers, nWriters)); // Set replCoord last optime only after we're sure the WUOW didn't abort and roll back. - txn->recoveryUnit()->onCommit( - [replCoord, finalOpTime] { replCoord->setMyLastAppliedOpTimeForward(finalOpTime); }); - - ReplClientInfo::forClient(txn->getClient()).setLastOp(finalOpTime); + txn->recoveryUnit()->onCommit([txn, replCoord, finalOpTime] { + replCoord->setMyLastAppliedOpTimeForward(finalOpTime); + ReplClientInfo::forClient(txn->getClient()).setLastOp(finalOpTime); + }); } void logOp(OperationContext* txn, diff --git a/src/mongo/db/repl/repl_client_info.cpp b/src/mongo/db/repl/repl_client_info.cpp index 678938f2755..3e98a0cb9d3 100644 --- a/src/mongo/db/repl/repl_client_info.cpp +++ b/src/mongo/db/repl/repl_client_info.cpp @@ -43,6 +43,11 @@ namespace repl { const Client::Decoration<ReplClientInfo> ReplClientInfo::forClient = Client::declareDecoration<ReplClientInfo>(); +void ReplClientInfo::setLastOp(const OpTime& ot) { + invariant(ot >= _lastOp); + _lastOp = ot; +} + void ReplClientInfo::setLastOpToSystemLastOpTime(OperationContext* txn) { ReplicationCoordinator* replCoord = repl::ReplicationCoordinator::get(txn->getServiceContext()); if (replCoord->isReplEnabled() && txn->writesAreReplicated()) { diff --git a/src/mongo/db/repl/repl_client_info.h b/src/mongo/db/repl/repl_client_info.h index 4c01119b794..3c81953d65f 100644 --- a/src/mongo/db/repl/repl_client_info.h +++ b/src/mongo/db/repl/repl_client_info.h @@ -45,13 +45,17 @@ class ReplClientInfo { public: static const Client::Decoration<ReplClientInfo> forClient; - void setLastOp(const OpTime& op) { - _lastOp = op; - } + void setLastOp(const OpTime& op); + OpTime getLastOp() const { return _lastOp; } + // Resets the last op on this client; should only be used in testing. + void clearLastOp_forTest() { + _lastOp = OpTime(); + } + void setLastSnapshot(SnapshotName name) { _lastSnapshot = name; } diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp index e547f4aa8a6..e10f536c21f 100644 --- a/src/mongo/dbtests/repltests.cpp +++ b/src/mongo/dbtests/repltests.cpp @@ -45,6 +45,7 @@ #include "mongo/db/ops/update.h" #include "mongo/db/repl/master_slave.h" #include "mongo/db/repl/oplog.h" +#include "mongo/db/repl/repl_client_info.h" #include "mongo/db/repl/replication_coordinator_global.h" #include "mongo/db/repl/replication_coordinator_mock.h" #include "mongo/db/repl/sync_tail.h" @@ -78,6 +79,11 @@ public: replSettings.setMaster(true); setGlobalReplicationCoordinator(new repl::ReplicationCoordinatorMock(replSettings)); + // Since the Client object persists across tests, even though the global + // ReplicationCoordinator does not, we need to clear the last op associated with the client + // to avoid the invariant in ReplClientInfo::setLastOp that the optime only goes forward. + repl::ReplClientInfo::forClient(_txn.getClient()).clearLastOp_forTest(); + getGlobalServiceContext()->setOpObserver(stdx::make_unique<OpObserverImpl>()); setOplogCollectionName(); |