mongodb, репликации и ошибки: {«$ err»: «не мастер, а slaveOk = false», «код»: 13435}

174

Я попробовал наборы реплик монго в первый раз.

Я использую Ubuntu на EC2, и я загрузил три экземпляра. Я использовал частный 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 и копирую, но я подумал, что если я что-то делаю в одном, то и в другом. Итак, если я добавлю запись в одну, что мне нужно сделать, чтобы реплицировать на разных машинах?

eLRuLL
источник
понял, что я должен использовать rs.slaveOk (); Это оставляет меня к другому вопросу. Я должен сделать это, сделать это для каждого запроса? Что если я нахожусь на главном узле?

Ответы:

282

Вы должны установить режим «slave okay», чтобы оболочка mongo знала, что вы разрешаете чтение с вторичного устройства. Это сделано для того, чтобы защитить вас и ваши приложения от случайного последовательного чтения. Вы можете сделать это в оболочке с помощью:

rs.slaveOk()

После этого вы можете сделать запрос в обычном режиме.

Примечание о «возможной согласованности»: при нормальных обстоятельствах вторичные серверы набора реплик имеют все те же данные, что и первичные файлы, в течение секунды или меньше. При очень высокой нагрузке данные, которые вы записали на первичный сервер, могут реплицироваться на вторичный сервер. Это известно как «задержка реплики», а чтение с запаздывающего вторичного устройства известно как «в конечном итоге непротиворечивое» чтение, поскольку, хотя недавно записанные данные будут отображаться в какой-то момент (исключая сбои в сети и т. Д.), Это может быть Сразу Доступно.

Изменить: вам нужно установить slaveok только при запросе от вторичных, и только один раз за сеанс.

dcrosta
источник
3
Всегда проверяйте руководство, прежде чем приступить к выполнению команд, которые вы не понимаете в своих БД. Для команды могут быть последствия, которые ответ не объясняет. Меняет ли эта команда способ распределения операций чтения для всех подключений к набору реплик? Лучше узнай. Эта команда появилась еще в v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOk Вы можете (и должны) всегда заменять часть "/ manual /" URL-адреса docs.mongodb.com к вашей конкретной версии, чтобы убедиться, что вы получаете соответствующую информацию.
Бруно Броноски,
45

Чтобы не печатать rs.slaveOk()каждый раз, сделайте это:

Создайте файл с именем replStart.js, содержащий одну строку:rs.slaveOk()

Затем включите --shell replStart.jsпри запуске оболочки Mongo. Конечно, если вы подключаетесь локально к одному экземпляру, это не спасет вас от набора текста.

Эд Норрис
источник
26
Лучший способ сэкономить на вводе текста - добавить rs.slaveOk()в ~/.mongorc.jsфайл файл, который будет автоматически выполняться при запуске оболочки mongo.
Стенни
2
Я считаю это полезным поставить конфигурацию по умолчанию в ~/.mongorc.jsи пользовательских конфигураций в replStart.jsили adminStart.jsили любой другой .
Эд Норрис
41

в mongodb2.0

вы должны напечатать

rs.slaveOk()

во вторичном монгодном узле

andyshi
источник
11

ЭТО ТОЛЬКО ЗАМЕТКА ДЛЯ ЛЮБОГО УЧАСТИЯ В ЭТОЙ ПРОБЛЕМЕ С ИСПОЛЬЗОВАНИЕМ РУБИНОВОГО ДРАЙВЕРА

У меня была такая же проблема при использовании Ruby Gem.

Чтобы установить slaveOk в Ruby, вы просто передаете его в качестве аргумента при создании клиента следующим образом:

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» является третьим необязательным аргументом.

campeterson
источник
1

Я просто добавляю этот ответ для неловкой ситуации от поставщика БД.

то, что произошло в нашем случае, это то, что первичный и вторичный db сместились обратно (первичный на вторичный и наоборот), и мы получаем ту же ошибку.

поэтому, пожалуйста, проверьте в настройках конфигурации состояние базы данных, которое может вам помочь.

JIT
источник
0

Я попал сюда в поисках той же ошибки, но из Node.js родной драйвер . Ответом для меня была комбинация ответов Кампетерсона и Прабхата .

Проблема заключается в том, что readPreferenceзначение по умолчанию равно primary, что затем приводит к сбивающей с толку slaveOkошибке. Моя проблема в том, что я просто хочу читать с моего набора реплик с любого узла. Я даже не подключаюсь к нему как к репликасу. Я просто подключаюсь к любому узлу, чтобы читать с него.

Установка readPreferenceна primaryPreferred(или лучше на ReadPreference.PRIMARY_PREFERREDпостоянную) решила для меня. Просто передайте его в качестве опции MongoClient.connect()или к client.db()или к любому find(), aggregate()или другой функции.

const { MongoClient, ReadPreference } = require('mongodb');
const client = await MongoClient.connect(MONGODB_CONNECTIONSTRING, { readPreference: ReadPreference.PRIMARY_PREFERRED });
kub1x
источник