Skip to content

Instantly share code, notes, and snippets.

@nivs
Created July 28, 2015 18:37
Show Gist options
  • Save nivs/7adbbe2c7f4a77202698 to your computer and use it in GitHub Desktop.
Save nivs/7adbbe2c7f4a77202698 to your computer and use it in GitHub Desktop.
function mergeEmptyChunks(namespace) {
assert(isString(namespace) && namespace.length, "No namespace specified");
var databaseName = namespace.split(".")[0];
assert(databaseName != namespace, "Namespace should be database.collection");
var database = db.getSiblingDB(databaseName);
assert(database, "Database " + databaseName + " not found");
//print("stop balancer");
//sh.stopBalancer();
assert(sh.getBalancerState() == false, "Balancer is not off");
assert(sh.isBalancerRunning() == false, "Balancer is running");
// based on Maurizio Merli's post
// https://medium.com/@dash1e/mongodb-merge-all-empty-chunks-6e367680f78d
var configdb = db.getSiblingDB("config");
var admindb = db.getSiblingDB("admin");
var minchunk = null;
var count = 0;
try {
configdb.chunks.find({ns : namespace}).sort({min: 1}).forEach(function(chunk) {
var ds = database.runCommand({
datasize: namespace,
keyPattern: { "_id": 1 },
min: chunk.min,
max: chunk.max });
if (minchunk != null) {
if (minchunk.shard != chunk.shard) {
while(true) {
print("move empty chunk: " + tojsononeline(minchunk)
+ " to: " + chunk.shard);
var res = admindb.runCommand({
moveChunk: namespace,
bounds: [ minchunk.min, minchunk.max ],
to: chunk.shard });
if(!res.ok) {
print("error: " + res.errmsg);
if(res.errmsg == "move failed") {
sleep(1000);
print("RETRYING");
continue;
}
throw res.errmsg;
}
minchunk.shard = chunk.shard;
break;
}
}
while(true) {
var mergeBounds = [ minchunk.min, chunk.max ];
print("merge chunk into: " + chunk._id
+ " shard: " + chunk.shard
+ " bounds: " + tojsononeline(mergeBounds)
+ " size: " + ds.size
+ " #" + count);
var res = admindb.runCommand({
mergeChunks: namespace,
bounds: mergeBounds });
if(!res.ok) {
print("error: " + res.errmsg);
if(res.errmsg.startsWith("could not acquire collection lock")) {
sleep(1000);
print("RETRYING");
continue;
}
throw res.errmsg;
}
break;
}
minchunk.max = chunk.max;
}
if (ds.size == 0) {
if (minchunk == null) {
ds.shard = chunk.shard;
ds.min = chunk.min;
ds.max = chunk.max;
minchunk = ds;
count = 1;
print("min chunk: " + tojsononeline(ds));
} else {
count++;
}
} else {
minchunk = null;
}
});
} finally {
//print("start balancer");
//sh.startBalancer();
}
}
// mergeEmptyChunks("db.collection");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment