mongodb, replikuje się i błąd: {„$ err”: „not master and slaveOk = false”, „code”: 13435}

174

Po raz pierwszy próbowałem replik mongo.

Używam ubuntu na ec2 i uruchomiłem trzy instancje. Użyłem prywatnego adresu IP każdej z instancji. Wybrałem jako podstawowy, a poniżej jest kod.

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

W tym momencie wszystko jest w porządku. Kiedy wchodzę na stronę http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:28017/_replSet , widzę, że mam głównego, drugiego i arbitra.

Ok, teraz do testu.

Na podstawowym utwórz bazę danych w następujący sposób:

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

po drugie robię to i otrzymuję poniższy błąd:

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

Jestem nowy w mongodb i powiela się, ale pomyślałem, że jeśli zrobię coś w jednym, to przejdzie do drugiego. Jeśli więc dodam rekord w jednym, co muszę zrobić, aby zreplikować go między komputerami?

eLRuLL
źródło
zorientowałem się, że muszę użyć rs.slaveOk (); To pozostawia mnie do kolejnego pytania. Muszę to zrobić dla każdego zapytania? A jeśli jestem w węźle głównym?

Odpowiedzi:

282

Musisz ustawić tryb „slave okay”, aby powłoka mongo wiedziała, że ​​zezwalasz na odczyty z urządzenia wtórnego. Ma to na celu ochronę Ciebie i Twoich aplikacji przed przypadkowym wykonaniem spójnych odczytów. Możesz to zrobić w powłoce za pomocą:

rs.slaveOk()

Następnie możesz normalnie przesyłać zapytania z urządzeń pomocniczych.

Uwaga dotycząca „ostatecznej spójności”: w normalnych okolicznościach części pomocnicze zestawu replik mają te same dane co części główne w ciągu sekundy lub mniej. W przypadku bardzo dużego obciążenia replikacja danych zapisanych na serwerze podstawowym może zająć trochę czasu. Nazywa się to „opóźnieniem repliki”, a odczyt z opóźnionego wtórnika jest znany jako odczyt „ostatecznie spójny”, ponieważ chociaż nowo zapisane dane pojawią się w pewnym momencie (z wyjątkiem awarii sieci itp.), Może to nie być dostępne od zaraz.

Edycja: Musisz ustawić slaveok tylko podczas odpytywania z drugorzędnych i tylko raz na sesję.

dcrosta
źródło
3
Zawsze sprawdź podręcznik, zanim zaczniesz wykonywać polecenia, których nie rozumiesz na swoich bazach danych. Polecenie może mieć konsekwencje, których odpowiedź nie wyjaśnia. Czy to polecenie zmienia sposób dystrybucji operacji odczytu dla wszystkich połączeń z zestawem replik? Lepiej się dowiedz. To polecenie pojawia się już w wersji 2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOk. Możesz (i powinieneś) zawsze zastępować część „/ manual /” adresu URL docs.mongodb.com do konkretnej wersji, aby mieć pewność, że otrzymujesz odpowiednie informacje.
Bruno Bronosky
45

Aby uniknąć pisania za rs.slaveOk()każdym razem, zrób to:

Utwórz plik o nazwie replStart.js, zawierający jedną linię:rs.slaveOk()

Następnie uwzględnij --shell replStart.jspodczas uruchamiania powłoki Mongo. Oczywiście, jeśli łączysz się lokalnie z pojedynczą instancją, nie oszczędza to żadnego wpisywania.

Ed Norris
źródło
26
Lepszym sposobem na zaoszczędzenie czasu na wpisywaniu byłoby dodanie rs.slaveOk()do ~/.mongorc.jspliku, który zostanie automatycznie wykonany podczas uruchamiania powłoki mongo.
Stennie
2
Uważam, że przydatne jest umieszczenie domyślnej konfiguracji ~/.mongorc.jsi konfiguracji niestandardowych w replStart.jslub w adminStart.jsczymkolwiek.
Ed Norris
41

w mongodb2.0

należy wpisać

rs.slaveOk()

we wtórnym węźle mongod

andyshi
źródło
11

TO TYLKO WSKAZÓWKA DLA KAŻDEGO, KTÓRZY BĘDZIE SIĘ Z TYM PROBLEMEM UŻYWAJĄC STEROWNIKA

Miałem ten sam problem podczas korzystania z Ruby Gem.

Aby ustawić slaveOk w Rubim, wystarczy przekazać go jako argument podczas tworzenia klienta w następujący sposób:

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)

Zwróć uwagę, że „argumenty” to trzeci opcjonalny argument.

campeterson
źródło
1

Właśnie dodam tę odpowiedź na niezręczną sytuację od dostawcy bazy danych.

to, co wydarzyło się w naszym przypadku, to podstawowa i drugorzędna db przesunięta odwrotnie (pierwotna do drugiej i odwrotnie) i otrzymujemy ten sam błąd.

więc sprawdź w ustawieniach konfiguracji status bazy danych, który może ci pomóc.

jit
źródło
0

Mam tutaj szukając tego samego błędu, ale z node.js natywny sterownik . Odpowiedź była dla mnie połączeniem odpowiedzi poprzez campeterson i Prabhat .

Problem polega na tym, że readPreferenceustawienie domyślne to primary, co w jakiś sposób prowadzi do mylącego slaveOkbłędu. Mój problem polega na tym, że chcę po prostu czytać z mojego zestawu replik z dowolnego węzła. Nawet nie łączę się z nim jak z repliką. Po prostu podłączam się do dowolnego węzła, aby z niego czytać.

Ustawianie readPreferencesię primaryPreferred(lub lepiej do ReadPreference.PRIMARY_PREFERREDstałej) rozwiązać go dla mnie. Wystarczy przekazać go jako opcja MongoClient.connect()lub do client.db()lub z dowolnego find(), aggregate()lub innej funkcji.

const { MongoClient, ReadPreference } = require('mongodb');
const client = await MongoClient.connect(MONGODB_CONNECTIONSTRING, { readPreference: ReadPreference.PRIMARY_PREFERRED });
kub1x
źródło