dbStats 命令需在目标数据库显式授予 read 角色,不能依赖 readAnyDatabase 等跨库角色;WiredTiger + journal 启用时权限校验更严格,须确保 authSource 与执行库一致。

dbStats 命令需要 read 权限,不是只读用户默认就有
很多人以为只要给了 read 角色,就能跑 db.stats(),结果报错 "not authorized on <db> to execute command dbStats"</db>。问题不在命令本身,而在于 MongoDB 对 dbStats 的权限划分比直觉更细:它被归入 read 操作集,但**必须显式授予该数据库的 read 角色**,不能靠跨库角色(如 readAnyDatabase)间接覆盖——除非你连的是 admin 库并用该库认证。
- 如果你在
bcc-livenet库里执行db.stats(),用户必须在bcc-livenet上有read角色,哪怕他同时在admin库有readAnyDatabase -
readAnyDatabase确实包含所有库的read操作,但它只在你连接时指定?authSource=admin且实际在admin库上下文运行命令才生效;直接切到业务库再调db.stats()会降级为该库的权限检查 -
dbAdmin角色不包含dbStats—— 它管结构操作(create,drop,validate),和统计无关
WiredTiger + journal 开启时,dbStats 权限要求更高
在 WiredTiger 存储引擎、journal 已启用的生产环境里,db.stats() 会访问底层存储状态(比如缓存使用、压缩统计),这部分指标被划入更严格的 read 范畴。即使你确认用户有 read 角色,仍可能失败。
- 典型错误信息:
"not authorized on <db> to execute command dbStats"</db>或带"Unauthorized: not authorized on <db> to execute command { dbStats: 1 }"</db> - 这不是 bug,是设计:MongoDB 把部分引擎级指标视为敏感数据,不随基础
read自动开放 - 临时验证方式:用
admin用户连admin库,执行db.runCommand({dbStats: 1, scale: 1024})—— 如果成功,说明问题纯出在业务用户权限配置上
如何给普通用户正确授权以运行 dbStats
最稳妥的做法是:在目标业务库中,为用户显式添加 read 角色,并确保连接串指定了正确的 authSource。
- 切换到业务库:
use bcc-livenet - 检查当前用户角色:
db.getUser("bcc_rw"),确认roles数组里有{role: "read", db: "bcc-livenet"} - 若缺失,补上:
db.grantRolesToUser("bcc_rw", [{role: "read", db: "bcc-livenet"}]) - 连接时必须带参数:
mongodb://bcc_rw:xxx@host:27017/bcc-livenet?authSource=bcc-livenet(注意不是admin) - 避免踩坑:不要用
dbAdminAnyDatabase代替readWriteAnyDatabase—— 前者完全不提供dbStats所需的读取能力
dbStats 失败不等于权限全无,要区分具体字段
db.stats() 返回的字段很多,但并非全部受同一权限控制。有些字段(如 collections, objects)只要 read 就能看;而像 fileSize, dataFileVersion 这类涉及存储层的,则可能触发更严校验。
- 可尝试缩小范围验证:
db.runCommand({dbStats: 1, scale: 1}),去掉freeStorage或fsUsedSize等易受限字段 - 如果只想查文档数和集合数,用
db.listCollections().toArray().length和db.collection.countDocuments({})组合,它们只依赖基础read,更稳定 - 监控场景建议改用
serverStatus(需clusterMonitor)或 Atlas 提供的 Metrics API,避开权限碎片问题
dbStats 看似简单,实则横跨逻辑层与存储层,容易在角色作用域、authSource、引擎配置三处同时掉链子。


















