ChatGPT解决这个技术问题 Extra ChatGPT

mongodb,复制和错误:{ "$err" : "not master and slaveOk=false", "code" : 13435 }

我第一次尝试了 mongo 副本集。

我在 ec2 上使用 ubuntu 并启动了三个实例。我使用了每个实例的私有 IP 地址。我选择了主要的,下面是代码。

mongo --host Private IP Address
rs.initiate()
rs.add(“Private IP Address”)
rs.addArb(“Private IP Address”)

在这一点上一切都很好。当我访问 http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:28017/_replSet 站点时,我看到我有一个主要、次要和仲裁者。

好的,现在进行测试。

在主要创建数据库时,代码如下:

use tt
db.tt.save( { a : 123 } )

在二级上,然后我这样做并得到以下错误:

db.tt.find()
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }

我对 mongodb 和复制非常陌生,但我认为如果我在一个中做某事,它会转到另一个。那么,如果我在一个记录中添加一条记录,我必须做什么才能跨机器复制?

发现我必须使用 rs.slaveOk();这让我想到另一个问题。我必须为每个查询都这样做吗?如果我在主节点上怎么办?

S
Saurabh Maurya

您必须设置“辅助好的”模式以让 mongo shell 知道您允许从辅助读取。这是为了保护您和您的应用程序不会意外执行最终一致的读取。您可以在 shell 中执行此操作:

rs.secondaryOk()

之后,您可以从辅助节点正常查询。

关于“最终一致性”的说明:在正常情况下,副本集辅助节点在一秒或更短的时间内拥有与主节点相同的所有数据。在非常高的负载下,您写入主服务器的数据可能需要一段时间才能复制到辅助服务器。这被称为“副本滞后”,从滞后的辅助读取被称为“最终一致”的读取,因为虽然新写入的数据会在某个时候出现(除非网络故障等),但它可能不会立即可用。

编辑:您只需要在从辅助节点查询时设置 secondaryOk,并且每个会话只需设置一次。


在您在数据库上执行您不理解的命令之前,请务必查看手册。答案未解释的命令可能会产生后果。此命令是否会更改为副本集的所有连接分配读取操作的方式?最好找出来。此命令最早出现在 v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOk 您可以(并且应该)始终将 docs.mongodb.com URL 的“/manual/”部分替换为您的特定版本,以确保您获得相关信息。
slaveOk() 已弃用,可能会在下一个主要版本中删除。请改用 secondaryOk()
E
Ed Norris

要避免每次都输入 rs.slaveOk(),请执行以下操作:

创建一个名为 replStart.js 的文件,其中包含一行:rs.slaveOk()

然后在您启动 Mongo shell 时包含 --shell replStart.js。当然,如果您在本地连接到单个实例,这不会节省任何输入。


节省输入的更好方法是将 rs.slaveOk() 添加到您的 ~/.mongorc.js 文件中,该文件将在启动 mongo shell 时自动执行。
我发现将默认配置放在 ~/.mongorc.js 中并将自定义配置放在 replStart.jsadminStart.js 或其他任何内容中很有用。
f
fguillen

在mongodb2.0

你应该输入

rs.slaveOk()

在辅助 mongod 节点中


c
campeterson

这只是给使用 Ruby 驱动程序处理此问题的任何人的注意事项

我在使用 Ruby Gem 时遇到了同样的问题。

要在 Ruby 中设置 slaveOk,您只需在创建客户端时将其作为参数传递,如下所示:

mongo_client = MongoClient.new("localhost", 27017, { slave_ok: true })

https://github.com/mongodb/mongo-ruby-driver/wiki/Tutorial#making-a-connection

mongo_client = MongoClient.new # (optional host/port args)

请注意,“args”是第三个可选参数。


k
kub1x

我到这里搜索相同的错误,但来自 Node.js native driver。我的答案是 campetersonPrabhat 的答案组合。

问题是 readPreference 设置默认为 primary,然后以某种方式导致令人困惑的 slaveOk 错误。我的问题是我只想从任何节点读取我的副本集。我什至没有连接到它作为副本集。我只是连接到任何节点以从中读取。

readPreference 设置为 primaryPreferred(或更好地设置为 ReadPreference.PRIMARY_PREFERRED 常量)为我解决了这个问题。只需将其作为选项传递给 MongoClient.connect()client.db() 或任何 find()aggregate() 或其他函数。

https://docs.mongodb.com/v3.0/reference/read-preference/#primaryPreferred

http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html(搜索readPreference)

const { MongoClient, ReadPreference } = require('mongodb');
const client = await MongoClient.connect(MONGODB_CONNECTIONSTRING, { readPreference: ReadPreference.PRIMARY_PREFERRED });

M
Michael

警告:slaveOk() 已弃用,可能会在下一个主要版本中删除。请改用secondaryOk()。 rs.secondaryOk()


P
Prabhat

slaveOk 不再起作用了。需要使用 readPreference https://docs.mongodb.com/v3.0/reference/read-preference/#primaryPreferred

例如

const client = new MongoClient(mongoURL + "?readPreference=primaryPreferred", { useUnifiedTopology: true, useNewUrlParser: true });

j
jit

我只是为数据库提供商的尴尬情况添加了这个答案。

在我们的案例中发生的事情是主数据库和辅助数据库反向移动(主要到辅助,反之亦然),我们得到了同样的错误。

因此,请检查数据库状态的配置设置,这可能会对您有所帮助。


P
Pavneet Kaur

将 readPreference 添加为 PRIMARY

const { MongoClient, ReadPreference } = require('mongodb');
const client = new MongoClient(url, { readPreference: ReadPreference.PRIMARY_PREFERRED});
client.connect();

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅