diff options
author | Lingzhi Deng <lingzhi.deng@mongodb.com> | 2021-03-10 19:48:39 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-03-17 01:05:54 +0000 |
commit | ef10e1a9d7e4ba5278ce80190d181d4f5fbd684d (patch) | |
tree | 6af533e8966cfd1c95a64401c286878d17f540c7 | |
parent | 77a1e00c536e2f76327bfb96aff1b3323bbfcc5a (diff) | |
download | mongo-ef10e1a9d7e4ba5278ce80190d181d4f5fbd684d.tar.gz |
SERVER-54267: Update tenant migration recipient currentOp output for cloners stats
8 files changed, 86 insertions, 0 deletions
diff --git a/jstests/replsets/tenant_migration_recipient_current_op.js b/jstests/replsets/tenant_migration_recipient_current_op.js index ca379e2b356..19933a21da1 100644 --- a/jstests/replsets/tenant_migration_recipient_current_op.js +++ b/jstests/replsets/tenant_migration_recipient_current_op.js @@ -44,6 +44,17 @@ const migrationOpts = { const recipientPrimary = tenantMigrationTest.getRecipientPrimary(); +// Initial inserts to test cloner stats. +const dbsToClone = ["db0", "db1", "db2"]; +const collsToClone = ["coll0", "coll1"]; +const docs = [...Array(10).keys()].map((i) => ({x: i})); +for (const db of dbsToClone) { + const tenantDB = tenantMigrationTest.tenantDB(kTenantId, db); + for (const coll of collsToClone) { + tenantMigrationTest.insertDonorDB(tenantDB, coll, docs); + } +} + // Makes sure the fields that are always expected to exist, such as the donorConnectionString, are // correct. function checkStandardFieldsOK(res) { @@ -201,5 +212,32 @@ assert.eq(currOp.state, migrationStates.kDone, tojson(res)); assert.eq(currOp.migrationCompleted, true, tojson(res)); assert(currOp.expireAt, tojson(res)); +assert(currOp.hasOwnProperty("databases")); +assert.eq(0, currOp.databases.databasesClonedBeforeFailover, tojson(res)); +assert.eq(dbsToClone.length, currOp.databases.databasesToClone, tojson(res)); +assert.eq(dbsToClone.length, currOp.databases.databasesCloned, tojson(res)); +for (const db of dbsToClone) { + const tenantDB = tenantMigrationTest.tenantDB(kTenantId, db); + assert(currOp.databases.hasOwnProperty(tenantDB), tojson(res)); + const dbStats = currOp.databases[tenantDB]; + assert.eq(0, dbStats.clonedCollectionsBeforeFailover, tojson(res)); + assert.eq(collsToClone.length, dbStats.collections, tojson(res)); + assert.eq(collsToClone.length, dbStats.clonedCollections, tojson(res)); + assert(dbStats.hasOwnProperty("start"), tojson(res)); + assert(dbStats.hasOwnProperty("end"), tojson(res)); + assert.neq(0, dbStats.elapsedMillis, tojson(res)); + for (const coll of collsToClone) { + assert(dbStats.hasOwnProperty(`${tenantDB}.${coll}`), tojson(res)); + const collStats = dbStats[`${tenantDB}.${coll}`]; + assert.eq(docs.length, collStats.documentsToCopy, tojson(res)); + assert.eq(docs.length, collStats.documentsCopied, tojson(res)); + assert.eq(1, collStats.indexes, tojson(res)); + assert.eq(collStats.insertedBatches, collStats.receivedBatches, tojson(res)); + assert(collStats.hasOwnProperty("start"), tojson(res)); + assert(collStats.hasOwnProperty("end"), tojson(res)); + assert.neq(0, collStats.elapsedMillis, tojson(res)); + } +} + tenantMigrationTest.stop(); })(); diff --git a/src/mongo/db/repl/tenant_all_database_cloner.cpp b/src/mongo/db/repl/tenant_all_database_cloner.cpp index 85c580ef3b7..dd0e1f3e113 100644 --- a/src/mongo/db/repl/tenant_all_database_cloner.cpp +++ b/src/mongo/db/repl/tenant_all_database_cloner.cpp @@ -161,6 +161,14 @@ BaseCloner::AfterStageBehavior TenantAllDatabaseCloner::listExistingDatabasesSta const auto& lastClonedDb = clonedDatabases.back(); const auto& startingDb = std::lower_bound(_databases.begin(), _databases.end(), lastClonedDb); + { + stdx::lock_guard<Latch> lk(_mutex); + if (startingDb != _databases.end() && *startingDb == lastClonedDb) { + _stats.databasesClonedBeforeFailover = clonedDatabases.size() - 1; + } else { + _stats.databasesClonedBeforeFailover = clonedDatabases.size(); + } + } _databases.erase(_databases.begin(), startingDb); if (!_databases.empty()) { LOGV2(5271502, @@ -183,6 +191,7 @@ void TenantAllDatabaseCloner::postStage() { { stdx::lock_guard<Latch> lk(_mutex); _stats.databasesCloned = 0; + _stats.databasesToClone = _databases.size(); _stats.databaseStats.reserve(_databases.size()); for (const auto& dbName : _databases) { _stats.databaseStats.emplace_back(); @@ -256,6 +265,9 @@ BSONObj TenantAllDatabaseCloner::Stats::toBSON() const { } void TenantAllDatabaseCloner::Stats::append(BSONObjBuilder* builder) const { + builder->appendNumber("databasesClonedBeforeFailover", + static_cast<long long>(databasesClonedBeforeFailover)); + builder->appendNumber("databasesToClone", static_cast<long long>(databasesToClone)); builder->appendNumber("databasesCloned", static_cast<long long>(databasesCloned)); for (auto&& db : databaseStats) { BSONObjBuilder dbBuilder(builder->subobjStart(db.dbname)); diff --git a/src/mongo/db/repl/tenant_all_database_cloner.h b/src/mongo/db/repl/tenant_all_database_cloner.h index 68e417d7459..86729055fd0 100644 --- a/src/mongo/db/repl/tenant_all_database_cloner.h +++ b/src/mongo/db/repl/tenant_all_database_cloner.h @@ -42,7 +42,9 @@ namespace repl { class TenantAllDatabaseCloner final : public TenantBaseCloner { public: struct Stats { + size_t databasesToClone{0}; size_t databasesCloned{0}; + size_t databasesClonedBeforeFailover{0}; std::vector<TenantDatabaseCloner::Stats> databaseStats; std::string toString() const; diff --git a/src/mongo/db/repl/tenant_all_database_cloner_test.cpp b/src/mongo/db/repl/tenant_all_database_cloner_test.cpp index c05c035b094..c736493c0d6 100644 --- a/src/mongo/db/repl/tenant_all_database_cloner_test.cpp +++ b/src/mongo/db/repl/tenant_all_database_cloner_test.cpp @@ -392,6 +392,8 @@ TEST_F(TenantAllDatabaseClonerTest, ResumingFromLastClonedDb) { auto databases = getDatabasesFromCloner(cloner.get()); ASSERT_EQUALS(1u, databases.size()); ASSERT_EQUALS(_tenantDbAAB, databases[0]); + + ASSERT_EQUALS(1, cloner->getStats().databasesClonedBeforeFailover); } TEST_F(TenantAllDatabaseClonerTest, LastClonedDbDeleted_AllGreater) { @@ -415,6 +417,8 @@ TEST_F(TenantAllDatabaseClonerTest, LastClonedDbDeleted_AllGreater) { ASSERT_EQUALS(2u, databases.size()); ASSERT_EQUALS(_tenantDbAAB, databases[0]); ASSERT_EQUALS(_tenantDbABC, databases[1]); + + ASSERT_EQUALS(1, cloner->getStats().databasesClonedBeforeFailover); } TEST_F(TenantAllDatabaseClonerTest, LastClonedDbDeleted_SomeGreater) { @@ -439,6 +443,8 @@ TEST_F(TenantAllDatabaseClonerTest, LastClonedDbDeleted_SomeGreater) { auto databases = getDatabasesFromCloner(cloner.get()); ASSERT_EQUALS(1u, databases.size()); ASSERT_EQUALS(_tenantDbABC, databases[0]); + + ASSERT_EQUALS(2, cloner->getStats().databasesClonedBeforeFailover); } TEST_F(TenantAllDatabaseClonerTest, LastClonedDbDeleted_AllLess) { @@ -463,6 +469,8 @@ TEST_F(TenantAllDatabaseClonerTest, LastClonedDbDeleted_AllLess) { // Nothing to clone. auto databases = getDatabasesFromCloner(cloner.get()); ASSERT_EQUALS(0u, databases.size()); + + ASSERT_EQUALS(3, cloner->getStats().databasesClonedBeforeFailover); } } // namespace repl diff --git a/src/mongo/db/repl/tenant_database_cloner.cpp b/src/mongo/db/repl/tenant_database_cloner.cpp index 81b1a7c0eec..c4c21178f81 100644 --- a/src/mongo/db/repl/tenant_database_cloner.cpp +++ b/src/mongo/db/repl/tenant_database_cloner.cpp @@ -220,6 +220,15 @@ BaseCloner::AfterStageBehavior TenantDatabaseCloner::listExistingCollectionsStag _collections.end(), lastClonedCollectionUUID, [](const auto& collection, const auto& uuid) { return collection.second.uuid < uuid; }); + { + stdx::lock_guard<Latch> lk(_mutex); + if (startingCollection != _collections.end() && + startingCollection->second.uuid == lastClonedCollectionUUID) { + _stats.clonedCollectionsBeforeFailover = clonedCollectionUUIDs.size() - 1; + } else { + _stats.clonedCollectionsBeforeFailover = clonedCollectionUUIDs.size(); + } + } _collections.erase(_collections.begin(), startingCollection); if (!_collections.empty()) { LOGV2(5271601, @@ -322,6 +331,8 @@ BSONObj TenantDatabaseCloner::Stats::toBSON() const { } void TenantDatabaseCloner::Stats::append(BSONObjBuilder* builder) const { + builder->appendNumber("clonedCollectionsBeforeFailover", + static_cast<long long>(clonedCollectionsBeforeFailover)); builder->appendNumber("collections", static_cast<long long>(collections)); builder->appendNumber("clonedCollections", static_cast<long long>(clonedCollections)); if (start != Date_t()) { diff --git a/src/mongo/db/repl/tenant_database_cloner.h b/src/mongo/db/repl/tenant_database_cloner.h index 502755bc279..94413fffefb 100644 --- a/src/mongo/db/repl/tenant_database_cloner.h +++ b/src/mongo/db/repl/tenant_database_cloner.h @@ -47,6 +47,7 @@ public: Date_t end; size_t collections{0}; size_t clonedCollections{0}; + size_t clonedCollectionsBeforeFailover{0}; std::vector<TenantCollectionCloner::Stats> collectionStats; std::string toString() const; diff --git a/src/mongo/db/repl/tenant_database_cloner_test.cpp b/src/mongo/db/repl/tenant_database_cloner_test.cpp index 28ba2e5393a..287a7904115 100644 --- a/src/mongo/db/repl/tenant_database_cloner_test.cpp +++ b/src/mongo/db/repl/tenant_database_cloner_test.cpp @@ -699,6 +699,8 @@ TEST_F(TenantDatabaseClonerTest, ResumingFromLastClonedCollection) { ASSERT_EQUALS(1U, collections.size()); ASSERT_EQ(NamespaceString(_dbName, "b"), collections[0].first); ASSERT_BSONOBJ_EQ(BSON("uuid" << uuid[1]), collections[0].second.toBSON()); + + ASSERT_EQUALS(1, cloner->getStats().clonedCollectionsBeforeFailover); } TEST_F(TenantDatabaseClonerTest, LastClonedCollectionDeleted_AllGreater) { @@ -746,6 +748,8 @@ TEST_F(TenantDatabaseClonerTest, LastClonedCollectionDeleted_AllGreater) { ASSERT_BSONOBJ_EQ(BSON("uuid" << uuid[1]), collections[0].second.toBSON()); ASSERT_EQ(NamespaceString(_dbName, "c"), collections[1].first); ASSERT_BSONOBJ_EQ(BSON("uuid" << uuid[2]), collections[1].second.toBSON()); + + ASSERT_EQUALS(1, cloner->getStats().clonedCollectionsBeforeFailover); } TEST_F(TenantDatabaseClonerTest, LastClonedCollectionDeleted_SomeGreater) { @@ -793,6 +797,8 @@ TEST_F(TenantDatabaseClonerTest, LastClonedCollectionDeleted_SomeGreater) { ASSERT_EQUALS(1U, collections.size()); ASSERT_EQ(NamespaceString(_dbName, "c"), collections[0].first); ASSERT_BSONOBJ_EQ(BSON("uuid" << uuid[2]), collections[0].second.toBSON()); + + ASSERT_EQUALS(2, cloner->getStats().clonedCollectionsBeforeFailover); } TEST_F(TenantDatabaseClonerTest, LastClonedCollectionDeleted_AllLess) { @@ -841,6 +847,8 @@ TEST_F(TenantDatabaseClonerTest, LastClonedCollectionDeleted_AllLess) { // Nothing to clone. ASSERT_EQUALS(0U, collections.size()); + + ASSERT_EQUALS(3, cloner->getStats().clonedCollectionsBeforeFailover); } } // namespace repl diff --git a/src/mongo/db/repl/tenant_migration_recipient_service.cpp b/src/mongo/db/repl/tenant_migration_recipient_service.cpp index 75058f48b96..182d6ef092c 100644 --- a/src/mongo/db/repl/tenant_migration_recipient_service.cpp +++ b/src/mongo/db/repl/tenant_migration_recipient_service.cpp @@ -353,6 +353,12 @@ boost::optional<BSONObj> TenantMigrationRecipientService::Instance::reportForCur static_cast<long long>(_tenantOplogApplier->getNumOpsApplied())); } + if (_tenantAllDatabaseCloner) { + BSONObjBuilder dbsBuilder(bob.subobjStart("databases")); + _tenantAllDatabaseCloner->getStats().append(&dbsBuilder); + dbsBuilder.doneFast(); + } + return bob.obj(); } |