I am very new on Mongo.I have shards and 3 replica on each.and 3 config server. I am unable to run compact command it gives an error "not authorized on admin to execute command" .I connected mongo instances and change security-authorization "disable-enable" section in mongod.conf and tried create new user but it gives an error "not authorized on admin to execute command" again.
How to connect and run commands on instances over mongos?
Check the documentation:
Sharded Cluster
compact
only applies tomongod
instances. In a sharded environment, runcompact
on each shard separately as a maintenance operation.You cannot issue compact against a
mongos
instance.
You can run this script from mongos
. It connects to all mongod instances in a loop and runs compact
const MONGO_PASSWROD = "secret";
const user = "local_admin";
const map = db.adminCommand("getShardMap").map;
for (let rs of Object.keys(map)) {
if (rs == "config") continue; // Running 'compact' of Config server is most likely useless
let uri = map[rs].split("/");
let connectionString = `mongodb://${user}:${MONGO_PASSWROD}@${uri[1]}/admin?replicaSet=${uri[0]}&authSource=admin`;
let replicaSet = Mongo(connectionString).getDB("admin");
for (let member of replicaSet.adminCommand({ replSetGetStatus: 1 }).members) {
if (!replicaSet.hello().hosts.includes(member.name)) continue; // Used to skip ARBITER
if (member.health != 1 || !Array("PRIMARY", "SECONDARY").includes(member.stateStr)) {
print(`Member state of ${member.name} is '${member.stateStr}' - skip 'compact'`);
} else {
let connectionString = `mongodb://${user}:${MONGO_PASSWROD}@${member.name}/admin?authSource=admin`;
let node = Mongo(connectionString).getDB("admin");
print(`node.adminCommand({ compact: "<collection name>" }) on ${member.name}`);
// maybe optionally run 'node.stepDown()' in order to minimize impact
node.adminCommand({ compact: "<collection name>" });
}
}
}
Regarding authentication and privileges:
In a Sharded Cluster you have two types of users, see Users
mongos
In order to run compact
you need to connect directly to the shard, thus you must use the shard local administrative user. I guess this user is not created yet, see Create the shard-local user administrator
The tutorial creates two users ("shard-local user administrator" and "shard-local cluster administrator"), I don't see any reason for this. Create just one local admin user:
const admin = db.getSiblingDB("admin")
admin.createUser({ user: "local_admin", pwd: "secret", roles: ["clusterAdmin", "userAdminAnyDatabase"] })
You need to create this user on each (PRIMARY) shard! On the config server, the sharded cluster users and the shard local users are the same. Thus it is not required to create local user on config server, it would be redundant.
Just another note in case you use ReplicaSet with ARBITER. The ARBITER does not store any data, this includes user account data. Due to this the compact
is pointless on ARBITER. However, if you need to create local user on ARBITER for whatever reason then see cannot authenticate in mongodb arbiter