mongodb、複製、エラー:{“ $ err”:“ not master and slaveOk = false”、“ code”:13435}


174

初めてモンゴのレプリカセットを試しました。

ec2でubuntuを使用していて、3つのインスタンスを起動しました。各インスタンスのプライベート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サイト私は主、seconday、およびアービタを持っていることがわかります。

さて、今テストのために。

プライマリでこれにデータベースを作成するのはコードです:

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

セカンダリでは、これを実行して以下のエラーが発生します。

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

私はmongodbに非常に慣れておらず、複製しますが、1つで何かを行うと、もう1つに行くと思いました。それで、レコードを1つに追加した場合、マシン間で複製するにはどうすればよいですか?


私はrs.slaveOk();を使用する必要があることを理解しました。それは私に別の質問を残します。これをすべてのクエリで行う必要がありますか?マスターノードにいる場合はどうなりますか?

回答:


282

セカンダリからの読み取りを許可していることをmongoシェルに通知するには、「スレーブオーケー」モードを設定する必要があります。これは、あなたとあなたのアプリケーションが偶然に最終的に一貫した読み取りを実行するのを防ぐためです。シェルでこれを行うことができます:

rs.slaveOk()

その後、セカンダリから通常どおりクエリを実行できます。

「結果整合性」に関する注記:通常の状況では、レプリカセットのセカンダリはすべてプライマリと同じデータを1秒以内に保持します。非常に高い負荷がかかると、プライマリに書き込んだデータがセカンダリに複製されるまでに時間がかかる場合があります。これは「レプリカラグ」と呼ばれ、遅れているセカンダリからの読み取りは「最終的に整合性のある」読み取りと呼ばれます。これは、新しく書き込まれたデータが(ネットワーク障害などの理由で)ある時点で表示される一方で、すぐに利用できます。

編集:セカンダリからクエリを実行するときに、slaveokを設定するだけでよく、セッションごとに1回だけです。


3
DBで理解できないコマンドを実行する前に、必ずマニュアルを確認してください。答えが説明しないコマンドへの結果があるかもしれません。このコマンドは、レプリカセットへのすべての接続に対する読み取り操作の配布方法を変更しますか?よく調べる。このコマンドは、v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOkまでさかのぼって表示できます特定のバージョンに変更して、関連情報を取得していることを確認してください。
Bruno Bronosky

45

rs.slaveOk()毎回入力するのを避けるには、次のようにします。

という名前のファイルを作成し、次のreplStart.js1行を含めます。rs.slaveOk()

次に--shell replStart.js、Mongoシェルを起動するときに含めます。もちろん、ローカルで単一のインスタンスに接続している場合は、タイピングの手間が省けます。


26
タイピングを節約するより良い方法はrs.slaveOk()~/.mongorc.jsファイルに追加することです。これは、mongoシェルの起動時に自動的に実行されます。
ステニー

2
私はそれが有用でデフォルトの設定を置くことを見つける~/.mongorc.jsには、カスタム設定replStart.jsまたはadminStart.jsまたはものは何でも。
Ed Norris 2013年


11

これは、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」が3番目のオプションの引数であることに注意してください。



1

私は、DBプロバイダーからの厄介な状況に対してこの回答を追加しています。

私たちの場合に起こったことは、プライマリとセカンダリのdbが逆にシフトされており(プライマリからセカンダリ、そしてその逆)、同じエラーが発生しています。

構成設定でデータベースステータスを確認してください。


0

ここで同じエラーを検索しましたが、Node.jsネイティブドライバからのものです。私の答えは、campetersonPrabhatの答えを組み合わせたものでした。

問題は、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 });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.