diff options
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/replsets/get_replication_info_helper.js | 38 | ||||
-rw-r--r-- | jstests/replsets/initial_sync_replSetGetStatus.js | 108 |
2 files changed, 130 insertions, 16 deletions
diff --git a/jstests/replsets/get_replication_info_helper.js b/jstests/replsets/get_replication_info_helper.js index 39355e2ceda..0558d8ee5ee 100644 --- a/jstests/replsets/get_replication_info_helper.js +++ b/jstests/replsets/get_replication_info_helper.js @@ -4,12 +4,46 @@ (function() { "use strict"; var name = "getReplicationInfo"; -var replSet = new ReplSetTest({name: name, nodes: 3, oplogSize: 50}); -var nodes = replSet.nodeList(); +const replSet = new ReplSetTest({name: name, nodes: 2, oplogSize: 50}); + replSet.startSet(); replSet.initiate(); var primary = replSet.getPrimary(); + +// Test that db.printSlaveReplicationInfo() and db.printSecondaryReplicationInfo() both print +// out initial sync info when called during an initial sync. +const syncTarget = replSet.add({ + rsConfig: {votes: 0, priority: 0}, + setParameter: { + 'failpoint.forceSyncSourceCandidate': + tojson({mode: 'alwaysOn', data: {hostAndPort: primary.name}}) + } +}); +syncTarget.setSecondaryOk(); +assert.commandWorked(syncTarget.getDB('admin').runCommand( + {configureFailPoint: 'initialSyncHangBeforeFinish', mode: 'alwaysOn'})); +replSet.reInitiate(); + +// Wait for initial sync to pause before it copies the databases. +checkLog.contains(syncTarget, 'initial sync - initialSyncHangBeforeFinish fail point enabled'); +const callPrintSecondaryReplInfo = startParallelShell( + "db.getSiblingDB('admin').printSecondaryReplicationInfo();", syncTarget.port); +callPrintSecondaryReplInfo(); +assert(rawMongoProgramOutput().match("InitialSyncSyncSource: " + primary.name)); +assert(rawMongoProgramOutput().match("InitialSyncRemainingEstimatedDuration: ")); +clearRawMongoProgramOutput(); + +const callPrintSlaveReplInfo = + startParallelShell("db.getSiblingDB('admin').printSlaveReplicationInfo();", syncTarget.port); +callPrintSlaveReplInfo(); +assert(rawMongoProgramOutput().match("InitialSyncSyncSource: " + primary.name)); +assert(rawMongoProgramOutput().match("InitialSyncRemainingEstimatedDuration: ")); +clearRawMongoProgramOutput(); +assert.commandWorked(syncTarget.getDB('admin').runCommand( + {configureFailPoint: 'initialSyncHangBeforeFinish', mode: 'off'})); +replSet.awaitSecondaryNodes(); + for (var i = 0; i < 100; i++) { primary.getDB('test').foo.insert({a: i}); } diff --git a/jstests/replsets/initial_sync_replSetGetStatus.js b/jstests/replsets/initial_sync_replSetGetStatus.js index 57289816d51..8b1d7364e9d 100644 --- a/jstests/replsets/initial_sync_replSetGetStatus.js +++ b/jstests/replsets/initial_sync_replSetGetStatus.js @@ -16,12 +16,24 @@ replSet.startSet(); replSet.initiate(); var primary = replSet.getPrimary(); +const barColl = primary.getDB('pretest').bar; +assert.commandWorked(barColl.insert({a: 1})); +assert.commandWorked(barColl.insert({a: 2})); +assert.commandWorked(barColl.insert({a: 3})); + var coll = primary.getDB('test').foo; assert.writeOK(coll.insert({a: 1})); assert.writeOK(coll.insert({a: 2})); // Add a secondary node but make it hang before copying databases. -var secondary = replSet.add(); +let secondary = replSet.add({ + rsConfig: {votes: 0, priority: 0}, + setParameter: { + 'collectionClonerBatchSize': 2, + 'failpoint.initialSyncHangDuringCollectionClone': + tojson({mode: 'alwaysOn', data: {namespace: barColl.getFullName(), numDocsToClone: 2}}) + } +}); secondary.setSlaveOk(); assert.commandWorked(secondary.getDB('admin').runCommand( @@ -53,23 +65,91 @@ assert.writeOK(coll.insert({a: 4})); assert.commandWorked(secondary.getDB('admin').runCommand( {configureFailPoint: 'initialSyncHangBeforeCopyingDatabases', mode: 'off'})); +// Wait for initial sync to pause halfway through cloning the 'pretest.bar' collection. +checkLog.contains(secondary, + "initial sync - initialSyncHangDuringCollectionClone fail point enabled."); + +const pretestDbRes = assert.commandWorked(secondary.adminCommand({replSetGetStatus: 1})); + +assert.gt(pretestDbRes.initialSyncStatus.totalInitialSyncElapsedMillis, 0); +assert.gt(pretestDbRes.initialSyncStatus.remainingInitialSyncEstimatedMillis, 0); +assert.gt(pretestDbRes.initialSyncStatus.approxTotalDataSize, 0); + +assert.eq(pretestDbRes.initialSyncStatus.databases.pretest.collections, 1); +assert.eq(pretestDbRes.initialSyncStatus.databases.pretest.clonedCollections, 0); + +let barCollRes = pretestDbRes.initialSyncStatus.databases.pretest["pretest.bar"]; +assert.eq(barCollRes.documentsToCopy, 3); +// Even though we set the collectionClonerBatchSize to 2, it is possible for a batch to actually +// return only 1 document. This can lead to us hitting the failpoint in the next batch instead, +// causing us to copy up to 3 documents. +assert.lte(barCollRes.documentsCopied, 3); +assert.gt(barCollRes.bytesToCopy, 0); +assert.gt(barCollRes.approxBytesCopied, 0); +assert.lte(barCollRes.approxBytesCopied, barCollRes.bytesToCopy); +assert.lt(barCollRes.approxBytesCopied, pretestDbRes.initialSyncStatus.approxTotalDataSize); + +const bytesCopiedAdminDb = + pretestDbRes.initialSyncStatus.databases.admin["admin.system.version"].approxBytesCopied + + pretestDbRes.initialSyncStatus.databases.admin["admin.system.keys"].approxBytesCopied; +assert.eq(pretestDbRes.initialSyncStatus.approxTotalBytesCopied, + bytesCopiedAdminDb + barCollRes.approxBytesCopied); +assert.gt(pretestDbRes.initialSyncStatus.approxTotalBytesCopied, 0); + +// The server still has the 'pretest' and 'test' dbs to finish cloning. +assert.eq(pretestDbRes.initialSyncStatus.databases.databasesCloned, 2); +assert.eq(pretestDbRes.initialSyncStatus.databases.databasesToClone, 2); + +assert.commandWorked(secondary.adminCommand( + {configureFailPoint: 'initialSyncHangDuringCollectionClone', mode: "off"})); + // Wait for initial sync to pause right before it finishes. checkLog.contains(secondary, 'initial sync - initialSyncHangBeforeFinish fail point enabled'); -res = assert.commandWorked(secondary.adminCommand({replSetGetStatus: 1})); -assert(res.initialSyncStatus, +const endOfCloningRes = assert.commandWorked(secondary.adminCommand({replSetGetStatus: 1})); +assert(endOfCloningRes.initialSyncStatus, () => "Response should have an 'initialSyncStatus' field: " + tojson(res)); -assert.eq(res.initialSyncStatus.fetchedMissingDocs, 0); -assert.eq(res.initialSyncStatus.appliedOps, 3); -assert.eq(res.initialSyncStatus.failedInitialSyncAttempts, 0); -assert.eq(res.initialSyncStatus.maxFailedInitialSyncAttempts, 10); -assert.eq(res.initialSyncStatus.databases.databasesCloned, 3); -assert.eq(res.initialSyncStatus.databases.test.collections, 1); -assert.eq(res.initialSyncStatus.databases.test.clonedCollections, 1); -assert.eq(res.initialSyncStatus.databases.test["test.foo"].documentsToCopy, 4); -assert.eq(res.initialSyncStatus.databases.test["test.foo"].documentsCopied, 4); -assert.eq(res.initialSyncStatus.databases.test["test.foo"].indexes, 1); -assert.eq(res.initialSyncStatus.databases.test["test.foo"].fetchedBatches, 1); + +// Assert metrics have progressed in the right direction since the last time we checked the metrics. +assert.gt(endOfCloningRes.initialSyncStatus.totalInitialSyncElapsedMillis, + pretestDbRes.initialSyncStatus.totalInitialSyncElapsedMillis); +assert.lt(endOfCloningRes.initialSyncStatus.remainingInitialSyncEstimatedMillis, + pretestDbRes.initialSyncStatus.remainingInitialSyncEstimatedMillis); +assert.gt(endOfCloningRes.initialSyncStatus.approxTotalBytesCopied, + pretestDbRes.initialSyncStatus.approxTotalBytesCopied); +assert.eq(endOfCloningRes.initialSyncStatus.approxTotalDataSize, + pretestDbRes.initialSyncStatus.approxTotalDataSize); + +assert.eq(endOfCloningRes.initialSyncStatus.failedInitialSyncAttempts, 0); +assert.eq(endOfCloningRes.initialSyncStatus.maxFailedInitialSyncAttempts, 10); + +assert.eq(endOfCloningRes.initialSyncStatus.databases.databasesCloned, 4); +assert.eq(endOfCloningRes.initialSyncStatus.databases.databasesToClone, 0); + +assert.eq(endOfCloningRes.initialSyncStatus.databases.pretest.collections, 1); +assert.eq(endOfCloningRes.initialSyncStatus.databases.pretest.clonedCollections, 1); +barCollRes = endOfCloningRes.initialSyncStatus.databases.pretest["pretest.bar"]; +assert.eq(barCollRes.documentsToCopy, 3); +assert.eq(barCollRes.documentsCopied, 3); +assert.eq(barCollRes.indexes, 1); +assert.lte(barCollRes.fetchedBatches, 2); +assert.gt(barCollRes.bytesToCopy, 0); +assert.eq(barCollRes.approxBytesCopied, barCollRes.bytesToCopy); + +let fooCollRes = endOfCloningRes.initialSyncStatus.databases.test["test.foo"]; +assert.eq(endOfCloningRes.initialSyncStatus.databases.test.collections, 1); +assert.eq(endOfCloningRes.initialSyncStatus.databases.test.clonedCollections, 1); +assert.eq(fooCollRes.documentsToCopy, 4); +assert.eq(fooCollRes.documentsCopied, 4); +assert.eq(fooCollRes.indexes, 1); +assert.lte(fooCollRes.fetchedBatches, 2); +assert.gt(fooCollRes.bytesToCopy, 0); +assert.eq(fooCollRes.approxBytesCopied, fooCollRes.bytesToCopy); + +assert.eq(endOfCloningRes.initialSyncStatus.approxTotalDataSize, + endOfCloningRes.initialSyncStatus.approxTotalBytesCopied); +assert.eq(endOfCloningRes.initialSyncStatus.approxTotalBytesCopied, + fooCollRes.approxBytesCopied + barCollRes.approxBytesCopied + bytesCopiedAdminDb); // Let initial sync finish and get into secondary state. assert.commandWorked(secondary.getDB('admin').runCommand( |