MongoDB从3.x版本开始对索引操作做了更细粒度的权限划分,很多团队在升级或调整账号权限后发现,原本能正常读写数据的账号,一旦执行createIndex或dropIndex就直接被拒绝,日志中会出现编号为2680的报错信息。这类问题的本质并不是数据库损坏,而是索引操作被单独的权限项控制着,普通读写角色并不包含这些权限。理解2680错误背后的权限模型,是解决问题的关键。

故障码2680的典型表现与触发场景
2680错误最常见的形式是在执行索引管理命令时抛出not authorized异常。比如一个账号持有readWrite角色,在业务库上执行db.collection.createIndex({userId: 1}),服务端返回的报错信息大致为:对当前库执行createIndex动作未获授权,错误编号2680。之所以让人困惑,是因为readWrite角色确实可以写数据、建集合,唯独不包含索引管理动作。
触发这个错误的场景主要有三类。第一类是应用账号被限制了权限,开发人员为了安全只给了readWrite,却忘了索引创建属于独立权限。第二类是分片集群或副本集中,运维账号在某个分片节点上直接操作,而该节点的本地权限与配置中心不一致。第三类是使用云托管MongoDB时,控制台分配的角色粒度较粗,索引操作被平台单独管控,需要到控制台开通索引管理权限。
还有一个容易忽略的情况:认证库不匹配。账号建立在admin库,但连接时把authSource指向了业务库,认证虽然通过(如果业务库有同名用户),但该用户没有索引权限,同样报2680。排查时务必先确认连接串中的authSource参数是否指向账号所在的库。
MongoDB索引相关权限项详解
MongoDB把索引操作拆成了几个独立的权限动作,理解它们才能对症下药。核心的动作包括:
createIndex:在集合上创建索引,包含createSearchIndexes等衍生动作dropIndex:删除索引,注意reIndex等动作也依赖它listIndexes:查看集合的索引列表,只读操作也会用到collMod:修改索引属性,比如TTL时间调整
内置角色中,dbAdmin和dbAdminAnyDatabase包含上述全部动作,而readWrite只包含部分查询和写入动作,不涵盖createIndex与dropIndex,这就是2680错误最直接的成因。可以通过下面的命令查看某个内置角色到底包含哪些动作:
// 切换到admin库查看角色定义
use admin
db.getRole("readWrite", { showPrivileges: true })
// 输出的privileges数组中找不到createIndex动作,印证了2680的成因
如果不想让应用账号持有完整的dbAdmin权限,更安全的做法是自定义角色,只授予索引相关动作,再附加原有的readWrite。这种方式符合最小权限原则,即使账号泄露,攻击者也无法执行dbHash、collMod等更敏感的操作。
排查步骤与完整解决方案
遇到2680错误时,建议按固定顺序排查,避免盲目提权。第一步确认当前身份与角色,第二步确认认证库,第三步补齐权限。
第一步,在mongosh中执行身份检查:
// 查看当前连接的用户与角色分布
db.runCommand({ connectionStatus: 1, showPrivileges: true })
// 或者直接看角色
db.getUser("app_user")
输出中如果只看到readWrite角色,基本可以确认问题所在。第二步检查连接串,确认authSource是否指向账号真实所在的库。第三步,在admin库上创建一个专职索引管理的自定义角色并授予目标账号:
use admin
db.createRole({
role: "indexManager",
privileges: [
{
resource: { db: "order_db", collection: "" },
actions: [ "createIndex", "dropIndex", "listIndexes", "collMod" ]
}
],
roles: []
})
// 将新角色授予业务账号
db.grantRolesToUser("app_user", [
{ role: "indexManager", db: "admin" }
])
上面的命令把indexManager角色限定在order_db这一个库上,resource中的collection留空表示对该库全部集合生效。授权完成后无需重启服务,重新执行索引命令即可生效。如果是在副本集环境下,务必通过主节点或mongos执行授权操作,在从节点上写入会直接失败,报错形态可能和2680混淆,需要仔细分辨。
最后提醒两点:一是权限变更后建议记录到运维日志,方便日后审计;二是定期用db.getRole复查账号持有的角色,防止临时提权变成永久后门。把索引权限从管理员角色中剥离出来单独管控,既解决了2680报错,也让权限体系更清晰安全。
MongoDB故障码2680索引权限控制MongoDB权限管理修改时间:2026-09-07 10:46:43