Files
mongo/jstests/replsets/initial_sync_rename_collection.js

106 lines
4.4 KiB
JavaScript

/**
* Tests that initial sync is completed successfully if a 'renameCollection' operation
* occurs on the sync source during initial sync.
* See SERVER-4941.
*/
(function() {
'use strict';
load('jstests/replsets/rslib.js');
const basename = 'initial_sync_rename_collection';
jsTestLog('Bring up a replica set');
const rst = new ReplSetTest({name: basename, nodes: 1});
rst.startSet();
rst.initiate();
const db0_name = "db0";
const db1_name = "db1";
const primary = rst.getPrimary();
// Create two separate databases so that we can rename a collection across databases.
const primary_db0 = primary.getDB(db0_name);
const primary_db1 = primary.getDB(db1_name);
jsTestLog("Create collections on primary");
const collRenameWithinDB_name = 'coll_1';
const collRenameAcrossDBs_name = 'coll_2';
const collWithinFinal_name = 'renamed';
const collAcrossFinal_name = 'renamed_across';
// Create two collections on the same database. One will be renamed within the database
// and the other will be renamed to a different database.
assert.writeOK(primary_db0[collRenameWithinDB_name].save({}));
assert.writeOK(primary_db0[collRenameAcrossDBs_name].save({}));
jsTestLog('Waiting for replication');
rst.awaitReplication();
jsTestLog('Bring up a new node');
const secondary = rst.add({setParameter: 'numInitialSyncAttempts=1'});
// Add a fail point that causes the secondary's initial sync to hang before
// copying databases.
assert.commandWorked(secondary.adminCommand(
{configureFailPoint: 'initialSyncHangBeforeCopyingDatabases', mode: 'alwaysOn'}));
jsTestLog('Begin initial sync on secondary');
let conf = rst.getPrimary().getDB('admin').runCommand({replSetGetConfig: 1}).config;
conf.members.push({_id: 1, host: secondary.host, priority: 0, votes: 0});
conf.version++;
assert.commandWorked(rst.getPrimary().getDB('admin').runCommand({replSetReconfig: conf}));
assert.eq(primary, rst.getPrimary(), 'Primary changed after reconfig');
// Confirm that initial sync started on the secondary node.
jsTestLog('Waiting for initial sync to start');
checkLog.contains(secondary,
'initial sync - initialSyncHangBeforeCopyingDatabases fail point enabled');
// Start renaming collections while initial sync is hanging.
jsTestLog('Rename collection ' + db0_name + '.' + collRenameWithinDB_name + ' to ' + db0_name +
'.' + collWithinFinal_name + ' on the sync source ' + db0_name);
assert.commandWorked(
primary_db0[collRenameWithinDB_name].renameCollection(collWithinFinal_name));
jsTestLog('Rename collection ' + db0_name + '.' + collRenameAcrossDBs_name + ' to ' + db1_name +
'.' + collAcrossFinal_name + ' on the sync source ' + db0_name);
assert.commandWorked(primary.adminCommand({
renameCollection: primary_db0[collRenameAcrossDBs_name].getFullName(),
to: primary_db1[collAcrossFinal_name]
.getFullName() // Collection 'renamed_across' is implicitly created.
}));
// Disable fail point so that the secondary can finish its initial sync.
assert.commandWorked(secondary.adminCommand(
{configureFailPoint: 'initialSyncHangBeforeCopyingDatabases', mode: 'off'}));
jsTestLog('Wait for both nodes to be up-to-date');
rst.awaitSecondaryNodes();
rst.awaitReplication();
const secondary_db0 = secondary.getDB(db0_name);
const secondary_db1 = secondary.getDB(db1_name);
jsTestLog('Check that collection was renamed correctly on the secondary');
assert.eq(secondary_db0[collWithinFinal_name].find().itcount(),
1,
'renamed collection does not exist');
assert.eq(secondary_db1[collAcrossFinal_name].find().itcount(),
1,
'renamed_across collection does not exist');
assert.eq(secondary_db0[collRenameWithinDB_name].find().itcount(),
0,
'collection ' + collRenameWithinDB_name +
' still exists after it was supposed to be renamed');
assert.eq(secondary_db0[collRenameAcrossDBs_name].find().itcount(),
0,
'collection ' + collRenameAcrossDBs_name +
' still exists after it was supposed to be renamed');
rst.checkReplicatedDataHashes();
rst.checkOplogs();
rst.stopSet();
})();