203 votes

mongodb, réplique et erreur : { "$err" : "not master and slaveOk=false", "code" : 13435 }

J'ai essayé les ensembles de répliques mongo pour la première fois.

J'utilise ubuntu sur ec2 et j'ai démarré trois instances. J'ai utilisé l'adresse IP privée de chacune des instances. J'ai choisi la première comme primaire et voici le code.

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

Tout va bien à ce stade. Lorsque je me rends à la http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:28017/_replSet site je vois que j'ai un primaire, un secondaire et un arbitre.

Ok, maintenant pour un test.

Sur le primaire créer une base de données dans ce qui est le code :

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

sur le secondaire, je fais alors ceci et j'obtiens l'erreur suivante :

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

Je suis très novice en matière de mongodb et de répliques, mais je pensais que si je faisais quelque chose dans l'un, cela allait dans l'autre. Donc, si j'ajoute un enregistrement dans l'un, que dois-je faire pour répliquer entre les machines ?

317voto

dcrosta Points 11219

Vous devez définir le mode "secondary okay" pour que le shell mongo sache que vous autorisez les lectures à partir d'un secondaire. Ceci a pour but de vous protéger, vous et vos applications, d'effectuer des lectures éventuellement cohérentes par accident. Vous pouvez le faire dans le shell avec :

rs.secondaryOk()

Après cela, vous pouvez interroger normalement les secondaires.

Une remarque sur la "cohérence éventuelle" : dans des circonstances normales, les secondaires d'un ensemble de répliques ont toutes les mêmes données que les primaires en une seconde ou moins. En cas de charge très élevée, les données que vous avez écrites sur le primaire peuvent mettre un certain temps à être répliquées sur les secondaires. C'est ce qu'on appelle le "décalage de réplique", et la lecture à partir d'une réplique secondaire en retard est connue comme une lecture "éventuellement cohérente", parce que, bien que les données nouvellement écrites apparaîtront à un moment donné (sauf défaillances du réseau, etc.), elles peuvent ne pas être immédiatement disponibles.

Edit : Il vous suffit de définir secondaryOk lors d'une interrogation à partir de secondaires, et seulement une fois par session.

50voto

Ed Norris Points 776

Pour éviter de taper rs.slaveOk() à chaque fois, faites ça :

Créez un fichier nommé replStart.js contenant une ligne : rs.slaveOk()

Puis inclure --shell replStart.js lorsque vous lancez le shell Mongo. Bien sûr, si vous vous connectez localement à une seule instance, cela ne vous évitera pas de taper.

43voto

andyshi Points 310

Dans mongodb2.0

vous devez taper

rs.slaveOk()

dans le nœud secondaire de mongod

13voto

campeterson Points 515

CECI EST JUSTE UNE NOTE POUR TOUS CEUX QUI RENCONTRENT CE PROBLÈME EN UTILISANT LE PILOTE RUBY.

J'ai eu le même problème en utilisant la Gemme Rubis.

Pour définir slaveOk en Ruby, il suffit de le passer en argument lorsque vous créez le client, comme ceci :

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)

Remarquez que 'args' est le troisième argument facultatif.

8voto

kub1x Points 36

Je suis arrivé ici en cherchant la même erreur, mais à partir de Pilote natif Node.js . La réponse pour moi était une combinaison des réponses de campeterson et Prabhat .

Le problème est que readPreference Le paramètre par défaut est primary ce qui conduit d'une manière ou d'une autre à la confusion slaveOk erreur. Mon problème est que je veux simplement lire mon ensemble de répliques à partir de n'importe quel nœud. Je ne m'y connecte même pas en tant que replicaset. Je me connecte simplement à n'importe quel nœud pour le lire.

Réglage de readPreference à primaryPreferred (ou mieux à la ReadPreference.PRIMARY_PREFERRED constant) a résolu le problème pour moi. Il suffit de la passer comme option à MongoClient.connect() ou à client.db() ou à tout find() , aggregate() ou toute autre fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X