MySQL 마스터 / 슬레이브 구성을 활용하기 위해 핵심을 확보하는 방법은 무엇입니까?


21

이 질문을 읽고 MySQL 마스터 / 슬레이브 복제가 작동하지 않고 그 답변을 얻었습니다.

Drupal 코어에서는 슬레이브 데이터베이스 사용이 거의 구현되지 않았습니다. 자체 모듈을 개발하는 경우 db_query를 호출하면 $ options 배열을 사용하여 슬레이브 데이터베이스를 사용하도록 지정해야합니다. 이 배열을 설정하는 방법은 DatabaseConnection :: defaultOptions를 참조하십시오.

없는 방법이 새끼 고양이를 죽이는 핵심 얻을 수있는 해킹 db_query()db_select()이상의 슬레이브 SELECT 쿼리를 만들기 위해는?

기본적으로 이러한 함수는 슬레이브를 쿼리하도록 특별히 지시하지 않는 한 마스터를 쿼리합니다 (API 참조). 당신은 작성해야 db_query($query, $args, array('target' => 'slave'))이를 달성하기 위해 작성되지 않은 슬레이브 코어 (모든 모듈)에 문의하는 경우에,.

검색 (슬레이브 부분 참조)과 애그리 게이터 만 이 이것을 활용하는 것 같습니다.

편집 : 10 월 25 일
pressflow 7이 나오지 만 지금 많은 도움이되는지 확실하지 않습니다.
나는 적절한 것을 찾지 못했기 때문에 약간의 현상금을 시도하여 답변을 얻도록하겠습니다.

편집 : 10 월 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를 모듈 정보 파일에 추가 할 수 있습니다.


안녕하세요 Eric, 답변 주셔서 감사합니다.이 스레드가 주로 걱정되는 것은 : 노예와 어떤 관계입니까? 그리고 슬레이브에 관한 Crell의 의견 . 어떤 경우에도 안전한 솔루션입니까? 일부 SELECT쿼리 를 제한 합니까? 복제 지연 및 노드를 저장 한 직후로드하면 문제가 발생할 수 있다는 사실을 어떻게 처리합니까?
tostinni

Select 쿼리에서만 데이터베이스를 슬레이브로 변경합니다. 이는 쿼리가 db_query가 아닌 SelectQuery로 작성된 경우에만 발생하므로 슬레이브를 대상으로하는 것에 대해 걱정하거나 삽입하거나 업데이트 할 필요가 없습니다. 우리는 아무런 문제없이 3 개의 거대한 프로덕션 환경에서 이것을 실행하고 있습니다. 필자는 mysql 복제를 거의 즉각적으로 (내 경우에는) 걱정하지 않았지만 특정 환경에서 어떻게 작은 문제가 될 수 있는지 알 수 있습니다.
ericduran

귀하의 답변에 감사드립니다, 그것은 훌륭한 솔루션입니다, 이것이 우리 환경에서 가능한지 볼 것입니다.
tostinni

Eric,이 코드가 contrib 또는 샌드 박스 모듈로되어 있습니까?
paul-m

@ paul-m : drupal.org/project/autoslave를 참조하십시오 .
smokris

5

AutoSlave 모듈 리디렉션의 SELECT쿼리는 리플리 데이터베이스를 읽기 전용으로, 그리고 이 계정 복제 지연에 걸립니다.

모듈 문서에 따르면 다음 조건이 모두 충족되는 경우 읽기 전용 복제본 만 사용합니다.

  1. 쿼리는 선택 쿼리입니다
  2. 요청시 및 가정 된 복제 지연 내에 선택 쿼리의 테이블이 기록되지 않았습니다.
  3. 거래가 시작되지 않았습니다
  4. 선택 쿼리의 테이블이 드라이버 설정의 '테이블'옵션에 지정되어 있지 않습니다
  5. 잠금이 시작되지 않았습니다 (코어 db-lock 및 memcache-lock 지원)

1

최근 Drupal BADcamp Pressflow에서 들었던 것에서 마스터 / 슬레이브 구성을 원한다면 갈 수 있습니다. DB는 Mysql로 ​​제한됩니다. 또한 " 고성능 그룹 "을 확인하십시오.


1
현재 Pressflow 7 = D7, Pressflow가 D7이하지 않는 일 (아직)은 없습니다 :(
tostinni

1

Drupal 7의 데이터베이스 추상화 계층에서 수행 된 놀라운 작업에도 불구하고 Drupal 코어를 사용하는 것은 놀라운 일이 아닙니다. 다른 사람들이 언급했듯이, AutoSlave 는 선택 사항이지만, 완고한 거절로 인해 시도하기가 어려운 것이 아니라고 시도한 것은 아닙니다.

내가 찾은 간단한 해결책은 다음과 같습니다. 모든 SELECT s를 슬레이브 서버로 라우팅하려면 다음 내용으로 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 코어가 자체로 배송을 시작한 경우 includes/database/mysql/select.inc업그레이드 중에 파일을 덮어 쓰게되며 Drupal 코어와 함께 제공되는 select.inc의 패치 버전을 유지 관리해야합니다.

settings.php에 슬레이브 서버가 지정되어 있지 않으면 위의 코드는 문제를 일으키지 않습니다. 여전히 마스터 서버 사용으로 정상적으로 저하됩니다 .


예, 연결이 "슬레이브"로 설정 될 수 있지만 조회 자체에 target => 'slave'옵션이 설정 되지 않은 경우 에도 여전히 기본 연결에서 실행됩니다. 연결 대상을 query_alter레벨 에서 더 쉽게 설정하기가 쉽지 않습니다 .
David Thomas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.