// Tests that resharding a collection is detected correctly by all operation types // // The idea here is that a collection may be resharded / unsharded at any point, and any type of // operation on a mongos may be active when it happens. All operations should handle gracefully. // var st = new ShardingTest({ shards : 2, mongos : 5, verbose : 1 }); // Balancer is by default stopped, thus it will not interfere // Use separate mongos for reading, updating, inserting, removing data var readMongos = st.s1; var updateMongos = st.s2; var insertMongos = st.s3; var removeMongos = st.s4; var config = st.s.getDB( "config" ); var admin = st.s.getDB( "admin" ); var coll = st.s.getCollection( "foo.bar" ); insertMongos.getDB( "admin" ).runCommand({ setParameter : 1, traceExceptions : true }); var shards = {}; config.shards.find().forEach( function( doc ){ shards[ doc._id ] = new Mongo( doc.host ); }); // // Set up a sharded collection // jsTest.log( "Enabling sharding for the first time..." ); admin.runCommand({ enableSharding : coll.getDB() + "" }); st.ensurePrimaryShard(coll.getDB().getName(), 'shard0001'); admin.runCommand({ shardCollection : coll + "", key : { _id : 1 } }); assert.writeOK(coll.insert({ hello : "world" })); jsTest.log( "Sharding collection across multiple shards..." ); var getOtherShard = function( shard ){ for( id in shards ){ if( id != shard ) return id; } }; printjson( admin.runCommand({ split : coll + "", middle : { _id : 0 } }) ); printjson( admin.runCommand({ moveChunk : coll + "", find : { _id : 0 }, to : getOtherShard( config.databases.findOne({ _id : coll.getDB() + "" }).primary ) }) ); st.printShardingStatus(); // // Force all mongoses to load the current status of the cluster // jsTest.log( "Loading this status in all mongoses..." ); for( var i = 0; i < st._mongos.length; i++ ){ printjson( st._mongos[i].getDB( "admin" ).runCommand({ flushRouterConfig : 1 }) ); assert.neq( null, st._mongos[i].getCollection( coll + "" ).findOne() ); } // // Drop and recreate a new sharded collection in the same namespace, where the shard and collection // versions are the same, but the split is at a different point. // jsTest.log( "Rebuilding sharded collection with different split..." ); coll.drop(); var droppedCollDoc = config.collections.findOne({ _id: coll.getFullName() }); assert(droppedCollDoc != null); assert.eq(true, droppedCollDoc.dropped); assert(droppedCollDoc.lastmodEpoch != null); assert(droppedCollDoc.lastmodEpoch.equals(new ObjectId("000000000000000000000000")), "epoch not zero: " + droppedCollDoc.lastmodEpoch); admin.runCommand({ enableSharding : coll.getDB() + "" }); st.ensurePrimaryShard(coll.getDB().getName(), 'shard0001'); admin.runCommand({ shardCollection : coll + "", key : { _id : 1 } }); var bulk = coll.initializeUnorderedBulkOp(); for( var i = 0; i < 100; i++ ) bulk.insert({ _id : i }); assert.writeOK(bulk.execute()); printjson( admin.runCommand({ split : coll + "", middle : { _id : 200 } }) ); printjson( admin.runCommand({ moveChunk : coll + "", find : { _id : 200 }, to : getOtherShard( config.databases.findOne({ _id : coll.getDB() + "" }).primary ) }) ); // // Make sure all operations on mongoses aren't tricked by the change // jsTest.log( "Checking other mongoses for detection of change..." ); jsTest.log( "Checking find..." ); // Ensure that finding an element works when resharding assert.neq( null, readMongos.getCollection( coll + "" ).findOne({ _id : 1 }) ); jsTest.log( "Checking update..."); // Ensure that updating an element finds the right location assert.writeOK(updateMongos.getCollection( coll + "" ).update({ _id : 1 }, { $set : { updated : true } })); assert.neq( null, coll.findOne({ updated : true }) ); jsTest.log( "Checking insert..." ); // Ensure that inserting an element finds the right shard assert.writeOK(insertMongos.getCollection( coll + "" ).insert({ _id : 101 })); assert.neq( null, coll.findOne({ _id : 101 }) ); jsTest.log( "Checking remove..." ); // Ensure that removing an element finds the right shard, verified by the mongos doing the sharding assert.writeOK(removeMongos.getCollection( coll + "" ).remove({ _id : 2 })); assert.eq( null, coll.findOne({ _id : 2 }) ); coll.drop(); jsTest.log( "Done!" ); st.stop();