diff options
author | Antonin Kral <a.kral@bobek.cz> | 2011-12-15 09:35:47 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2011-12-15 09:35:47 +0100 |
commit | f0d9a01bccdaeb466c12c92057914bbfef59526c (patch) | |
tree | 7679efa1f0daf7d1d906882a15dc77af6b7aef32 /shell/collection.js | |
parent | 5d342a758c6095b4d30aba0750b54f13b8916f51 (diff) | |
download | mongodb-f0d9a01bccdaeb466c12c92057914bbfef59526c.tar.gz |
Imported Upstream version 2.0.2
Diffstat (limited to 'shell/collection.js')
-rw-r--r-- | shell/collection.js | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/shell/collection.js b/shell/collection.js index 1e6fe03..cb7035d 100644 --- a/shell/collection.js +++ b/shell/collection.js @@ -62,6 +62,7 @@ DBCollection.prototype.help = function () { print("\tdb." + shortName + ".update(query, object[, upsert_bool, multi_bool])"); print("\tdb." + shortName + ".validate( <full> ) - SLOW");; print("\tdb." + shortName + ".getShardVersion() - only for use with sharding"); + print("\tdb." + shortName + ".getShardDistribution() - prints statistics about data distribution in the cluster"); return __magicNoPrint; } @@ -654,3 +655,190 @@ DBCollection.autocomplete = function(obj){ } return ret; } + + +// Sharding additions + +/* +Usage : + +mongo <mongos> +> load('path-to-file/shardingAdditions.js') +Loading custom sharding extensions... +true + +> var collection = db.getMongo().getCollection("foo.bar") +> collection.getShardDistribution() // prints statistics related to the collection's data distribution + +> collection.getSplitKeysForChunks() // generates split points for all chunks in the collection, based on the + // default maxChunkSize or alternately a specified chunk size +> collection.getSplitKeysForChunks( 10 ) // Mb + +> var splitter = collection.getSplitKeysForChunks() // by default, the chunks are not split, the keys are just + // found. A splitter function is returned which will actually + // do the splits. + +> splitter() // ! Actually executes the splits on the cluster ! + +*/ + +DBCollection.prototype.getShardDistribution = function(){ + + var stats = this.stats() + + if( ! stats.sharded ){ + print( "Collection " + this + " is not sharded." ) + return + } + + var config = this.getMongo().getDB("config") + + var numChunks = 0 + + for( var shard in stats.shards ){ + + var shardDoc = config.shards.findOne({ _id : shard }) + + print( "\nShard " + shard + " at " + shardDoc.host ) + + var shardStats = stats.shards[ shard ] + + var chunks = config.chunks.find({ _id : sh._collRE( coll ), shard : shard }).toArray() + + numChunks += chunks.length + + var estChunkData = shardStats.size / chunks.length + var estChunkCount = Math.floor( shardStats.count / chunks.length ) + + print( " data : " + sh._dataFormat( shardStats.size ) + + " docs : " + shardStats.count + + " chunks : " + chunks.length ) + print( " estimated data per chunk : " + sh._dataFormat( estChunkData ) ) + print( " estimated docs per chunk : " + estChunkCount ) + + } + + print( "\nTotals" ) + print( " data : " + sh._dataFormat( stats.size ) + + " docs : " + stats.count + + " chunks : " + numChunks ) + for( var shard in stats.shards ){ + + var shardStats = stats.shards[ shard ] + + var estDataPercent = Math.floor( shardStats.size / stats.size * 10000 ) / 100 + var estDocPercent = Math.floor( shardStats.count / stats.count * 10000 ) / 100 + + print( " Shard " + shard + " contains " + estDataPercent + "% data, " + estDocPercent + "% docs in cluster, " + + "avg obj size on shard : " + sh._dataFormat( stats.shards[ shard ].avgObjSize ) ) + } + + print( "\n" ) + +} + +// In testing phase, use with caution +DBCollection.prototype._getSplitKeysForChunks = function( chunkSize ){ + + var stats = this.stats() + + if( ! stats.sharded ){ + print( "Collection " + this + " is not sharded." ) + return + } + + var config = this.getMongo().getDB("config") + + if( ! chunkSize ){ + chunkSize = config.settings.findOne({ _id : "chunksize" }).value + print( "Chunk size not set, using default of " + chunkSize + "Mb" ) + } + else{ + print( "Using chunk size of " + chunkSize + "Mb" ) + } + + var shardDocs = config.shards.find().toArray() + + var allSplitPoints = {} + var numSplits = 0 + + for( var i = 0; i < shardDocs.length; i++ ){ + + var shardDoc = shardDocs[i] + var shard = shardDoc._id + var host = shardDoc.host + var sconn = new Mongo( host ) + + var chunks = config.chunks.find({ _id : sh._collRE( this ), shard : shard }).toArray() + + print( "\nGetting split points for chunks on shard " + shard + " at " + host ) + + var splitPoints = [] + + for( var j = 0; j < chunks.length; j++ ){ + var chunk = chunks[j] + var result = sconn.getDB("admin").runCommand({ splitVector : this + "", min : chunk.min, max : chunk.max, maxChunkSize : chunkSize }) + if( ! result.ok ){ + print( " Had trouble getting split keys for chunk " + sh._pchunk( chunk ) + " :\n" ) + printjson( result ) + } + else{ + splitPoints = splitPoints.concat( result.splitKeys ) + + if( result.splitKeys.length > 0 ) + print( " Added " + result.splitKeys.length + " split points for chunk " + sh._pchunk( chunk ) ) + } + } + + print( "Total splits for shard " + shard + " : " + splitPoints.length ) + + numSplits += splitPoints.length + allSplitPoints[ shard ] = splitPoints + + } + + // Get most recent migration + var migration = config.changelog.find({ what : /^move.*/ }).sort({ time : -1 }).limit( 1 ).toArray() + if( migration.length == 0 ) + print( "\nNo migrations found in changelog." ) + else { + migration = migration[0] + print( "\nMost recent migration activity was on " + migration.ns + " at " + migration.time ) + } + + var admin = this.getMongo().getDB("admin") + var coll = this + var splitFunction = function(){ + + // Turn off the balancer, just to be safe + print( "Turning off balancer..." ) + config.settings.update({ _id : "balancer" }, { $set : { stopped : true } }, true ) + print( "Sleeping for 30s to allow balancers to detect change. To be extra safe, check config.changelog" + + " for recent migrations." ) + sleep( 30000 ) + + for( shard in allSplitPoints ){ + for( var i = 0; i < allSplitPoints[ shard ].length; i++ ){ + var splitKey = allSplitPoints[ shard ][i] + print( "Splitting at " + tojson( splitKey ) ) + printjson( admin.runCommand({ split : coll + "", middle : splitKey }) ) + } + } + + print( "Turning the balancer back on." ) + config.settings.update({ _id : "balancer" }, { $set : { stopped : false } } ) + sleep( 1 ) + } + + print( "\nGenerated " + numSplits + " split keys, run output function to perform splits.\n" + + " ex : \n" + + " > var splitter = <collection>.getSplitKeysForChunks()\n" + + " > splitter() // Execute splits on cluster !\n" ) + + return splitFunction + +} + + + + |