Skip to content

Instantly share code, notes, and snippets.

@jasoares
Last active December 18, 2017 02:16
Show Gist options
  • Save jasoares/3b21af33a7d62263010f to your computer and use it in GitHub Desktop.
Save jasoares/3b21af33a7d62263010f to your computer and use it in GitHub Desktop.
MongoDB Shell mongos helpers and custom prompt
/**
* MongoDB Shell mongos helper functions and custom prompt
*
* https://gist.github.com/jasoares/3b21af33a7d62263010f
*/
sh.getBalancerSummary = function(since) {
// 24 hours by default
since = since || new Date(ISODate().getTime() - 1000 * 60 * 60 * 24);
print("Printing Summary since " + since);
return db.getSiblingDB('config').changelog.aggregate([
{ '$match': { '$and': [{ 'time': { '$gt': since } },
{ 'what': 'moveChunk.from' }] } },
{ '$group': { _id: '$details.note', ns: { '$addToSet': '$ns' }, count: { '$sum': 1 } } }
]).pretty();
};
sh.getBalancerErrorDetails = function(since) {
// 24 hours by default
since = since || new Date(ISODate().getTime() - 1000 * 60 * 60 * 24);
print("Printing Summary since " + since);
return db.getSiblingDB('config').changelog.aggregate([
{ '$sort': { time: 1 } },
{ '$match': { '$and': [{ 'time': { '$gt': since } }, { 'what': 'moveChunk.from' }] } },
{ '$project': { _id: 0, ns: 1, time: 1, to: '$details.to', note: '$details.note', error: '$details.errmsg' } },
{ '$group': { _id: { ns: '$ns', to: '$to' }, time: { '$last': '$time' }, last_error_note: { '$last': '$note' }, last_error_msg: { '$last': '$error' } } },
{ '$match': { '$and': [{ last_error_note: 'aborted' }] } }, { '$sort': { '_id.ns': 1, '_id.to': 1 } }
]).pretty();
};
sh.getBalancerSuccessMoves = function(since) {
// 24 hours by default
since = since || new Date(ISODate().getTime() - 1000 * 60 * 60 * 24);
print("Printing Summary since " + since);
return db.getSiblingDB('config').changelog.aggregate([
{ '$match': { '$and': [{ 'time': { '$gt': since } }, { 'what': 'moveChunk.from' }, { 'details.note': 'success' }] } },
{ '$group': { _id: { ns: '$ns', to: '$details.to' }, lastSuccess: { '$last': '$time' }, last_result: { '$last': '$details.note' }, count: { '$sum': 1 } } },
{ '$sort': { 'lastSuccess': -1, '_id.ns': 1, '_id.to': 1 } }
]);
};
sh.getBalancerCurrentChunkMigration = function() {
var migrateChunk = db.getSiblingDB('config').locks.findOne({ state: 2, why: /migrating chunk/ });
if (migrateChunk == null) {
print("No chunk being migrated right now!");
return;
}
var ns = migrateChunk._id;
var moveChunkStart = db.getSiblingDB('config').changelog.find({ what: 'moveChunk.start', ns: ns }, { time: 1, details: 1 }).sort({ time: -1 }).limit(1);
var move = moveChunkStart.next();
print("Currently migrating chunk of " + ns + " from " + move['details']['from'] + " to " + move['details']['to'] + " since " + move['time']);
};
sh.getUnbalancedCollectionList = function(minTotalChunks, minChunkPercentage, limit) {
var minTotalChunks = minTotalChunks || 8;
var minChunkPercentage = minChunkPercentage || 0.20;
var limit = limit || 5;
var configDB = db.getSiblingDB('config');
return configDB.chunks.aggregate([
{ '$group': { _id: { ns: '$ns', shard: '$shard' }, count: { '$sum': 1 } } },
{ '$group': { _id: '$_id.ns', total: { '$sum': '$count' }, max: { '$max': '$count' } } },
{ '$project': { _id: 1, total: 1, max: 1, perc: { '$divide': [ '$max', '$total'] } } },
{ '$match': { '$and': [{ total: { '$gt': minTotalChunks } }, { perc: { '$gt': minChunkPercentage } }] } },
{ '$sort': { total: -1, perc: 1 } },
{ '$limit': limit }
]);
};
sh.getUnbalancedCollections = function(minTotalChunks, minChunkPercentage, limit) {
var configDB = db.getSiblingDB('config');
var unbalancedCollections = sh.getUnbalancedCollectionList(minTotalChunks, minChunkPercentage, limit);
while(unbalancedCollections.hasNext()) {
var nsInfo = unbalancedCollections.next();
var total = nsInfo['total'];
var max = nsInfo['max'];
var perc = nsInfo['perc'];
var coll = nsInfo['_id'];
print("Collection: " + coll);
var shardCounts = configDB.chunks.aggregate([
{ '$match': { ns: coll } },
{ '$group': { _id: { ns: '$ns', shard: '$shard' }, count: { '$sum': 1 } } },
{ '$sort': { '_id.shard': 1 } }
]);
var shardString = "Max: " + max + "(" + (Math.round((perc + 0.00001) * 100)) + "%) | Total:" + total + " | Shards: ";
while(shardCounts.hasNext()) {
var shardCount = shardCounts.next();
shardString += (shardCount['_id']['shard'] + ": " + shardCount['count'] + " ");
};
print(shardString + "\n");
};
};
sh.getShardDistributionForTopUnbalancedCollections = function(minTotalChunks, minChunkPercentage, limit) {
var unbalancedCollections = sh.getUnbalancedCollectionList(minTotalChunks, minChunkPercentage, limit);
while(unbalancedCollections.hasNext()) {
var ns = unbalancedCollections.next()['_id'];
var database = ns.split('.')[0];
var collection = ns.split('.')[1];
print("Shard distribution for collection: " + ns);
db.getSiblingDB(database)[collection].getShardDistribution();
};
};
sh.disableBalancingForAllCollections = function() {
var allCollections = db.getSiblingDB('config').collections.find();
while(allCollections.hasNext()) {
var coll = allCollections.next()['_id']; sh.disableBalancing(coll);
};
};
sh.enableBalancingForAllCollections = function() {
var allCollections = db.getSiblingDB('config').collections.find();
while(allCollections.hasNext()) {
var coll = allCollections.next()['_id']; sh.enableBalancing(coll);
};
};
sh.enableBalancingForTopUnbalancedCollections = function(minTotalChunks, minChunkPercentage, top) {
var unbalancedCollections = sh.getUnbalancedCollectionList(minTotalChunks, minChunkPercentage, top);
while(unbalancedCollections.hasNext()) {
var coll = unbalancedCollections.next()['_id'];
sh.enableBalancing(coll)
print("Enabled balancer for " + coll);
}
};
sh.getCollectionsActiveForBalancing = function() {
var activeCollections = db.getSiblingDB('config').collections.find({ '$or': [{ noBalance: false }, { noBalance: { '$exists': false } }] });
print("Collections active for balancing:");
while(activeCollections.hasNext()) {
var coll = activeCollections.next()['_id'];
print(coll);
};
};
cmdCount = 0;
host = db.serverStatus().host;
process = db.serverStatus().process;
prompt = function() {
return process + "@" + host + "[" + db + "]:" + (cmdCount++) + ">";
};
@stevenferrer
Copy link

sweet!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment