默认情况下,MongoDB 的读偏好(Read Preference)是 primary。这意味着驱动程序会强制要求连接到 Primary 节点来执行该命令。
如果你连接到的 IP (127.0.0.1:1531) 当前是一个 Secondary 节点:
驱动程序发现它不是 Primary。
驱动程序检查配置,发现 slaveOk (旧称) 或 readPreference 设置为 primary (即不允许从 Secondary 读)。
结果:抛出错误 not master and slaveOk=false。啥意思,从节点不是处理读操作吗,为啥不能读了
从节点(Secondary)确实是为了处理读操作而存在的(用于读写分离、分担负载)
“能读”不代表“默认就能读”
核心原因:防止读到“脏数据”或“旧数据”
MongoDB 的副本集采用异步复制(Asynchronous Replication)。
主节点(Primary):写入数据后,立即成功。
从节点(Secondary):主节点把数据变化(Oplog)发给从节点,从节点再应用这些变化。这中间有时间延迟(可能是几毫秒,也可能是几秒,取决于网络和数据量)。
因此,MongoDB 的设计哲学是:
默认情况下(Read Preference = primary),为了保证“写后必读”(Read-your-writes)的一致性,所有的读写操作都必须去主节点。
只有主节点拥有最新、最确定的数据
总结
从节点能读吗? 能,但必须显式授权。
为什么默认不能读? 为了防止你读到还没同步过来的旧数据,保证“写后立即可读”的一致性。
怎么解决? 在连接时加上 ?readPreference=secondaryPreferred明确告诉 MongoDB:“我知道这是从节点,我接受可能存在的延迟,请让我读。”
查看副本集状态:
在 mongo shell 中运行:
javascript
编辑
rs.status()
或者简化的:
rs.isMaster() // 新版推荐用 rs.primary()
MongoDB 的副本集(Replica Set)架构中,节点分为三种角色:
Primary (主节点):唯一可以处理写操作和部分强一致性读操作的节点。
Secondary (从节点):只能处理读操作(且需要显式允许),不能处理写操作。
Arbiter (仲裁者):不参与数据存储,只参与选举。
当你执行 show collections 时:
这是一个读操作。
默认情况下,MongoDB 的读偏好(Read Preference)是 primary。这意味着驱动程序会强制要求连接到 Primary 节点来执行该命令。
如果你连接到的 IP (127.0.0.1:1531) 当前是一个 Secondary 节点:
驱动程序发现它不是 Primary。
驱动程序检查配置,发现 slaveOk (旧称) 或 readPreference 设置为 primary (即不允许从 Secondary 读)。
结果:抛出错误 not master and slaveOk=false。
注:slaveOk 是旧版 MongoDB 驱动中的参数名,新版称为 readPreference。报错信息保留了这个旧术语是为了兼容性。
admin 数据库中。admin 库),你在连接 admindb 时,必须指定认证源为 admin。# 方式 1: 命令行参数指定 authSource mongo 127.0.0.1:1531/admindb -u <你的用户名> -p <你的密码> --authenticationDatabase admin # 方式 2: URI 字符串指定 authSource mongo "mongodb://<用户名>:<密码>@127.0.0.1:1531/admindb?authSource=admin"admin 库:use admin db.auth("用户名", "密码") // 认证成功后,你可以自由切换回 admindb use admindb