diff options
author | Matthew Russotto <matthew.russotto@mongodb.com> | 2021-11-03 11:06:32 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-11-04 14:47:41 +0000 |
commit | ee60e4ecf5e0bc8bfc9166bcf407eeeaa493a15f (patch) | |
tree | f94d081a273e5f986abbf5da3d5fa7df722b9812 | |
parent | bd9939bf4f98cced5b8dcd1f7249431ed5ee688c (diff) | |
download | mongo-ee60e4ecf5e0bc8bfc9166bcf407eeeaa493a15f.tar.gz |
SERVER-61213 Reconfiguration changes crash during File Copy Based Initial Sync
7 files changed, 62 insertions, 2 deletions
diff --git a/src/mongo/db/repl/data_replicator_external_state.h b/src/mongo/db/repl/data_replicator_external_state.h index 067a131201b..23716b9c578 100644 --- a/src/mongo/db/repl/data_replicator_external_state.h +++ b/src/mongo/db/repl/data_replicator_external_state.h @@ -121,9 +121,20 @@ public: ThreadPool* writerPool) = 0; /** - * Returns the current replica set config if there is one, or an error why there isn't. + * Returns the current in-memory replica set config if there is one, or an error why there + * isn't. */ virtual StatusWith<ReplSetConfig> getCurrentConfig() const = 0; + + /** + * Returns the current stored replica set config if there is one, or an error why there isn't. + */ + virtual StatusWith<BSONObj> loadLocalConfigDocument(OperationContext* opCtx) const = 0; + + /** + * Stores the replica set config document in local storage, or returns an error. + */ + virtual Status storeLocalConfigDocument(OperationContext* opCtx, const BSONObj& config) = 0; }; } // namespace repl diff --git a/src/mongo/db/repl/data_replicator_external_state_impl.cpp b/src/mongo/db/repl/data_replicator_external_state_impl.cpp index 8e693456799..81c5141a757 100644 --- a/src/mongo/db/repl/data_replicator_external_state_impl.cpp +++ b/src/mongo/db/repl/data_replicator_external_state_impl.cpp @@ -152,6 +152,17 @@ StatusWith<ReplSetConfig> DataReplicatorExternalStateImpl::getCurrentConfig() co return _replicationCoordinator->getConfig(); } +StatusWith<BSONObj> DataReplicatorExternalStateImpl::loadLocalConfigDocument( + OperationContext* opCtx) const { + return _replicationCoordinatorExternalState->loadLocalConfigDocument(opCtx); +} + +Status DataReplicatorExternalStateImpl::storeLocalConfigDocument(OperationContext* opCtx, + const BSONObj& config) { + return _replicationCoordinatorExternalState->storeLocalConfigDocument( + opCtx, config, false /* write oplog entry */); +} + ReplicationCoordinator* DataReplicatorExternalStateImpl::getReplicationCoordinator() const { return _replicationCoordinator; } diff --git a/src/mongo/db/repl/data_replicator_external_state_impl.h b/src/mongo/db/repl/data_replicator_external_state_impl.h index aa62e77a7d0..48b20165806 100644 --- a/src/mongo/db/repl/data_replicator_external_state_impl.h +++ b/src/mongo/db/repl/data_replicator_external_state_impl.h @@ -80,6 +80,10 @@ public: StatusWith<ReplSetConfig> getCurrentConfig() const override; + StatusWith<BSONObj> loadLocalConfigDocument(OperationContext* opCtx) const override; + + Status storeLocalConfigDocument(OperationContext* opCtx, const BSONObj& config) override; + protected: ReplicationCoordinator* getReplicationCoordinator() const; ReplicationCoordinatorExternalState* getReplicationCoordinatorExternalState() const; diff --git a/src/mongo/db/repl/data_replicator_external_state_mock.cpp b/src/mongo/db/repl/data_replicator_external_state_mock.cpp index 5e292f899d1..f48f8ebdd9e 100644 --- a/src/mongo/db/repl/data_replicator_external_state_mock.cpp +++ b/src/mongo/db/repl/data_replicator_external_state_mock.cpp @@ -124,5 +124,18 @@ StatusWith<ReplSetConfig> DataReplicatorExternalStateMock::getCurrentConfig() co return replSetConfigResult; } +StatusWith<BSONObj> DataReplicatorExternalStateMock::loadLocalConfigDocument( + OperationContext* opCtx) const { + if (replSetConfigResult.isOK()) { + return replSetConfigResult.getValue().toBSON(); + } + return replSetConfigResult.getStatus(); +} + +Status DataReplicatorExternalStateMock::storeLocalConfigDocument(OperationContext* opCtx, + const BSONObj& config) { + return Status::OK(); +} + } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/data_replicator_external_state_mock.h b/src/mongo/db/repl/data_replicator_external_state_mock.h index b32ff68df1c..367f24f91b0 100644 --- a/src/mongo/db/repl/data_replicator_external_state_mock.h +++ b/src/mongo/db/repl/data_replicator_external_state_mock.h @@ -70,6 +70,10 @@ public: StatusWith<ReplSetConfig> getCurrentConfig() const override; + StatusWith<BSONObj> loadLocalConfigDocument(OperationContext* opCtx) const override; + + Status storeLocalConfigDocument(OperationContext* opCtx, const BSONObj& config) override; + // Task executor. std::shared_ptr<executor::TaskExecutor> taskExecutor = nullptr; diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp index ca32abc45c8..a2962139d74 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp @@ -688,7 +688,16 @@ void ReplicationCoordinatorImpl::_heartbeatReconfigStore( auto status = _externalState->storeLocalConfigDocument( opCtx.get(), newConfig.toBSON(), false /* writeOplog */); // Wait for durability of the new config document. - JournalFlusher::get(opCtx.get())->waitForJournalFlush(); + try { + JournalFlusher::get(opCtx.get())->waitForJournalFlush(); + } catch (const ExceptionFor<ErrorCodes::InterruptedDueToStorageChange>& e) { + // Anyone changing the storage engine is responsible for copying the on-disk + // configuration between the old engine and the new. + LOGV2_DEBUG(6121300, + 1, + "Storage engine changed while waiting for new config to become durable.", + "error"_attr = e.toStatus()); + } bool isFirstConfig; { diff --git a/src/mongo/db/repl/tenant_migration_recipient_service.cpp b/src/mongo/db/repl/tenant_migration_recipient_service.cpp index 2d826c9d841..6f35ce0d0cb 100644 --- a/src/mongo/db/repl/tenant_migration_recipient_service.cpp +++ b/src/mongo/db/repl/tenant_migration_recipient_service.cpp @@ -229,6 +229,14 @@ public: virtual StatusWith<ReplSetConfig> getCurrentConfig() const final { MONGO_UNREACHABLE; } + + StatusWith<BSONObj> loadLocalConfigDocument(OperationContext* opCtx) const final { + MONGO_UNREACHABLE; + } + + Status storeLocalConfigDocument(OperationContext* opCtx, const BSONObj& config) final { + MONGO_UNREACHABLE; + } }; |