diff options
-rw-r--r-- | jstests/noPassthrough/wt_disable_majority_reads.js | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_recovery.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_recovery_test.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/repl/rollback_test_fixture.h | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface.h | 5 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.h | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_mock.h | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/kv/kv_engine.h | 7 | ||||
-rw-r--r-- | src/mongo/db/storage/kv/kv_storage_engine.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/kv/kv_storage_engine.h | 2 | ||||
-rw-r--r-- | src/mongo/db/storage/storage_engine.h | 7 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h | 2 |
14 files changed, 72 insertions, 9 deletions
diff --git a/jstests/noPassthrough/wt_disable_majority_reads.js b/jstests/noPassthrough/wt_disable_majority_reads.js index d4b0d66e7b9..57249723d2c 100644 --- a/jstests/noPassthrough/wt_disable_majority_reads.js +++ b/jstests/noPassthrough/wt_disable_majority_reads.js @@ -1,4 +1,4 @@ -// @tags: [requires_wiredtiger] +// @tags: [requires_wiredtiger, requires_replication] (function() { "use strict"; diff --git a/src/mongo/db/repl/replication_recovery.cpp b/src/mongo/db/repl/replication_recovery.cpp index b9dbc665155..a41f8b81919 100644 --- a/src/mongo/db/repl/replication_recovery.cpp +++ b/src/mongo/db/repl/replication_recovery.cpp @@ -247,10 +247,9 @@ void ReplicationRecoveryImpl::recoverFromOplog(OperationContext* opCtx, // recovery timestamp. If the storage engine returns a timestamp, we recover from that point. // However, if the storage engine returns "none", the storage engine does not have a stable // checkpoint and we must recover from an unstable checkpoint instead. - const bool supportsRecoverToStableTimestamp = - _storageInterface->supportsRecoverToStableTimestamp(opCtx->getServiceContext()); - if (!stableTimestamp && - (supportsRecoverToStableTimestamp || !serverGlobalParams.enableMajorityReadConcern)) { + const bool supportsRecoveryTimestamp = + _storageInterface->supportsRecoveryTimestamp(opCtx->getServiceContext()); + if (!stableTimestamp && supportsRecoveryTimestamp) { stableTimestamp = _storageInterface->getRecoveryTimestamp(opCtx->getServiceContext()); } @@ -262,8 +261,7 @@ void ReplicationRecoveryImpl::recoverFromOplog(OperationContext* opCtx, << appliedThrough.toString()); if (stableTimestamp) { - invariant(supportsRecoverToStableTimestamp || - !serverGlobalParams.enableMajorityReadConcern); + invariant(supportsRecoveryTimestamp); _recoverFromStableTimestamp(opCtx, *stableTimestamp, appliedThrough, topOfOplog); } else { _recoverFromUnstableCheckpoint(opCtx, appliedThrough, topOfOplog); diff --git a/src/mongo/db/repl/replication_recovery_test.cpp b/src/mongo/db/repl/replication_recovery_test.cpp index 1a7cc5f8be8..cd5e072a513 100644 --- a/src/mongo/db/repl/replication_recovery_test.cpp +++ b/src/mongo/db/repl/replication_recovery_test.cpp @@ -78,11 +78,22 @@ public: _supportsRecoverToStableTimestamp = supports; } + bool supportsRecoveryTimestamp(ServiceContext* serviceCtx) const override { + stdx::lock_guard<stdx::mutex> lock(_mutex); + return _supportsRecoveryTimestamp; + } + + void setSupportsRecoveryTimestamp(bool supports) { + stdx::lock_guard<stdx::mutex> lock(_mutex); + _supportsRecoveryTimestamp = supports; + } + private: mutable stdx::mutex _mutex; Timestamp _initialDataTimestamp = Timestamp::min(); boost::optional<Timestamp> _recoveryTimestamp = boost::none; bool _supportsRecoverToStableTimestamp = true; + bool _supportsRecoveryTimestamp = true; }; class ReplicationRecoveryTest : public ServiceContextMongoDTest { @@ -357,9 +368,9 @@ DEATH_TEST_F(ReplicationRecoveryTest, } DEATH_TEST_F(ReplicationRecoveryTest, - RecoveryInvariantsIfStableTimestampAndDoesNotSupportRTT, + RecoveryInvariantsIfStableTimestampAndDoesNotSupportRecoveryTimestamp, "Invariant failure") { - getStorageInterfaceRecovery()->setSupportsRecoverToStableTimestamp(false); + getStorageInterfaceRecovery()->setSupportsRecoveryTimestamp(false); ReplicationRecoveryImpl recovery(getStorageInterface(), getConsistencyMarkers()); auto opCtx = getOperationContext(); diff --git a/src/mongo/db/repl/rollback_test_fixture.h b/src/mongo/db/repl/rollback_test_fixture.h index 8d31c63564f..26c568db2c4 100644 --- a/src/mongo/db/repl/rollback_test_fixture.h +++ b/src/mongo/db/repl/rollback_test_fixture.h @@ -137,6 +137,10 @@ public: return true; } + bool supportsRecoveryTimestamp(ServiceContext* serviceCtx) const override { + return true; + } + void setRecoverToTimestampStatus(Status status) { stdx::lock_guard<stdx::mutex> lock(_mutex); _recoverToTimestampStatus = status; diff --git a/src/mongo/db/repl/storage_interface.h b/src/mongo/db/repl/storage_interface.h index 5b526456752..2d9e3518dde 100644 --- a/src/mongo/db/repl/storage_interface.h +++ b/src/mongo/db/repl/storage_interface.h @@ -374,6 +374,11 @@ public: virtual bool supportsRecoverToStableTimestamp(ServiceContext* serviceCtx) const = 0; /** + * Returns whether the storage engine can provide a recovery timestamp. + */ + virtual bool supportsRecoveryTimestamp(ServiceContext* serviceCtx) const = 0; + + /** * Returns the stable timestamp that the storage engine recovered to on startup. If the * recovery point was not stable, returns "none". */ diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index 93d93a319d4..6497c9aa36e 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -1062,6 +1062,10 @@ bool StorageInterfaceImpl::supportsRecoverToStableTimestamp(ServiceContext* serv return serviceCtx->getStorageEngine()->supportsRecoverToStableTimestamp(); } +bool StorageInterfaceImpl::supportsRecoveryTimestamp(ServiceContext* serviceCtx) const { + return serviceCtx->getStorageEngine()->supportsRecoveryTimestamp(); +} + boost::optional<Timestamp> StorageInterfaceImpl::getRecoveryTimestamp( ServiceContext* serviceCtx) const { return serviceCtx->getStorageEngine()->getRecoveryTimestamp(); diff --git a/src/mongo/db/repl/storage_interface_impl.h b/src/mongo/db/repl/storage_interface_impl.h index 17555669b00..08e8f3b0dbf 100644 --- a/src/mongo/db/repl/storage_interface_impl.h +++ b/src/mongo/db/repl/storage_interface_impl.h @@ -166,6 +166,8 @@ public: bool supportsRecoverToStableTimestamp(ServiceContext* serviceCtx) const override; + bool supportsRecoveryTimestamp(ServiceContext* serviceCtx) const override; + boost::optional<Timestamp> getRecoveryTimestamp(ServiceContext* serviceCtx) const override; bool supportsDocLocking(ServiceContext* serviceCtx) const override; diff --git a/src/mongo/db/repl/storage_interface_mock.h b/src/mongo/db/repl/storage_interface_mock.h index 41b3d71c916..a3bf9f960ab 100644 --- a/src/mongo/db/repl/storage_interface_mock.h +++ b/src/mongo/db/repl/storage_interface_mock.h @@ -303,6 +303,10 @@ public: return false; } + bool supportsRecoveryTimestamp(ServiceContext* serviceCtx) const override { + return false; + } + boost::optional<Timestamp> getRecoveryTimestamp(ServiceContext* serviceCtx) const override { return boost::none; } diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h index fd5819d81cb..bd46f60577c 100644 --- a/src/mongo/db/storage/kv/kv_engine.h +++ b/src/mongo/db/storage/kv/kv_engine.h @@ -306,6 +306,13 @@ public: } /** + * See `StorageEngine::supportsRecoveryTimestamp` + */ + virtual bool supportsRecoveryTimestamp() const { + return false; + } + + /** * See `StorageEngine::recoverToStableTimestamp` */ virtual StatusWith<Timestamp> recoverToStableTimestamp(OperationContext* opCtx) { diff --git a/src/mongo/db/storage/kv/kv_storage_engine.cpp b/src/mongo/db/storage/kv/kv_storage_engine.cpp index 925fbc59c3d..006ab2ae489 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine.cpp +++ b/src/mongo/db/storage/kv/kv_storage_engine.cpp @@ -638,6 +638,10 @@ bool KVStorageEngine::supportsRecoverToStableTimestamp() const { return _engine->supportsRecoverToStableTimestamp(); } +bool KVStorageEngine::supportsRecoveryTimestamp() const { + return _engine->supportsRecoveryTimestamp(); +} + StatusWith<Timestamp> KVStorageEngine::recoverToStableTimestamp(OperationContext* opCtx) { invariant(opCtx->lockState()->isW()); diff --git a/src/mongo/db/storage/kv/kv_storage_engine.h b/src/mongo/db/storage/kv/kv_storage_engine.h index d0c6051d950..8c9033db398 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine.h +++ b/src/mongo/db/storage/kv/kv_storage_engine.h @@ -126,6 +126,8 @@ public: virtual bool supportsRecoverToStableTimestamp() const override; + virtual bool supportsRecoveryTimestamp() const override; + virtual StatusWith<Timestamp> recoverToStableTimestamp(OperationContext* opCtx) override; virtual boost::optional<Timestamp> getRecoveryTimestamp() const override; diff --git a/src/mongo/db/storage/storage_engine.h b/src/mongo/db/storage/storage_engine.h index b89f83934ea..d6b6a3c4290 100644 --- a/src/mongo/db/storage/storage_engine.h +++ b/src/mongo/db/storage/storage_engine.h @@ -320,6 +320,13 @@ public: } /** + * Returns whether the storage engine can provide a recovery timestamp. + */ + virtual bool supportsRecoveryTimestamp() const { + return false; + } + + /** * Returns true if the storage engine supports the readConcern level "snapshot". */ virtual bool supportsReadConcernSnapshot() const { diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index cbfdd2cc024..a756c1314e1 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -1461,6 +1461,14 @@ bool WiredTigerKVEngine::supportsRecoverToStableTimestamp() const { return true; } +bool WiredTigerKVEngine::supportsRecoveryTimestamp() const { + if (_ephemeral) { + return false; + } + + return true; +} + StatusWith<Timestamp> WiredTigerKVEngine::recoverToStableTimestamp(OperationContext* opCtx) { if (!supportsRecoverToStableTimestamp()) { severe() << "WiredTiger is configured to not support recover to a stable timestamp"; @@ -1515,6 +1523,11 @@ Timestamp WiredTigerKVEngine::getAllCommittedTimestamp() const { } boost::optional<Timestamp> WiredTigerKVEngine::getRecoveryTimestamp() const { + if (!supportsRecoveryTimestamp()) { + severe() << "WiredTiger is configured to not support providing a recovery timestamp"; + fassertFailed(50745); + } + if (_recoveryTimestamp.isNull()) { return boost::none; } diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h index fb242aa926b..d46be5862cd 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h @@ -196,6 +196,8 @@ public: virtual bool supportsRecoverToStableTimestamp() const override; + virtual bool supportsRecoveryTimestamp() const override; + virtual StatusWith<Timestamp> recoverToStableTimestamp(OperationContext* opCtx) override; virtual boost::optional<Timestamp> getRecoveryTimestamp() const override; |