summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingzhi Deng <lingzhi.deng@mongodb.com>2021-03-10 19:48:39 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-17 01:05:54 +0000
commitef10e1a9d7e4ba5278ce80190d181d4f5fbd684d (patch)
tree6af533e8966cfd1c95a64401c286878d17f540c7
parent77a1e00c536e2f76327bfb96aff1b3323bbfcc5a (diff)
downloadmongo-ef10e1a9d7e4ba5278ce80190d181d4f5fbd684d.tar.gz
SERVER-54267: Update tenant migration recipient currentOp output for cloners stats
-rw-r--r--jstests/replsets/tenant_migration_recipient_current_op.js38
-rw-r--r--src/mongo/db/repl/tenant_all_database_cloner.cpp12
-rw-r--r--src/mongo/db/repl/tenant_all_database_cloner.h2
-rw-r--r--src/mongo/db/repl/tenant_all_database_cloner_test.cpp8
-rw-r--r--src/mongo/db/repl/tenant_database_cloner.cpp11
-rw-r--r--src/mongo/db/repl/tenant_database_cloner.h1
-rw-r--r--src/mongo/db/repl/tenant_database_cloner_test.cpp8
-rw-r--r--src/mongo/db/repl/tenant_migration_recipient_service.cpp6
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();
}