@RolandoMySQLDBA ได้ตอบคำถามอย่างถูกต้อง ... แต่เขายังชี้ให้เห็นว่าทางออกของเขาคือ "รวดเร็วและสกปรก"
และนั่นคือคำแถลงที่แท้จริง :)
สิ่งที่เกี่ยวข้องกับฉันที่นี่ไม่ใช่คำตอบนั้น แต่เป็นคำถามเดิมที่ดูเหมือนจะทำให้สมมติฐานที่ไม่ถูกต้อง:
ฉันสามารถค้นหาเซิร์ฟเวอร์ทั้งสองและถามว่าเซิร์ฟเวอร์ใดเป็นเซิร์ฟเวอร์หลักแล้วดำเนินการสอบถามทั้งหมดไปยังเซิร์ฟเวอร์นั้น
ปัญหาคือว่าในการจำลองแบบ MySQL ต้นแบบไม่เคยรู้จริง ๆ ว่ามันเป็นต้นแบบ
แนวคิดของ "promotion to master" ไม่ใช่แนวคิดในการจำลองแบบอะซิงโครนัสของ MySQL "การโปรโมต" เซิร์ฟเวอร์ MySQL ไปที่บทบาทหลักคือสิ่งที่เกิดขึ้น "ภายนอก" เซิร์ฟเวอร์ MySQL ซึ่งตรงข้ามกับสิ่งที่เกิดขึ้น "ภายใน" กับเซิร์ฟเวอร์ MySQL
"การส่งเสริมการขายเป็นหลัก" ไม่ได้ดำเนินการโดยการจัดเตรียมเซิร์ฟเวอร์ใด ๆ เพราะในทางเทคนิคแล้วเซิร์ฟเวอร์ MySQL ทุกเครื่องที่เปิดใช้งานการบันทึกแบบไบนารีนั้นเป็นผู้เชี่ยวชาญแม้ว่าจะไม่เคยมีทาสก็ตาม SHOW MASTER STATUS
ทำงานในลักษณะเดียวกันและส่งกลับผลลัพธ์เดียวกันทาสหรือไม่และต้นแบบที่มี 2 ทาสไม่ได้เป็นเจ้านายมากกว่าทาสที่มีทาส 1 คนหรือทาส 0 คน ในทำนองเดียวกันเจ้านายที่มีทาสทุกคนออฟไลน์ยังคงเป็นเจ้านายอยู่มากเพราะเมื่อทาสกลับมาออนไลน์พวกเขาจะรับการจำลองที่พวกเขาทิ้งไว้
เรียกได้ว่า "การรับรู้" เพียงอย่างเดียวในส่วนของเซิร์ฟเวอร์นั้นไม่ว่าจะเป็นมาสเตอร์ แต่จะเป็นทาส (หรือ "ไม่ใช่")
นั่นคือสิ่งที่ทางออกของ Rolando ถาม: "คุณเป็นทาสหรือไม่" หากคำตอบคือไม่แล้วสมมติฐานก็คือว่านี้จะต้องเป็นเจ้านาย ... ซึ่งเขาก็ชี้ให้เห็นว่าเป็นข้อสันนิษฐานข้อบกพร่องหากSTOP SLAVE;
มีการออก แต่ทาสที่ถูกหยุดยังคงเป็นทาสดังนั้น "ไม่ใช่ทาส" (ในเวลาใดก็ได้) ไม่ถือเอาว่าเป็น "เจ้านาย"
การทดสอบที่คล้ายกันสามารถทำได้กับผู้เชี่ยวชาญสันนิษฐานว่า:
SELECT COUNT(1) FROM information_schema.processlist
WHERE user = 'the_username_used_by_the_slave';
หรือ
SELECT COUNT(1) FROM information_schema.processlist
WHERE command = 'binlog dump';
หากค่าเป็นศูนย์แสดงว่า IO thread ของ slave ไม่ได้เชื่อมต่อ การทดสอบนี้มีข้อบกพร่องที่คล้ายกันซึ่งหากทาสถูกตัดการเชื่อมต่อการบริหารแยกหรือล้มเหลวแล้วมันจะไม่ถูกเชื่อมต่อ ดังนั้นนี่ไม่ได้แก้อะไรด้วย
ยังเลว (สำหรับสถานการณ์เหล่านี้อย่างใดอย่างหนึ่ง) information_schema.processlist "ตาราง" เป็นตารางเสมือนที่ได้รับเป็นรูปธรรมทุกครั้งที่มันถูกเลือกจากและสิ่งนี้ต้องใช้เวลาและค่าใช้จ่ายทรัพยากร ยิ่งเซิร์ฟเวอร์ของคุณยุ่งมากเท่าใดก็ยิ่งมีค่าใช้จ่ายมากขึ้นเพราะกิจกรรมของแต่ละเธรดจะต้องมีการพิจารณา
โซลูชันที่มีน้ำหนักเบากว่านี้คือ:
SELECT @@global.read_only;
บนทาสคุณสามารถ / ควรตั้งค่าตัวแปรส่วนกลางread_only
เพื่อให้ผู้ใช้ที่ไม่มีSUPER
สิทธิ์ไม่สามารถเขียนลงไปโดยไม่ได้ตั้งใจ (และแอปพลิเคชันของคุณไม่ควรมีSUPER
) หากคุณ "เลื่อนขั้น" ทาสด้วยตนเองไปยังบทบาทหลักคุณSET GLOBAL read_only = OFF
ต้องเปิดใช้งานการเขียน (การจำลองแบบสามารถเขียนถึงทาสได้เสมอไม่ว่าจะตั้งค่าอย่างไร)
แต่นี่ฉันคิดว่ายังคงพลาดจุดสำคัญ:
ฉันจะเสนอว่าแอปพลิเคชันไม่ควรทำการตัดสินใจแบบฮิวริสติกในการตั้งค่าหลัก / ทาสและแน่นอนไม่ได้อยู่บนพื้นฐานของการเชื่อมต่อโดยการเชื่อมต่อ แอปพลิเคชันควรใช้ตัวเลือกการกำหนดค่าอย่างใดอย่างหนึ่งหรือแอปพลิเคชันควรไม่ทราบและมีปลายทางการเชื่อมต่อฐานข้อมูลที่จัดการโดยอย่างอื่น
หรืออย่างน้อยที่สุดแอปพลิเคชันไม่ควรสลับไปมาจนกว่าต้นแบบจะล้มเหลวและไม่ควรสลับกลับมาใช้ด้วยตนเอง
นี่คือเหตุผลที่ฉันพูดว่า: เมื่อ "การตัดสินใจ" ถูกสร้างขึ้น - ไม่ว่าจะด้วยวิธีใดก็ตาม - เพื่อสร้างเซิร์ฟเวอร์อื่นเป็นหลักแอปพลิเคชันไม่สามารถได้รับอนุญาตด้วยเหตุผลใดก็ตามที่จะเปลี่ยนกลับไปเป็นต้นแบบดั้งเดิมแม้หลังจากกลับมาออนไลน์ โดยไม่มีการแทรกแซง
สมมติว่าคุณพบข้อผิดพลาดและเกิดข้อผิดพลาดจากซอฟต์แวร์ mysqld_safe
รีสตาร์ทตามหน้าที่mysqld
และการกู้คืนความเสียหายของ InnoDB ดำเนินการอย่างไม่มีที่ติ แต่นั่นใช้เวลาไม่กี่นาที
ในขณะเดียวกันต้นแบบไม่ทำงานดังนั้นแอปพลิเคชันของคุณจึงเปลี่ยนไปใช้งานทาส มีการสร้างธุรกรรมการสั่งซื้อการโอนเงินความเห็นที่โพสต์บล็อกที่แก้ไขไม่ว่าระบบของคุณจะทำอะไร
ตอนนี้ต้นแบบดั้งเดิมกลับมาออนไลน์อีกครั้ง
หากแอปพลิเคชันของคุณเปลี่ยนกลับไปเป็นต้นแบบดั้งเดิมคุณอยู่ในโลกแห่งความเจ็บปวดอย่างแน่นอนเพราะสิ่งต่อไปที่น่าจะเกิดขึ้นคือการจำลองแบบหยุดลงเนื่องจากความไม่สอดคล้องกันเนื่องจากแอปพลิเคชันของคุณเปลี่ยนข้อมูลบนทาสในค่าเฉลี่ย เวลา. ตอนนี้คุณมีเซิร์ฟเวอร์ฐานข้อมูลสองตัวที่มีข้อมูลไม่สอดคล้องกันซึ่งคุณจะต้องกระทบยอดด้วยตนเอง หากมีดอลลาร์หรือคะแนนหรือเครดิตที่เกี่ยวข้องตอนนี้คุณมียอดคงเหลือไม่ตรงกัน
ดังนั้นจึงเป็นเรื่องสำคัญที่แอพพลิเคชั่นจะไม่ได้รับอนุญาตให้เปลี่ยนกลับไปเป็นต้นแบบดั้งเดิมโดยปราศจากการแทรกแซง
รอคุณเพิ่งพบปัญหากับสถานการณ์นี้ตามที่ฉันอธิบายหรือไม่ ต้นแบบล้มเหลว แต่แอปพลิเคชันของคุณจะไม่ใช้ทาสเพราะคิดว่าทาสยังคงเป็นทาสไม่ใช่เจ้านาย ... information_schema.processlist
ข้อความค้นหาบนทาสจะยังส่งคืนค่าที่ไม่เป็นศูนย์แม้ว่าเซิร์ฟเวอร์หลักจะปิดตัวลง .
ดังนั้นแอปพลิเคชั่นไม่ได้ค้นพบอะไรมากนักเนื่องจากคุณจะต้องทำการSTOP SLAVE
ทดสอบด้วยตนเองเพื่อให้มีประโยชน์
อาจเป็นวิธีที่ดีกว่าถ้าคุณต้องการให้แอปพลิเคชันสามารถสลับได้คือการกำหนดค่าเซิร์ฟเวอร์ด้วยการจำลองแบบวงกลม
การเรพลิเคทแบบวนรอบมีปัญหาโดยธรรมชาติของตัวเอง แต่ตราบใดที่แอปพลิเคชันของคุณมักจะเขียนไปยังเซิร์ฟเวอร์หนึ่งครั้งเท่านั้นปัญหาส่วนใหญ่เหล่านั้นจะกลายเป็นเรื่องที่ไม่ใช่ปัญหา กล่าวอีกนัยหนึ่งเครื่องทั้งสองอยู่เสมอและพร้อมกันทั้งต้นแบบและทาสในแง่ของการจำลองแบบ แต่แอปพลิเคชันของคุณผ่านกลไกบางอย่างชี้ไปที่เครื่องเพียงเครื่องเดียวในเวลาเดียวกับ "ต้นแบบ" ที่สามารถและควรเขียน .
คุณไม่สามารถปรับใช้เครื่องมือ HA บนเซิร์ฟเวอร์ MySQL ได้เนื่องจากมีการแยกออกจากกัน แต่คุณสามารถนำไปใช้กับ HAProxy ที่ทำงานบนแอพพลิเคชันเซิร์ฟเวอร์ แอปพลิเคชันเชื่อมต่อกับ "MySQL" บนโลคัลโฮสต์ซึ่งไม่ใช่ MySQL เลย แต่จริงๆแล้ว HAProxy ... และจะส่งต่อการเชื่อมต่อ TCP ไปยังเครื่อง MySQL ที่เหมาะสม
HAProxy สามารถทดสอบการเชื่อมต่อไปยังเซิร์ฟเวอร์ MySQL และเสนอการรับส่งข้อมูลไปยังเครื่อง MySQL ที่ยอมรับการเชื่อมต่อและอนุญาตการพิสูจน์ตัวตนเท่านั้น
การรวมกันของ HAProxy ทำงานบนแอพพลิเคชันเซิร์ฟเวอร์ (ความต้องการทรัพยากรไม่มากเมื่อเทียบกับทุกอย่างที่แอปพลิเคชันเซิร์ฟเวอร์ต้องทำ - มันเป็นเพียงแค่การเชื่อมต่อซ็อกเก็ตเข้าด้วยกันและละเว้นการทำซ้ำ) ... จะเป็นวิธีที่ฉันอาจใช้ในกรณีนี้ตามสิ่งที่รู้จากคำถาม
หรือสำหรับการตั้งค่าด้วยตนเองอย่างเข้มงวดไปกับสิ่งที่ง่ายกว่า "การค้นพบ" เช่นรายการใน/etc/hosts
ไฟล์เซิร์ฟเวอร์แอปที่มีชื่อโฮสต์ที่แอปพลิเคชันใช้เชื่อมต่อกับ MySQL ซึ่งคุณสามารถอัปเดตด้วยตนเองได้ ต้นแบบมีวัตถุประสงค์เพื่อเป็นกระบวนการแบบแมนนวล
หรือสิ่งที่ซับซ้อนยิ่งขึ้นโดยใช้ Percona XtraDB Cluster อย่างไรก็ตามคุณต้องการเพิ่มเซิร์ฟเวอร์ตัวที่สามเนื่องจากมี 3 โหนดใน PXC หาก 2 เซิร์ฟเวอร์สามารถเห็นกันและกัน แต่แยกจากเซิร์ฟเวอร์ 1 ตัว (ถ้าทั้งสามยังคงทำงานอยู่) เซิร์ฟเวอร์ทั้งสองทำงานอย่างมีความสุข แต่ เซิร์ฟเวอร์ 1 ขดตัวเป็นลูกบอลเล็ก ๆ และปฏิเสธที่จะทำอะไรเพราะมันรู้ว่ามันจะต้องเป็นคนแปลก วิธีนี้ใช้งานได้เนื่องจาก 2 รู้ว่าพวกเขายังคงเป็นโหนดส่วนใหญ่ที่ออนไลน์ก่อนที่เครือข่ายจะแยกและ 1 ก็ตระหนักว่ามันไม่ใช่ ด้วย PXC มันไม่สำคัญว่าเซิร์ฟเวอร์ของคุณจะเชื่อมต่อกับแอปพลิเคชันของคุณ
ฉันบอกว่าทั้งหมดนี้คือการพูดว่า "ไม่มีแอพพลิเคชั่นสำรวจเซิร์ฟเวอร์เพื่อดูว่าอันไหนเป็นมาสเตอร์" เพราะมันจะกัดคุณไม่ช้าก็เร็วและมันจะตอดตอนประสิทธิภาพของคุณจนถึงวันที่มันกัด