Bagaimana cara mendapatkan core untuk meningkatkan konfigurasi master / slave MySQL?

21

Saya membaca pertanyaan ini replikasi master / slave MySQL tidak berfungsi dan jawabannya:

Menggunakan database slave hampir tidak diimplementasikan dalam inti Drupal. Jika Anda mengembangkan modul Anda sendiri maka panggilan ke db_query perlu menentukan bahwa mereka ingin menggunakan database slave menggunakan array $ options. Lihat DatabaseConnection :: defaultOptions untuk cara mengatur array ini.

Adakah cara tanpa membunuh anak kucing yang meretas inti untuk mendapatkan db_query()dan db_select()membuat lebih banyak permintaan SELECT budak?

Secara default, fungsi-fungsi ini akan meminta master kecuali jika secara khusus diberitahu untuk meminta budak (lihat API mereka) Anda harus menulis db_query($query, $args, array('target' => 'slave'))untuk meminta budak dan inti (dan semua modul) tidak ditulis untuk mencapai ini.

Hanya pencarian (lihat bagian slave) dan agregator yang tampaknya memanfaatkan ini.

Sunting: Okt, 25
Saya melihat pressflow 7 keluar tapi saya tidak yakin apakah itu banyak membantu saat ini.
Saya belum menemukan sesuatu yang relevan jadi mari kita coba sedikit karunia untuk membantu ini mendapatkan jawaban.

Sunting: Okt, 31
Saya terutama khawatir tentang komentar Crell mengenai topik ini: Apa yang harus dilakukan dengan budak? .
Terutama, apakah ada masalah jika saya mengirim SELECTpertanyaan ke slave, apa yang terjadi dengan keterlambatan dalam replikasi dan fakta bahwa saya mungkin ingin melakukan node_load()sesaat setelah menyimpan node baru.

tostinni
sumber

Jawaban:

17

Begini cara saya mengimplementasikan ini.

Pertama, Anda perlu mengatur kelas SelectQueryExtender seperti ini:

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

Setelah Anda memilikinya, maka yang harus Anda lakukan adalah mendapatkan semua pertanyaan lain untuk memperpanjang extender. :) jika itu masuk akal. Ini cuplikannya.

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

Dan sekarang semua SelectQuery Anda mengenai budak ;-) Ini adalah satu-satunya cara saya dapat mencapai ini. Bagaimanapun itu bekerja dengan baik.

Juga jika Anda memiliki ini pada modul khusus, Anda dapat mengatur SlaveTarget agar berada di file SlaveTarget.inc dan menambahkan file [] = SlaveTarget.inc ke file info modul Anda.

ericduran
sumber
Hai Eric, terima kasih atas jawaban Anda, yang terutama membuat saya khawatir adalah utas ini: Apa yang harus dilakukan dengan budak? dan komentar Crell tentang budak . Jadi, apakah solusi Anda aman dalam hal apa pun? Apakah Anda membatasi beberapa SELECTpermintaan? Bagaimana Anda menangani keterlambatan dalam replikasi dan fakta bahwa memuat simpul setelah disimpan dapat menyebabkan masalah?
tostinni
Ini mengubah database menjadi slave hanya pada Select queries. Ini hanya terjadi ketika kueri telah ditulis dengan SelectQuery bukan db_query sehingga tidak perlu khawatir dan menyisipkan atau memperbarui yang ditargetkan ke slave. Kami menjalankan ini pada 3 lingkungan produksi besar tanpa masalah. Saya belum terlalu khawatir tentang replikasi mysql karena hampir instan (dalam kasus saya) tetapi saya bisa melihat bagaimana itu mungkin menjadi masalah kecil di lingkungan tertentu.
ericduran
Terima kasih atas jawaban Anda, ini solusi hebat, saya akan melihat apakah ini layak untuk lingkungan kita.
tostinni
Eric, apakah kode ini ada di luar sana sebagai modul contrib atau sandbox?
paul-m
@ paul-m: lihat drupal.org/project/autoslave .
smokris
5

The AutoSlave pengalihan modul SELECTquery untuk read-only database replicant, dan dibutuhkan dalam replikasi akun lag.

Menurut dokumen modul, itu hanya menggunakan replant baca-saja ketika semua kondisi berikut ini benar:

  1. Kueri adalah kueri pemilihan
  2. Tabel dalam kueri pemilihan belum ditulis selama permintaan dan dalam jeda replikasi yang diasumsikan
  3. Transaksi belum dimulai
  4. Tabel dalam kueri pemilihan tidak ditentukan dalam opsi 'tabel' dalam pengaturan driver
  5. Kunci belum dimulai (core db-lock dan memcache-lock didukung)
smokris
sumber
1

dari apa yang saya dengar di Drupal BADcamp Pressflow baru-baru ini adalah cara untuk pergi jika Anda ingin konfigurasi master / slave. Anda akan terbatas pada Mysql sebagai DB. Juga, keluar dari " grup berkinerja tinggi " saat bekerja

kamu
sumber
1
Saat ini Pressflow 7 = D7, tidak ada (belum) bahwa Pressflow melakukan itu D7 tidak :(
tostinni
1

Terlepas dari semua pekerjaan luar biasa yang dilakukan pada lapisan abstraksi basis data di Drupal 7, ini masih sangat sulit dilakukan dengan inti Drupal di luar kotak. Seperti yang telah disebutkan orang lain, AutoSlave adalah sebuah pilihan, meskipun bukan yang saya coba karena penolakan keras kepala saya untuk percaya bahwa itu harus sulit untuk melakukan ini.

Solusi sederhana yang saya temukan adalah sebagai berikut. Untuk merutekan semua SELECT s ke server slave, Anda membuat file berjudul select.incdi dalam includes/database/mysqldirektori inti dengan konten berikut:

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

Ada beberapa risiko dengan metode ini:

  1. Metode ini akan membajak semua SELECT dan mengarahkan mereka ke budak, yang tidak diragukan lagi akan menyebabkan masalah jika Anda memiliki keterlambatan dalam replikasi. Baca kalimat itu lagi.
  2. Ketika Anda memutakhirkan inti Drupal, ada kemungkinan bahwa file ini akan dihapus.
  3. Jika inti Drupal pernah memulai pengiriman dengan miliknya sendiri includes/database/mysql/select.inc, file Anda akan ditimpa selama peningkatan, dan Anda harus mulai mempertahankan versi tambalan Anda sendiri yang dipilih.

Jika Anda tidak memiliki server slave yang ditentukan di settings.php, kode di atas tidak akan menyebabkan masalah. Itu masih akan dengan anggun menurunkan menggunakan server master .

q0rban
sumber
Ya, itu muncul meskipun koneksi dapat diatur ke "budak", jika permintaan itu sendiri tidak memiliki target => 'slave'opsi yang ditetapkan, itu akan tetap berjalan pada koneksi default. Ini menyebalkan itu tidak mudah untuk menetapkan target koneksi lebih mudah di query_altertingkat.
David Thomas