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

174

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 comme principal et ci-dessous est le code.

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

Tout à ce stade est très bien. Quand je vais sur le site http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:28017/_replSet , je vois que j'ai un principal, un seconday et un arbitre.

Ok, maintenant pour un test.

Sur le primaire, créez une base de données dans ce code:

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

sur le secondaire, je fais ensuite ceci et j'obtiens l'erreur ci-dessous:

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

Je suis très nouveau sur mongodb et réplique mais je pensais que si je fais quelque chose dans l'un, cela va dans l'autre. Donc, si j'ajoute un enregistrement dans un, que dois-je faire pour répliquer sur plusieurs machines?

eLRuLL
la source
compris que je dois utiliser rs.slaveOk (); Cela me laisse à une autre question. Je dois le faire pour chaque requête? Et si je suis sur le nœud maître?

Réponses:

282

Vous devez définir le mode "slave okay" pour que le shell mongo sache que vous autorisez les lectures depuis un secondaire. Ceci afin de vous protéger, vous et vos applications, contre la réalisation de lectures cohérentes par accident. Vous pouvez le faire dans le shell avec:

rs.slaveOk()

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

Une note sur la "cohérence éventuelle": dans des circonstances normales, les secondaires du jeu de répliques ont toutes les mêmes données que les primaires en une seconde ou moins. Sous une charge très élevée, les données que vous avez écrites sur le primaire peuvent mettre un certain temps à se répliquer vers les secondaires. Ceci est connu sous le nom de «retard de réplique», et la lecture à partir d'un secondaire retardé est connue sous le nom de lecture «éventuellement cohérente», car, même si les données nouvellement écrites apparaîtront à un moment donné (à l'exception des pannes de réseau, etc.), il se peut qu'elles ne soient pas Immédiatement disponible.

Edit: Vous ne devez définir slaveok que lors d'une requête à partir de secondaires, et une seule fois par session.

dcrosta
la source
3
Consultez toujours le manuel avant d'exécuter des commandes que vous ne comprenez pas sur vos bases de données. Il pourrait y avoir des conséquences sur la commande que la réponse n'explique pas. Cette commande modifie-t-elle la façon dont les opérations de lecture sont distribuées pour toutes les connexions au jeu de réplicas? Mieux vaut le découvrir. Cette commande apparaît aussi loin que v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOk Vous pouvez (et devriez) toujours remplacer la partie "/ manual /" d'une URL docs.mongodb.com à votre version spécifique pour vous assurer que vous obtenez des informations pertinentes.
Bruno Bronosky
45

Pour éviter de taper à rs.slaveOk()chaque fois, procédez comme suit:

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

Ensuite, incluez --shell replStart.jslorsque vous lancez le shell Mongo. Bien sûr, si vous vous connectez localement à une seule instance, cela n'économise aucune saisie.

Ed Norris
la source
26
Une meilleure façon d'économiser lors de la frappe serait d'ajouter rs.slaveOk()à votre ~/.mongorc.jsfichier, qui sera automatiquement exécuté au démarrage du shell mongo.
Stennie
2
Je trouve utile de mettre la configuration par défaut ~/.mongorc.jset les configurations personnalisées dans replStart.jsou adminStart.jsou autre.
Ed Norris
41

dans mongodb2.0

tu devrais taper

rs.slaveOk()

dans le nœud mongod secondaire

Andyshi
la source
11

CECI EST JUSTE UNE REMARQUE POUR TOUTE PERSONNE CONTENANT CE PROBLÈME À L'AIDE DU PILOTE RUBY

J'ai eu ce même problème lors de l'utilisation du Ruby Gem.

Pour définir slaveOk dans Ruby, il vous suffit de le passer comme 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)

Notez que «args» est le troisième argument facultatif.

Campeterson
la source
1

J'ajoute simplement cette réponse pour une situation délicate du fournisseur de base de données.

ce qui s'est passé dans notre cas, c'est que la base de données primaire et secondaire est inversée (primaire à secondaire et vice versa) et nous obtenons la même erreur.

veuillez donc vérifier les paramètres de configuration pour connaître l'état de la base de données, ce qui peut vous aider.

jit
la source
0

Je suis arrivé ici la recherche de la même erreur, mais de Node.js pilote natif . La réponse pour moi était une combinaison de réponses de Campeterson et Prabhat .

Le problème est que le readPreferenceparamètre par défaut est primary, ce qui conduit en quelque sorte à l' slaveOkerreur déroutante . Mon problème est que je veux juste lire à partir de mon jeu de répliques à partir de n'importe quel nœud. Je ne me connecte même pas au réplicaset. Je me connecte simplement à n'importe quel nœud pour y lire.

Mettre readPreferenceà primaryPreferred(ou mieux à la ReadPreference.PRIMARY_PREFERREDconstante) l'a résolu pour moi. Il suffit de passer comme une option MongoClient.connect()ou client.db()ou à tout find(), aggregate()ou toute autre fonction.

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