mongodb, replicates และ error: {“ $ err”:“ ไม่ใช่ master และ slaveOk = false”,“ code”: 13435}


174

ฉันลองชุดจำลองของ Mongo เป็นครั้งแรก

ฉันใช้อูบุนตูบน 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 และ replicates แต่ฉันคิดว่าถ้าฉันทำอะไรบางอย่างในที่หนึ่งมันจะไปที่อื่น ดังนั้นถ้าฉันเพิ่มบันทึกลงในหนึ่งฉันต้องทำอย่างไรเพื่อทำซ้ำในเครื่อง?


คิดออกว่าฉันต้องใช้ rs.slaveOk (); นั่นทำให้ฉันมีคำถามอื่น ฉันต้องทำสิ่งนี้ทำสิ่งนี้สำหรับทุกคำถามหรือไม่? เกิดอะไรขึ้นถ้าฉันอยู่บนโหนดหลัก?

คำตอบ:


282

คุณต้องตั้งค่าโหมด "slave okay" เพื่อให้ mongo shell รู้ว่าคุณอนุญาตให้อ่านจากช่องที่สอง นี่คือการปกป้องคุณและแอปพลิเคชันของคุณจากการอ่านที่สอดคล้องกันในที่สุดโดยไม่ได้ตั้งใจ คุณสามารถทำได้ในเชลล์ด้วย:

rs.slaveOk()

หลังจากนั้นคุณสามารถสอบถามได้ตามปกติจากบุคคลที่สอง

หมายเหตุเกี่ยวกับ "ความสอดคล้องในที่สุด": ภายใต้สถานการณ์ปกติชุดที่สองชุดข้อมูลจำลองมีข้อมูลเดียวกับพรรคในไม่กี่วินาที ในการโหลดที่สูงมากข้อมูลที่คุณเขียนไปยังไฟล์หลักอาจใช้เวลาสักครู่ในการทำซ้ำไปยังรุ่นที่สอง สิ่งนี้เรียกว่า "ความล่าช้าในการจำลอง" และการอ่านจากการปกคลุมด้วยวัตถุทุติยภูมิเป็นที่รู้จักกันว่าการอ่าน "ในที่สุดสอดคล้อง" เพราะในขณะที่ข้อมูลที่เขียนใหม่จะปรากฏขึ้นในบางจุด (ยกเว้นเครือข่ายล้มเหลว ฯลฯ ) อาจไม่ ใช้ได้ทันที

แก้ไข:คุณต้องตั้งค่า slaveok เมื่อทำการสอบถามจากบุคคลที่สองและเพียงครั้งเดียวต่อเซสชัน


3
ตรวจสอบคู่มือก่อนที่จะดำเนินการคำสั่งที่คุณไม่เข้าใจในฐานข้อมูลของคุณ อาจมีผลต่อคำสั่งที่คำตอบไม่ได้อธิบาย คำสั่งนี้เปลี่ยนวิธีกระจายการอ่าน ope สำหรับการเชื่อมต่อทั้งหมดไปยังชุดเรพพลิกาหรือไม่? หาคำตอบกันดีกว่า คำสั่งนี้ปรากฏย้อนหลังได้ถึง v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOkคุณสามารถ (และควร) แทนที่ส่วน "/ manual /" ของ URL docs.mongodb.com เป็นรุ่นเฉพาะของคุณเพื่อให้แน่ใจว่าคุณได้รับข้อมูลที่เกี่ยวข้อง
Bruno Bronosky

45

หากต้องการหลีกเลี่ยงการพิมพ์rs.slaveOk()ทุกครั้งให้ทำดังนี้

สร้างชื่อไฟล์replStart.jsที่มีหนึ่งบรรทัด:rs.slaveOk()

จากนั้น--shell replStart.jsสอดแทรกเมื่อคุณเรียกใช้เชลล์ Mongo แน่นอนหากคุณกำลังเชื่อมต่อภายในเครื่องกับอินสแตนซ์เดียวสิ่งนี้จะไม่บันทึกการพิมพ์ใด ๆ


26
วิธีที่ดีกว่าในการประหยัดในการพิมพ์คือการเพิ่มลงrs.slaveOk()ใน~/.mongorc.jsไฟล์ของคุณซึ่งจะถูกดำเนินการโดยอัตโนมัติเมื่อเริ่มเชลล์ mongo
Stennie

2
ฉันคิดว่ามันมีประโยชน์ที่จะนำการตั้งค่าเริ่มต้น~/.mongorc.jsและการกำหนดค่าที่กำหนดเองในreplStart.jsหรือadminStart.jsหรืออะไรก็ตาม
Ed Norris


11

นี่เป็นเพียงหมายเหตุสำหรับทุกคนที่เกี่ยวข้องกับปัญหานี้โดยใช้ไดรเวอร์ RUBY

ฉันมีปัญหาเดียวกันนี้เมื่อใช้ 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' เป็นอาร์กิวเมนต์ตัวเลือกที่สาม



1

ฉันแค่เพิ่มคำตอบนี้สำหรับสถานการณ์ที่น่าอึดอัดใจจากผู้ให้บริการฐานข้อมูล

สิ่งที่เกิดขึ้นในกรณีของเราคือฐานข้อมูลหลักและรองเปลี่ยนจากการย้อนกลับ (หลักเป็นรองและกลับกัน) และเราได้รับข้อผิดพลาดเดียวกัน

ดังนั้นโปรดตรวจสอบการตั้งค่าการกำหนดค่าสำหรับสถานะฐานข้อมูลที่อาจช่วยคุณได้


0

ผมได้ที่นี่ค้นหาข้อผิดพลาดเดียวกัน แต่จากไดรเวอร์พื้นเมือง Node.js คำตอบสำหรับฉันคือการรวมกันของคำตอบโดยcampetersonและPrabhat

ปัญหาคือ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.