\_retryWrites=true 仅在 MongoDB 4.0+ 副本集或分片集群中对支持重试的写操作生效,单节点下被忽略且不报错;需确保 URI 含至少两个节点并指定 replicaSet,驱动版本 ≥ 3.6,且通过 rs.status() 确认副本集状态。

为什么加了 _retryWrites=true 还是遇到写操作失败?
这个参数只在 MongoDB 4.0+ 副本集或分片集群中生效,且仅对支持重试的写操作(如 insertOne、updateOne)起作用。单节点模式下它被完全忽略,Node.js 驱动也不会报错——你根本不会意识到它没起效。
常见错误现象:MongoServerError: Not a replica set 或写入后查不到数据,误以为是重试没触发,其实是连接压根没进副本集模式。
- 确认集群状态:运行
rs.status()(在 mongo shell 里),不是db.runCommand({isMaster:1})返回ismaster:true就够了 - URI 必须包含至少两个节点,例如:
mongodb://node1:27017,node2:27017/db?replicaSet=rs0&_retryWrites=true - 驱动版本需 ≥ 3.6;老版本即使 URI 写了也静默丢弃
w 参数设成 majority 和数字有什么实际区别?
它控制写操作在多少个节点上成功才算“提交”,直接影响数据安全和延迟。设成 w=1(默认)只等主节点落盘,快但崩了就丢;w=majority 要等大多数节点确认,抗单点故障,但可能卡住——比如 3 节点集群挂掉 1 个,剩下 2 个无法凑出 majority(3/2+1=2,刚好够),但若网络分区让主节点孤立,写入就会超时。
使用场景:金融类操作建议 w=majority + j=true(强制 journal);日志类可接受 w=1 换吞吐。
-
w=2在 3 节点集群中比majority更宽松(不依赖动态计算),但硬编码易出错 -
w=majority在分片集群中含义不同:指该分片内 majority,不是整个集群 - 搭配
readConcern=majority才能真正读到已提交的数据,否则可能读到回滚前的脏值
为什么连上了却提示 Authentication failed,明明密码是对的?
大概率是 authSource 指错了。它不是“认证用的数据库名”,而是“存放用户凭证的数据库”。默认是 admin,但如果你用 db.createUser(..., {roles:[{role:'readWrite',db:'myapp'}]}) 在 myapp 库建的用户,就得显式写 authSource=myapp。
另一个坑:URI 中的用户名密码必须 URL 编码。比如密码含 @、/、:,不编码会导致解析截断——驱动会把 @ 前面当用户名,后面当 host,直接连错地址。
- 检查用户在哪建的:
use admin; db.getUser('u')看userSource字段 - URI 示例:
mongodb://user:pass%40123@localhost:27017/mydb?authSource=admin - Node.js 驱动 4.x+ 支持
auth.username/auth.password配置项,比塞在 URI 里更安全、免编码
连接字符串里混用多个参数,哪些组合会互相干扰?
最常踩的坑是 maxPoolSize 和 minPoolSize 设得太大,再叠加上 connectTimeoutMS=1000,结果服务端还没响应,客户端池子就撑爆内存了。MongoDB 驱动不会警告你“你配得太猛”,只会默默开一堆连接然后卡死。
性能影响明显的是 maxIdleTimeMS 和 minPoolSize:前者控制空闲连接存活时间,后者要求保底连接数。如果设 minPoolSize=10 但 maxIdleTimeMS=60000(1 分钟),意味着每分钟都要重建 10 个连接——纯属浪费。
- 生产环境建议:
minPoolSize=5、maxPoolSize=10、maxIdleTimeMS=600000(10 分钟) -
socketTimeoutMS别乱调小,低于 3000ms 容易误杀慢查询,尤其聚合操作 - 所有 timeout 类参数单位都是毫秒,但文档里有的写 ms、有的写 MS,驱动只认小写
ms后缀(如connectTimeoutMS是错的,正确是connectTimeoutMS——等等,不对,官方就是大写 MS,但拼错一个字母(如connetTimeoutMS)就静默忽略
参数之间没有“官方互斥列表”,但真实世界里,retryWrites 依赖副本集拓扑,w 依赖节点数量与健康状态,authSource 依赖用户元数据位置——它们各自成立的前提,往往比参数本身更难满足。










