mongodump 默认不导出 admin.system.users,必须加 --dumpdbusersandroles;mongorestore 导入时须配对使用 --restoredbusersandroles,且目标账号需有 useradminanydatabase 权限。

mongodump 默认不导出 admin.system.users,必须加 --dumpDbUsersAndRoles
直接执行 mongodump --db=admin 后发现 admin/ 目录下空或只有空的 .bson 文件?这是设计行为,不是权限错误。MongoDB 从 4.2 起默认跳过所有系统集合(包括 system.users 和 system.roles),哪怕你用 root 登录、显式指定 --db=admin,它也静默忽略。
必须启用专用开关:--dumpDbUsersAndRoles,且满足两个硬性前提:
-
--db=admin必须显式指定,不能用--uri连接字符串,否则报错:error parsing command line options: --dumpDbUsersAndRoles requires --db to be specified - 密码含特殊字符(如
@)必须 URL 编码,%40是正确写法,\@或未编码都会导致认证失败 - 导出结果不是单个
.bson,而是一个admin/子目录,内含system.users.bson、system.roles.bson和.metadata.json
mongorestore 导入时必须配对使用 --restoreDbUsersAndRoles
把 /backup/admin_users 目录直接扔给 mongorestore,它会完全忽略里面的 system.users.bson——因为常规恢复逻辑不处理系统集合。
必须显式启用恢复开关,并注意路径层级:
- 命令中路径必须指向
/backup/admin_users(即包含admin/子目录的父目录),不能写成/backup/admin_users/admin - 目标集群登录账号需具备
userAdminAnyDatabase角色,否则写入admin.system.users会被拒绝 - 若目标已有同名用户,新导入会覆盖其密码哈希和角色定义,但不会删除该用户;
--drop对系统集合无效,慎用
跨集群同步前必须验证三件事:版本、角色结构、oplog 兼容性
账号同步失败,八成卡在这三个地方,且错误现象往往不报具体字段问题,只表现为“导入后无法登录”或“db.auth() 返回 false”:
- 源与目标 MongoDB 主版本号差不能超过一个(如 6.0 → 6.3 可行,6.0 → 7.0 不行),否则
system.roles中新增字段(如 7.0 的inheritedRoles)在 6.x 上解析失败 - 目标集群
admin库必须可写,且local库需有足够 oplog 容量(建议oplogSizeMB: 10240),否则初始同步阶段因 oplog 回滚中断,用户数据写入不完整 - 若目标是副本集,确保所有节点 keyFile 一致且权限为
400,否则即使用户导入成功,从节点也无法通过 oplog 复制角色元数据
替代方案:mongosh + db.getUsers({showCredentials: true})
当 --dumpDbUsersAndRoles 不可用(如旧版 MongoDB 或受限环境),可退到 shell 接口导出 JSON:
- 连接源集群执行:
mongosh "mongodb://u:p@host:port/admin?authSource=admin" --eval 'JSON.stringify(db.getUsers({showCredentials: true}), null, 2)' > users.json -
showCredentials: true是关键,否则返回的credentials.SHA-256字段为空,恢复后用户无法认证 - 导入时不能用
mongorestore,需写 JS 脚本遍历users.json数组,对每个用户调用db.createUser(),注意跳过_id和userId字段(它们是内部生成的)
真正麻烦的从来不是命令怎么敲,而是 system.roles 字段结构随版本漂移、oplog 同步滞后导致角色元数据没复制完、以及 keyFile 权限在不同节点上悄悄变宽——这些点不提前查,同步完才发现用户能连但没权限,就得重来。











