不能直接用root或clusterAdmin,因其权限过大且无法精确限制“仅维护时直连分片”行为,易误删config server数据或篡改元数据;directShardOperations是MongoDB 8.0引入的专用角色,需在admin库创建并显式授权,维护后必须立即回收。

为什么不能直接用 root 或 clusterAdmin?
因为 directShardOperations 角色是 MongoDB 8.0 引入的专用权限,它允许绕过 mongos 直连分片执行底层命令(比如强制迁移 chunk、手动拆分、清除 jumbo chunk)。但 root 和 clusterAdmin 虽然权限更大,却无法精确控制“仅限维护时直连分片”这一行为——它们默认允许任意操作,包括误删 config server 数据或篡改元数据,风险不可控。
如何创建并绑定 directShardOperations 角色?
必须在 admin 数据库中创建,并显式指定作用域为分片集群的内部节点(不是应用连接地址):
use admin
db.createRole({
role: "shard_maintainer",
privileges: [
{
resource: { cluster: true },
actions: ["directShardOperations"]
}
],
roles: []
})
然后给运维账号授权:
db.grantRolesToUser("ops_admin", [{ role: "shard_maintainer", db: "admin" }])
- 该角色只在
admin数据库下生效,不能跨库继承 - 必须用
mongosh连接mongos执行授权,不能连 config server 或 shard 直接操作 - 角色名(如
shard_maintainer)不能含空格或特殊字符,否则后续db.runCommand()会报InvalidRoleName
执行维护命令时最常踩的坑
拿到 directShardOperations 权限后,仍需严格遵循访问路径和上下文限制:
- 命令必须发给目标
shard的主节点(不是 mongos),且连接字符串里不能带?directConnection=true—— 这会导致认证失败,正确写法是mongodb://shard1-primary:27017/?authSource=admin -
moveChunk、splitChunk等命令必须在admin数据库下运行,否则返回Unauthorized - 执行
sh.stopBalancer()后,不能立刻跑moveChunk;要等 config server 元数据同步完成(通常需 3–5 秒),否则 chunk 状态不一致,balancer 可能回滚操作 - 所有直连分片的操作都绕过 mongos 的查询路由和安全审计日志,生产环境务必配合
mongod日志中的ACCESS和COMMAND级别记录做交叉验证
维护完成后必须立即回收权限
这个角色不该长期启用。执行完 movePrimary 或修复 jumbo chunk 后,立刻撤销:
db.revokeRolesFromUser("ops_admin", [{ role: "shard_maintainer", db: "admin" }])
很多团队忽略这步,导致后续误操作无法追溯责任边界——directShardOperations 不记录在 auditLog 中的「谁在什么时间对哪个分片做了什么」,只留 mongod 日志里的原始命令行,排查成本极高。


















