diff options
author | nandinibhartiyaMDB <nandini.bhartiya@mongodb.com> | 2023-04-18 15:00:14 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-04-18 17:19:48 +0000 |
commit | 8b937a930ea842507e0924e6beb5371fcd7d5780 (patch) | |
tree | 22752741773196d0e843ccc83f3b8ef9f82292f8 /src | |
parent | ef9529cf74ebda96b48f492a6d9bdbbebc7b054a (diff) | |
download | mongo-8b937a930ea842507e0924e6beb5371fcd7d5780.tar.gz |
SERVER-75657: Add an interface for the Cloner class
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/cloner.cpp | 67 | ||||
-rw-r--r-- | src/mongo/db/cloner.h | 71 | ||||
-rw-r--r-- | src/mongo/db/s/move_primary/move_primary_recipient_service_test.cpp | 8 |
3 files changed, 97 insertions, 49 deletions
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp index 60a2dae15a6..0041768fe28 100644 --- a/src/mongo/db/cloner.cpp +++ b/src/mongo/db/cloner.cpp @@ -75,7 +75,7 @@ MONGO_FAIL_POINT_DEFINE(movePrimaryFailPoint); BSONElement getErrField(const BSONObj& o); -BSONObj Cloner::_getIdIndexSpec(const std::list<BSONObj>& indexSpecs) { +BSONObj DefaultClonerImpl::_getIdIndexSpec(const std::list<BSONObj>& indexSpecs) { for (auto&& indexSpec : indexSpecs) { BSONElement indexName; uassertStatusOK(bsonExtractTypedField( @@ -87,9 +87,7 @@ BSONObj Cloner::_getIdIndexSpec(const std::list<BSONObj>& indexSpecs) { return BSONObj(); } -Cloner::Cloner() {} - -struct Cloner::BatchHandler { +struct DefaultClonerImpl::BatchHandler { BatchHandler(OperationContext* opCtx, const std::string& dbName) : lastLog(0), opCtx(opCtx), _dbName(dbName), numSeen(0), saveLast(0) {} @@ -242,11 +240,11 @@ struct Cloner::BatchHandler { /** * Copy the specified collection. */ -void Cloner::_copy(OperationContext* opCtx, - const std::string& toDBName, - const NamespaceString& nss, - const BSONObj& from_opts, - const BSONObj& from_id_index) { +void DefaultClonerImpl::_copy(OperationContext* opCtx, + const std::string& toDBName, + const NamespaceString& nss, + const BSONObj& from_opts, + const BSONObj& from_id_index) { LOGV2_DEBUG(20414, 2, "\t\tcloning collection", @@ -272,11 +270,11 @@ void Cloner::_copy(OperationContext* opCtx, } } -void Cloner::_copyIndexes(OperationContext* opCtx, - const std::string& toDBName, - const NamespaceString& nss, - const BSONObj& from_opts, - const std::list<BSONObj>& from_indexes) { +void DefaultClonerImpl::_copyIndexes(OperationContext* opCtx, + const std::string& toDBName, + const NamespaceString& nss, + const BSONObj& from_opts, + const std::list<BSONObj>& from_indexes) { LOGV2_DEBUG(20415, 2, "\t\t copyIndexes", @@ -312,7 +310,7 @@ void Cloner::_copyIndexes(OperationContext* opCtx, }); } -StatusWith<std::vector<BSONObj>> Cloner::_filterCollectionsForClone( +StatusWith<std::vector<BSONObj>> DefaultClonerImpl::_filterCollectionsForClone( const std::string& fromDBName, const std::list<BSONObj>& initialCollections) { std::vector<BSONObj> finalCollections; for (auto&& collection : initialCollections) { @@ -346,7 +344,7 @@ StatusWith<std::vector<BSONObj>> Cloner::_filterCollectionsForClone( return finalCollections; } -Status Cloner::_createCollectionsForDb( +Status DefaultClonerImpl::_createCollectionsForDb( OperationContext* opCtx, const std::vector<CreateCollectionParams>& createCollectionParams, const std::string& dbName) { @@ -441,9 +439,9 @@ Status Cloner::_createCollectionsForDb( return Status::OK(); } -Status Cloner::setupConn(OperationContext* opCtx, - const std::string& dBName, - const std::string& masterHost) { +Status DefaultClonerImpl::setupConn(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost) { invariant(!_conn); invariant(!opCtx->lockState()->isLocked()); auto statusWithMasterHost = ConnectionString::parse(masterHost); @@ -487,9 +485,8 @@ Status Cloner::setupConn(OperationContext* opCtx, return Status::OK(); } -StatusWith<std::vector<BSONObj>> Cloner::getListOfCollections(OperationContext* opCtx, - const std::string& dBName, - const std::string& masterHost) { +StatusWith<std::vector<BSONObj>> DefaultClonerImpl::getListOfCollections( + OperationContext* opCtx, const std::string& dBName, const std::string& masterHost) { invariant(!opCtx->lockState()->isLocked()); std::vector<BSONObj> collsToClone; if (!_conn) { @@ -505,11 +502,11 @@ StatusWith<std::vector<BSONObj>> Cloner::getListOfCollections(OperationContext* return _filterCollectionsForClone(dBName, initialCollections); } -Status Cloner::copyDb(OperationContext* opCtx, - const std::string& dBName, - const std::string& masterHost, - const std::vector<NamespaceString>& shardedColls, - std::set<std::string>* clonedColls) { +Status DefaultClonerImpl::copyDb(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost, + const std::vector<NamespaceString>& shardedColls, + std::set<std::string>* clonedColls) { invariant(clonedColls && clonedColls->empty(), str::stream() << masterHost << ":" << dBName); // This function can potentially block for a long time on network activity, so holding of locks // is disallowed. @@ -615,4 +612,20 @@ Status Cloner::copyDb(OperationContext* opCtx, return Status::OK(); } +Cloner::Cloner() : Cloner(std::make_unique<DefaultClonerImpl>()) {} + +Status Cloner::copyDb(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost, + const std::vector<NamespaceString>& shardedColls, + std::set<std::string>* clonedColls) { + return _clonerImpl->copyDb(opCtx, dBName, masterHost, shardedColls, clonedColls); +} + +StatusWith<std::vector<BSONObj>> Cloner::getListOfCollections(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost) { + return _clonerImpl->getListOfCollections(opCtx, dBName, masterHost); +} + } // namespace mongo diff --git a/src/mongo/db/cloner.h b/src/mongo/db/cloner.h index 761da5a052c..5adce5521b2 100644 --- a/src/mongo/db/cloner.h +++ b/src/mongo/db/cloner.h @@ -45,15 +45,25 @@ class DBClientBase; class NamespaceString; class OperationContext; -// TODO SERVER-75657: Create an interface for the Cloner. +class ClonerImpl { +public: + virtual ~ClonerImpl() = default; + virtual Status copyDb(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost, + const std::vector<NamespaceString>& shardedColls, + std::set<std::string>* clonedColls) = 0; -class Cloner { - Cloner(const Cloner&) = delete; - Cloner& operator=(const Cloner&) = delete; + virtual Status setupConn(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost) = 0; + + virtual StatusWith<std::vector<BSONObj>> getListOfCollections( + OperationContext* opCtx, const std::string& dBName, const std::string& masterHost) = 0; +}; +class DefaultClonerImpl : public ClonerImpl { public: - Cloner(); - virtual ~Cloner() {} /** * Copies an entire database from the specified host. * clonedColls: the function will return with this populated with a list of the collections that @@ -62,21 +72,21 @@ public: * that are cloned. When opts.createCollections is true, this parameter is * ignored and the collection list is fetched from the remote via _conn. */ - virtual Status copyDb(OperationContext* opCtx, - const std::string& dBName, - const std::string& masterHost, - const std::vector<NamespaceString>& shardedColls, - std::set<std::string>* clonedColls); + Status copyDb(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost, + const std::vector<NamespaceString>& shardedColls, + std::set<std::string>* clonedColls) override; - virtual Status setupConn(OperationContext* opCtx, - const std::string& dBName, - const std::string& masterHost); + Status setupConn(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost) override; - virtual StatusWith<std::vector<BSONObj>> getListOfCollections(OperationContext* opCtx, - const std::string& dBName, - const std::string& masterHost); + StatusWith<std::vector<BSONObj>> getListOfCollections(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost) override; -protected: +private: std::unique_ptr<ScopedDbConnection> _conn; // Filters a database's collection list and removes collections that should not be cloned. @@ -121,4 +131,29 @@ protected: } }; +class Cloner { + +public: + Cloner(std::unique_ptr<ClonerImpl> clonerImpl) : _clonerImpl(std::move(clonerImpl)) {} + + Cloner(); + + Cloner(const Cloner&) = delete; + + Cloner& operator=(const Cloner&) = delete; + + Status copyDb(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost, + const std::vector<NamespaceString>& shardedColls, + std::set<std::string>* clonedColls); + + StatusWith<std::vector<BSONObj>> getListOfCollections(OperationContext* opCtx, + const std::string& dBName, + const std::string& masterHost); + +private: + std::unique_ptr<ClonerImpl> _clonerImpl; +}; + } // namespace mongo diff --git a/src/mongo/db/s/move_primary/move_primary_recipient_service_test.cpp b/src/mongo/db/s/move_primary/move_primary_recipient_service_test.cpp index b6822c9184f..2b02e8bb20d 100644 --- a/src/mongo/db/s/move_primary/move_primary_recipient_service_test.cpp +++ b/src/mongo/db/s/move_primary/move_primary_recipient_service_test.cpp @@ -81,7 +81,7 @@ static HostAndPort makeHostAndPort(const ShardId& shardId) { } } // namespace -class ClonerForTest : public Cloner { +class TestClonerImpl : public ClonerImpl { Status copyDb(OperationContext* opCtx, const std::string& dBName, const std::string& masterHost, @@ -144,7 +144,7 @@ public: recipientStateDoc, std::make_shared<MovePrimaryRecipientExternalStateForTest>(), _serviceContext, - std::make_unique<ClonerForTest>()); + std::make_unique<Cloner>(std::make_unique<TestClonerImpl>())); } StringData getServiceName() const { @@ -718,7 +718,7 @@ TEST_F(MovePrimaryRecipientServiceTest, AbortsOnUnrecoverableClonerError) { // Step Down to register new POS before Step Up. stepDown(_serviceCtx, _registry); - class FailingCloner : public ClonerForTest { + class FailingCloner : public TestClonerImpl { Status copyDb(OperationContext* opCtx, const std::string& dBName, const std::string& masterHost, @@ -744,7 +744,7 @@ TEST_F(MovePrimaryRecipientServiceTest, AbortsOnUnrecoverableClonerError) { recipientStateDoc, std::make_shared<MovePrimaryRecipientExternalStateForTest>(), _serviceContext, - std::make_unique<FailingCloner>()); + std::make_unique<Cloner>(std::make_unique<FailingCloner>())); } StringData getServiceName() const override { |