124 lines
4.1 KiB
JavaScript
124 lines
4.1 KiB
JavaScript
//
|
|
// Tests during chunk migration that the recipient does not receive out of range deletes from
|
|
// the donor.
|
|
//
|
|
// Pauses the migration on the recipient shard after the initial data chunk cloning is finished.
|
|
// This allows time for the donor shard to perform deletes, half of which are on the migrating
|
|
// chunk. The recipient is then set to continue, collecting the delete mods from the donor, and
|
|
// finishes the migration. A failpoint is set prior to resuming in the recipient shard to fail
|
|
// if it receives an out of chunk range delete from the donor's delete mods log.
|
|
//
|
|
// The idea is that the recipient shard should not be collecting deletes from the donor shard
|
|
// that are not in range and that will unnecessarily prevent the migration from finishing: the
|
|
// migration can only end when donor's log of delete mods for the migrating chunk is empty.
|
|
//
|
|
|
|
load('./jstests/libs/chunk_manipulation_util.js');
|
|
|
|
(function() {
|
|
"use strict";
|
|
|
|
var staticMongod = MongoRunner.runMongod({}); // For startParallelOps.
|
|
|
|
/**
|
|
* Start up new sharded cluster, stop balancer that would interfere in manual chunk management.
|
|
*/
|
|
|
|
var st = new ShardingTest({ shards : 2, mongos : 1 });
|
|
st.stopBalancer();
|
|
|
|
var mongos = st.s0,
|
|
admin = mongos.getDB('admin'),
|
|
shards = mongos.getCollection('config.shards').find().toArray(),
|
|
dbName = "testDB",
|
|
ns = dbName + ".foo",
|
|
coll = mongos.getCollection(ns),
|
|
donor = st.shard0,
|
|
recipient = st.shard1,
|
|
donorColl = donor.getCollection(ns),
|
|
recipientColl = recipient.getCollection(ns);
|
|
|
|
/**
|
|
* Exable sharding, and split collection into two chunks.
|
|
*/
|
|
|
|
// Two chunks
|
|
// Donor: [0, 10) [10, 20)
|
|
// Recipient:
|
|
jsTest.log('Enable sharding of the collection and pre-split into two chunks....');
|
|
assert.commandWorked( admin.runCommand( {enableSharding: dbName} ) );
|
|
st.ensurePrimaryShard(dbName, shards[0]._id);
|
|
assert.commandWorked( admin.runCommand( {shardCollection: ns, key: {a: 1}} ) );
|
|
assert.commandWorked( admin.runCommand( {split: ns, middle: {a: 10}} ) );
|
|
|
|
/**
|
|
* Insert data into collection
|
|
*/
|
|
|
|
// 10 documents in each chunk on the donor
|
|
jsTest.log('Inserting 20 docs into donor shard, 10 in each chunk....');
|
|
for (var i = 0; i < 20; ++i) donorColl.insert( {a: i} );
|
|
assert.eq(null, donorColl.getDB().getLastError());
|
|
assert.eq(20, donorColl.count());
|
|
|
|
/**
|
|
* Set failpoints. Recipient will crash if an out of chunk range data delete is
|
|
* received from donor. Recipient will pause migration after cloning chunk data from donor,
|
|
* before checking delete mods log on donor.
|
|
*/
|
|
|
|
jsTest.log('setting failpoint failMigrationReceivedOutOfRangeDelete');
|
|
assert.commandWorked(recipient.getDB('admin').runCommand( {configureFailPoint: 'failMigrationReceivedOutOfRangeDelete', mode: 'alwaysOn'} ))
|
|
|
|
jsTest.log('setting recipient failpoint cloned');
|
|
pauseMigrateAtStep(recipient, migrateStepNames.cloned);
|
|
|
|
/**
|
|
* Start a moveChunk in the background. Move chunk [10, 20), which has 10 docs,
|
|
* from shard 0 (donor) to shard 1 (recipient). Migration will pause after cloning
|
|
* (when it reaches the recipient failpoint).
|
|
*/
|
|
|
|
// Donor: [0, 10)
|
|
// Recipient: [10, 20)
|
|
jsTest.log('starting migration, pause after cloning...');
|
|
var joinMoveChunk = moveChunkParallel(
|
|
staticMongod,
|
|
st.s0.host,
|
|
{a: 10},
|
|
null,
|
|
coll.getFullName(),
|
|
shards[1]._id);
|
|
|
|
/**
|
|
* Wait for recipient to finish cloning.
|
|
* THEN delete 10 documents on donor, 5 in the migrating chunk and the 5 in the remaining chunk.
|
|
*/
|
|
|
|
jsTest.log('Delete 5 docs from each chunk, migrating chunk and remaining chunk...');
|
|
waitForMigrateStep(recipient, migrateStepNames.cloned);
|
|
donorColl.remove( {$and : [ {a: {$gte: 5}}, {a: {$lt: 15}} ]} );
|
|
|
|
/**
|
|
* Finish migration. Unpause recipient migration, wait for it to collect
|
|
* the delete diffs from donor and finish.
|
|
*/
|
|
|
|
jsTest.log('Continuing and finishing migration...');
|
|
unpauseMigrateAtStep(recipient, migrateStepNames.cloned);
|
|
joinMoveChunk();
|
|
|
|
/**
|
|
* Check documents are where they should be: 5 docs in each shard's chunk.
|
|
*/
|
|
|
|
jsTest.log('Checking that documents are on the shards they should be...');
|
|
assert.eq(5, donorColl.count());
|
|
assert.eq(5, recipientColl.count());
|
|
assert.eq(10, coll.count());
|
|
|
|
jsTest.log('DONE!');
|
|
st.stop();
|
|
|
|
})()
|