如何 运行 在 mongo 本地主机上 mongo 上压缩命令?

How to run Compact command on sharded mongo over mongos localhost?

我是 Mongo.I 的新手,在 each.and 3 配置服务器上有分片和 3 个副本。 我无法 运行 压缩命令,它给出了一个错误“管理员未授权执行命令” .我连接了 mongo 个实例并更改 mongod.conf 中的安全授权“禁用-启用”部分并尝试创建新用户但它再次给出错误“未授权管理员执行命令”。

如何在超过 mongo 秒的实例上连接和 运行 命令?

勾选 documentation:

Sharded Cluster

compact only applies to mongod instances. In a sharded environment, run compact on each shard separately as a maintenance operation.

You cannot issue compact against a mongos instance.

您可以 运行 来自 mongos 的脚本。它连接到一个循环中的所有 mongod 实例并且 运行s 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>" });
      }
   }
}

关于身份验证和权限:

在分片集群中,您有两种类型的用户,请参阅 Users

  • 当您通过 mongos
  • 连接时,将创建和使用 分片集群用户
  • 分片本地用户 直接在分片上创建和使用。

为了 运行 compact 您需要直接连接到分片,因此您必须使用分片本地管理用户。我想这个用户还没有创建,见 Create the shard-local user administrator

本教程创建了两个用户(“shard-local 用户管理员”和“shard-local 集群管理员”),我看不出有任何原因。只创建一个本地管理员用户:

const admin = db.getSiblingDB("admin")
admin.createUser({ user: "local_admin", pwd: "secret", roles: ["clusterAdmin", "userAdminAnyDatabase"] }) 

您需要在每个(主)分片上创建此用户!在 config 服务器上,sharded cluster usersshard local users 相同。因此不需要在配置服务器上创建本地用户,这将是多余的。

如果您将 ReplicaSet 与 ARBITER 一起使用,请注意这一点。仲裁者不存储任何数据,这包括用户帐户数据。因此 compact 在 ARBITER 上毫无意义。但是,如果您出于某种原因需要在 ARBITER 上创建本地用户,请参阅 cannot authenticate in mongodb arbiter