MongoDB 6.0下Mongosh自动创建用户及数据库的重复执行问题
解决MongoDB 6.0(mongosh)重复执行用户创建脚本的报错问题
问题场景
通过ARM模板创建安装MongoDB的Linux虚拟机时,从MongoDB 4.4升级到6.0后,原有的mongo工具需替换为mongosh。原脚本中db.dropUser()在目标用户不存在时会抛出MongoshInvalidInputError: [COMMON-10001] Invalid database name:错误;若移除dropUser语句,首次执行正常,但重复执行时会因用户已存在报错。需要实现与原脚本一致的幂等性效果——无论执行多少次,都能正常创建/重置目标数据库用户。
解决方案
方案1:检查用户存在性后再删除(与原脚本逻辑完全对齐)
通过db.getUser()判断目标用户是否存在,仅当用户存在时执行删除操作,避免用户不存在时的报错:
mongoScript="const targetDb = db.getSiblingDB('$userDatabase'); // 先检查用户是否存在,存在才删除 if (targetDb.getUser('$userName')) { targetDb.dropUser('$userName'); } // 创建用户,无论之前是否存在 targetDb.createUser({ user: '$userName', pwd: '$userPassword', roles: [ { role: 'readWrite', db: '$userDatabase' } ] });" mongosh --username $adminUsername --password $adminPassword --eval "$mongoScript" admin
方案2:捕获用户已存在错误并更新用户(更高效的幂等实现)
利用try-catch捕获createUser时的用户已存在错误(错误码11000),直接更新用户的密码和角色,避免删除再创建的操作:
mongoScript="const targetDb = db.getSiblingDB('$userDatabase'); try { // 尝试创建用户,不存在则创建成功 targetDb.createUser({ user: '$userName', pwd: '$userPassword', roles: [ { role: 'readWrite', db: '$userDatabase' } ] }); } catch (e) { // 仅处理用户已存在的错误 if (e.code === 11000) { targetDb.updateUser('$userName', { pwd: '$userPassword', roles: [ { role: 'readWrite', db: '$userDatabase' } ] }); } else { // 其他错误正常抛出,便于排查问题 throw e; } }" mongosh --username $adminUsername --password $adminPassword --eval "$mongoScript" admin
方案选择
- 若需要完全复刻原脚本“删除旧用户再创建新用户”的逻辑,选择方案1;
- 若仅需确保用户的密码和角色符合预期,无需删除用户的其他属性(如自定义权限、注释等),选择方案2更高效。
内容的提问来源于stack exchange,提问作者xatrivus
相关产品推荐
相关产品推荐

