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

Posted

技术标签:

【中文标题】mongodb,复制和错误: "$err" : "not master and slaveOk=false", "code" : 13435【英文标题】:mongodb, replicates and error: "$err" : "not master and slaveOk=false", "code" : 13435 mongodb,复制和错误: "$err" : "not master and slaveOk=false", "code" : 13435 【发布时间】:2012-02-17 21:30:14 【问题描述】:

我第一次尝试了 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();这让我想到另一个问题。我必须为每个查询都这样做吗?如果我在主节点上怎么办? 【参考方案1】:

将 readPreference 添加为 PRIMARY

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

【讨论】:

【参考方案2】:

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

rs.secondaryOk()

之后就可以正常从secondary查询了。

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

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

【讨论】:

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

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

【讨论】:

【参考方案4】:

我来到这里是为了寻找同样的错误,但来自Node.js native driver。我的答案是campeterson 和Prabhat 的答案组合。

问题是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 );

【讨论】:

【参考方案5】:

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

例如

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

【讨论】:

【参考方案6】:

在mongodb2.0中

你应该输入

rs.slaveOk()

在二级mongod节点中

【讨论】:

【参考方案7】:

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

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

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

【讨论】:

【参考方案8】:

这只是给使用 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”是第三个可选参数。

【讨论】:

【参考方案9】:

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

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

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

【讨论】:

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

以上是关于mongodb,复制和错误: "$err" : "not master and slaveOk=false", "code" : 13435的主要内容,如果未能解决你的问题,请参考以下文章

Node.js MongoDB 插入错误

Node.js MongoDB 插入错误

查找 PyMySQL 错误的来源 - err.InterfaceError("(0, '')")

mongodb的secondary可以支持写操作吗?

在节点 js“应该设置秘密”和反应“npm ERR!代码 ELIFECYCLE”中出现错误

插入时的 MongoDb 复制错误