Bir MySQL master / slave konfigürasyonundan yararlanmak için çekirdek almak


21

Bu soru okumak MySQL efendi / köle çalışmıyor çoğaltma ve cevap:

Köle veritabanlarının kullanılması Drupal çekirdeğinde zar zor uygulanmaktadır. Kendi modüllerinizi geliştiriyorsanız, db_query çağrıları, $ options dizisini kullanarak slave veritabanını kullanmak istediklerini belirtmelidir. Bu dizinin nasıl ayarlanacağı hakkında DatabaseConnection :: defaultOptions bölümüne bakınız.

Almakdb_query() ve db_select()daha fazla köle SELECT sorgusu yapmak için çekirdeği hackleyen yavru kedileri öldürmenin bir yolu var mı ?

Varsayılan olarak, bu işlevler, köleyi sorgulaması özel olarak söylenmediği sürece master'ı sorgulayacaktır (API'larına bakınız). db_query($query, $args, array('target' => 'slave'))Köleyi sorgulamak için yazmak zorundasınız ve çekirdeği (ve tüm modülleri) bunu başarmak için yazılmamış.

Yalnızca arama (köle bölümüne bakın) ve toplayıcı bunu kaldıracak gibi görünüyor.

Düzenleme: Ekim, 25
Pressflow 7 çıktı çıktı ama şu anda çok yardımcı olup olmadığından emin değilim.
Alakalı bir şey bulamadım, bu yüzden cevap alamam için biraz lütuf deneyelim.

Düzenleme: Eki, 31
Genelde Crell'in bu konudaki yorumları hakkında endişeliyim: Kölelerle ne yapmalı? .
Temel olarak, SELECTköle sorguları gönderirsem , replikasyondaki gecikmelerde ve node_load()yeni bir düğümü kaydettikten hemen sonra yapmak isteyebileceğim gerçeği var mı ?

Yanıtlar:


17

İşte şu anda bunu nasıl uygulayacağım.

İlk önce böyle bir SelectQueryExtender sınıfı kurmanız gerekir:

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');
  }
}

Bunu yaptıktan sonra, yapmanız gereken tek şey genişleticiyi genişletmek için diğer tüm sorguları almaktır. :) Mantıklı geliyorsa. İşte pasajı.

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

Ve şimdi tüm SelectQuery'niz köle isabet etti ;-) Bu başarabilmemin tek yolu bu. Neyse harika çalışıyor.

Ayrıca, bunu özel bir modülde kullanıyorsanız, SlaveTarget'ı SlaveTarget.inc dosyasında olacak şekilde ayarlayabilir ve bir dosya [] = SlaveTarget.inc modül modülünüze ekleyebilirsiniz.


Merhaba, Eric, cevabınız için teşekkürler, beni esas endişelendiriyor bu konu: Kölelerle ne yapmalı? ve Crell'in köle ilgili yorumu . Öyleyse, her durumda çözüm güvenli midir? Bazı SELECTsorguları kısıtlıyor musunuz ? Çoğaltmadaki gecikmelerle nasıl başa çıkacaksınız ve bir düğümü kaydettikten hemen sonra yüklemek sorunlara neden olabilir mi?
tostinni

Bu, veritabanını yalnızca Seçme sorguları üzerinde bağımlı olarak değiştiriyor. Bu sadece, sorgu SelectQuery ile db_query değil de yazıldığında gerçekleşir, bu yüzden köle hedef alan endişelenmenize ve eklemenize veya güncellemenize gerek yoktur. Bunu 3 devasa üretim ortamında sorunsuz olarak çalıştırıyoruz. MySQL çoğaltması hakkında neredeyse hiç olmadığı kadar endişelenmedim (benim durumumda), ancak bazı ortamlarda bunun nasıl küçük bir sorun olabileceğini görebiliyorum.
ericduran

Cevaplarınız için teşekkürler, bu harika bir çözüm, bunun çevre için geçerli olup olmadığını göreceğim.
tostinni

Eric, bu kod bir katkı ya da sanal alan modülü olarak dışarıda bir yerde mi?
paul-m


5

AutoSlave modülü yönlendirmeleri SELECTsorguları yinelenmiş veritabanları salt okunur, ve o hesap kopyalama gecikmesi dikkate alır.

Modül belgelerine göre, aşağıdaki koşulların tümü geçerli olduğunda yalnızca salt okunur kopyayı kullanır:

  1. Sorgu bir seçim sorgusu
  2. Seçim sorgusu içindeki tablolar istek sırasında ve varsayılan çoğaltma gecikmesi içinde yazılmamış
  3. Bir işlem başlatılmadı
  4. Seçim sorgusu içindeki tablolar, sürücü ayarlarındaki 'tablolar' seçeneğinde belirtilmez.
  5. Bir kilit başlatılmadı (çekirdek db kilidi ve memcache kilidi desteklendi)

1

Son Drupal BADcamp Pressflow'ta duyduğuma göre, master / slave konfigürasyonları istiyorsanız gitmek için bir yoldur. DB olarak Mysql ile sınırlı olacaksınız. Ayrıca, " yüksek performans grubu " nu kontrol edin


1
Şu anda Pressflow 7 = D7,
Pressflow'un

1

Drupal 7'deki veritabanı soyutlama katmanı üzerinde yapılan tüm şaşırtıcı çalışmalara rağmen, bu Drupal çekirdeği kutudan çıkarıldığında hala şaşırtıcı şekilde zordur. Diğerlerinin de belirttiği gibi, AutoSlave bir seçenek, inatçı bir şekilde bunu yapmanın bu kadar zor olması gerektiğine inanmayı reddettiğim için denediğim bir seçenek değil.

Bulduğum daha basit bir çözüm aşağıdadır. Yönlendirmek için tüm SELECT köle sunucusuna ler, başlıklı bir dosya oluşturmak select.incçekirdek içinde includes/database/mysqlaşağıdaki içeriği ile dizine:

<?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".
 */

Bu yöntemde bazı riskler vardır:

  1. Bu yöntem hepsini siler SELECTve onları köleye yönlendirir, şüphesiz çoğaltmada herhangi bir gecikme yaşarsanız şüphesiz sorunlara neden olur. O cümleyi tekrar oku.
  2. Drupal çekirdeğini yükselttiğinizde, bu dosyanın silinmesi olasıdır.
  3. Drupal çekirdeği includes/database/mysql/select.inckendi gönderisiyle başlayacaksa, yükseltme sırasında dosyanızın üzerine yazılır ve Drupal çekirdeği ile birlikte gelen select.inc öğesinin kendi yamalı sürümünü korumaya başlamanız gerekir.

Settings.php içinde belirtilen hiçbir bağımlı sunucunuz yoksa, yukarıdaki kod bir soruna neden olmaz. Ana sunucuyu kullanmaya yine de zarifçe düşecektir .


Evet, bağlantı "bağımlı" olarak ayarlanabilse de, sorgu kendinde bir target => 'slave'seçenek ayarlanmamışsa, varsayılan bağlantıda çalışmaya devam eder. Bağlantı hedefini daha kolay bir şekilde ayarlamak kolay değildir query_alter.
David Thomas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.