วิธีการรับแกนเพื่อยกระดับการกำหนดค่า MySQL master / slave?


21

ฉันอ่านคำถามนี้การจำลองแบบ MySQL master / slave ไม่ทำงานและคำตอบ:

การใช้ฐานข้อมูล Slave นั้นแทบจะไม่มีการใช้งานใน Drupal core หากคุณกำลังพัฒนาโมดูลของคุณเองการเรียกไปยัง db_query จำเป็นต้องระบุว่าพวกเขาต้องการใช้ฐานข้อมูลทาสโดยใช้อาร์เรย์ $ options ดู DatabaseConnection :: defaultOptions สำหรับวิธีการตั้งค่าอาร์เรย์นี้

มีวิธีโดยไม่ฆ่าลูกแมวที่แฮ็คคอร์เพื่อรับdb_query()และdb_select()สร้างคิวรีแบบ SELECT เพิ่มเติมหรือไม่

ตามค่าเริ่มต้นฟังก์ชั่นเหล่านี้จะทำการค้นหาข้อมูลหลักยกเว้นจะบอกให้ทำการสืบค้น Slave โดยเฉพาะ (ดูที่ API) คุณต้องเขียนdb_query($query, $args, array('target' => 'slave'))เพื่อสอบถามทาสและคอร์ (และโมดูลทั้งหมด) ไม่ได้ถูกเขียนเพื่อให้ได้สิ่งนี้

ค้นหาเท่านั้น(ดูส่วนทาส) และผู้รวบรวมดูเหมือนจะใช้ประโยชน์จากสิ่งนี้

แก้ไข:ต.ค. 25
ฉันเห็น pressflow 7 หมดแล้ว แต่ฉันไม่แน่ใจว่าจะช่วยได้มากตอนนี้หรือไม่
ฉันไม่พบสิ่งที่เกี่ยวข้องดังนั้นลองใช้ความช่วยเหลือเล็กน้อยเพื่อช่วยให้ได้รับคำตอบ

แก้ไข:ต.ค. , 31
ฉันกังวลเกี่ยวกับความคิดเห็นของ Crell เป็นหลักเกี่ยวกับหัวข้อนี้: จะทำอย่างไรกับทาส? .
ส่วนใหญ่มีปัญหาถ้าฉันส่งSELECTแบบสอบถามไปยังทาสสิ่งที่เกิดขึ้นกับความล่าช้าในการจำลองแบบและความจริงที่ว่าฉันอาจต้องการทำnode_load()เพียงแค่หลังจากบันทึกโหนดใหม่

คำตอบ:


17

นี่คือวิธีที่ฉันใช้ในปัจจุบัน

ก่อนอื่นคุณต้องตั้งค่าคลาส SelectQueryExtender ดังนี้:

class SlaveTarget extends SelectQueryExtender {
  public function __construct(SelectQueryInterface $query, DatabaseConnection $connection) {
    if ($connection->getTarget() != 'slave') {
      $connection = Database::getConnection('slave', $connection->getKey());
    }
    parent::__construct($query, $connection);
    $this->addTag('SlaveTarget');
  }
}

เมื่อคุณมีสิ่งนั้นสิ่งที่คุณต้องทำคือรับแบบสอบถามทั้งหมดเพื่อขยายตัวขยาย :) ถ้ามันสมเหตุสมผล นี่คือตัวอย่างข้อมูล

/**
 * Implements hook_query_alter().
 */
function example_query_alter(QueryAlterableInterface $query) { 
  if (is_a($query, 'SelectQuery') && !$query->hasTag('SlaveTarget')) {
    $query->extend('SlaveTarget');
  }
}

และตอนนี้ SelectQuery ทั้งหมดของคุณไปถึงทาส ;-) นี่เป็นวิธีเดียวที่ฉันสามารถทำได้ อย่างไรก็ตามมันใช้งานได้ดี

นอกจากนี้หากคุณมีสิ่งนี้ในโมดูลที่กำหนดเองคุณสามารถตั้งค่า SlaveTarget ให้เป็นไฟล์ SlaveTarget.inc และเพิ่มไฟล์ [] = SlaveTarget.inc ไปยังไฟล์ข้อมูลโมดูลของคุณ


สวัสดีเอริคขอบคุณสำหรับคำตอบของคุณสิ่งที่ทำให้ฉันกังวลมากที่สุดคือหัวข้อนี้: จะทำอย่างไรกับทาส? และแสดงความคิดเห็นเกี่ยวกับ Crell ทาส ดังนั้นคุณจะแก้ปัญหาความปลอดภัยในทุกกรณี? คุณ จำกัด การSELECTสืบค้นไหม? คุณจะจัดการกับความล่าช้าในการจำลองแบบและความจริงที่ว่าโหลดโหนดหลังจากบันทึกไว้อาจทำให้เกิดปัญหาได้อย่างไร
tostinni

นี่เป็นการเปลี่ยนฐานข้อมูลให้เป็นทาสเฉพาะในแบบสอบถามแบบใช้เลือกข้อมูล สิ่งนี้จะเกิดขึ้นเมื่อแบบสอบถามถูกเขียนด้วย SelectQuery ไม่ใช่ db_query ดังนั้นไม่จำเป็นต้องกังวลเกี่ยวกับและแทรกหรืออัปเดตเป้าหมายที่เป็นทาส เรากำลังดำเนินการใน 3 สภาพแวดล้อมการผลิตขนาดใหญ่โดยไม่มีปัญหาใด ๆ ฉันไม่ได้กังวลเกี่ยวกับการจำลองแบบ mysql เกือบจะทันที (ในกรณีของฉัน) แต่ฉันสามารถดูว่าอาจเป็นปัญหาเล็ก ๆ ในสภาพแวดล้อมบางอย่าง
ericduran

ขอบคุณสำหรับคำตอบของคุณมันเป็นคำตอบที่ยอดเยี่ยมฉันจะดูว่ามันเป็นไปได้หรือไม่ในสภาพแวดล้อมของเรา
tostinni

เอริครหัสนี้ออกมีที่ไหนสักแห่งในฐานะ contrib หรือโมดูลทราย?
paul-m

@ Paul-m: ดูdrupal.org/project/autoslave
โม

5

AutoSlaveโมดูลเปลี่ยนเส้นทางSELECTแบบสอบถามเพื่ออ่านอย่างเดียวฐานข้อมูล replicant, และมันจะเข้าสู่ความล่าช้าการจำลองแบบบัญชี

ตามเอกสาร doc โมดูลมันจะใช้การจำลองแบบอ่านอย่างเดียวเท่านั้นเมื่อเงื่อนไขต่อไปนี้ทั้งหมดเป็นจริง:

  1. แบบสอบถามเป็นแบบสอบถามแบบใช้เลือกข้อมูล
  2. ตารางในแบบสอบถามแบบใช้เลือกข้อมูลยังไม่ได้ถูกเขียนไปในระหว่างการร้องขอและภายในช่วงเวลาของการจำลองแบบล่าช้า
  3. ธุรกรรมยังไม่เริ่มต้น
  4. ตารางในแบบสอบถามแบบใช้เลือกข้อมูลไม่ได้ระบุไว้ในตัวเลือก 'ตาราง' ในการตั้งค่าไดรเวอร์
  5. ยังไม่ได้เริ่มการล็อค (รองรับ core db-lock และ memcache-lock)

1

จากสิ่งที่ฉันได้ยินเมื่อเร็ว ๆ นี้ Drupal BADcamp Pressflow เป็นวิธีที่จะไปหากคุณต้องการการกำหนดค่าหลัก / ทาส คุณจะถูก จำกัด ให้ Mysql เป็นฐานข้อมูล นอกจากนี้ให้ชำระเงิน " กลุ่มที่มีประสิทธิภาพสูง " ที่ต้องทำ


1
ปัจจุบัน Pressflow 7 = D7 ไม่มีสิ่งใด (Press) ที่ Pressflow ทำเช่นนั้น D7 ไม่ได้ :(
tostinni

1

แม้จะมีงานที่น่าทึ่งทั้งหมดที่ทำในชั้น abstraction ของฐานข้อมูลใน Drupal 7 แต่ก็ยังคงเป็นเรื่องยากที่จะทำกับ Drupal core นอกกรอบ อย่างที่คนอื่นพูดถึงAutoSlaveเป็นตัวเลือกแม้ว่าจะไม่ใช่คนที่ฉันเคยพยายามเพราะปฏิเสธที่ดื้อรั้นของฉันที่จะเชื่อว่ามันยากที่จะทำแบบนี้

ทางออกที่ง่ายกว่าที่ฉันพบมีดังต่อไปนี้ ในการจัดเส้นทางs ทั้งหมด SELECTไปยังเซิร์ฟเวอร์ทาสคุณสร้างไฟล์ชื่อselect.incภายในincludes/database/mysqlไดเรกทอรีหลักที่มีเนื้อหาดังต่อไปนี้:

<?php

/**
 * @file
 * Select builder for MySQL database engine, routing all SELECTs to the slave.
 */

/**
 * @addtogroup database
 * @{
 */

class SelectQuery_mysql extends SelectQuery {
  public function __construct($table, $alias = NULL, DatabaseConnection $connection, $options = array()) {
    $key = $connection->getKey();
    $connection = Database::getConnection('slave', $key);
    $options['target'] = 'slave';
    parent::__construct($table, $alias, $connection, $options);
  }
}

/**
 * @} End of "addtogroup database".
 */

มีความเสี่ยงด้วยวิธีนี้:

  1. วิธีนี้จะขโมยทั้งหมด SELECTและนำพวกเขาไปยังทาสซึ่งจะทำให้เกิดปัญหาอย่างไม่ต้องสงสัยถ้าคุณมีความล่าช้าในการจำลองแบบ อ่านประโยคนั้นอีกครั้ง
  2. เมื่อคุณอัพเกรดแกน Drupal อาจเป็นไปได้ว่าไฟล์นี้จะถูกลบ
  3. ถ้า Drupal core เคยเริ่มจัดส่งด้วยตัวเองincludes/database/mysql/select.incไฟล์ของคุณจะถูกเขียนทับในระหว่างการอัพเกรดและคุณจะต้องเริ่มรักษารุ่น select.inc ที่ได้รับการติดตั้งแล้วซึ่งมาพร้อมกับ Drupal core

หากคุณไม่มีทาสเซิร์ฟเวอร์ใด ๆ ที่ระบุไว้ใน settings.php รหัสด้านบนจะไม่ทำให้เกิดปัญหา มันจะยังคงลดลงอย่างสง่างามเมื่อใช้เซิร์ฟเวอร์หลัก


ใช่มันจะปรากฏขึ้นแม้ว่าการเชื่อมต่อสามารถตั้งค่าเป็น "ทาส" หากแบบสอบถามไม่ได้target => 'slave'ตั้งค่าตัวเลือกมันจะยังคงทำงานในการเชื่อมต่อเริ่มต้น มันเป็นความเจ็บปวดที่ไม่สามารถกำหนดเป้าหมายการเชื่อมต่อได้ง่ายขึ้นในquery_alterระดับ
David Thomas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.