Bir veritabanını MyISAM'den InnoDB'ye nasıl dönüştürebilirim?


9

Yoğun bir Drupal 6 sitesinin genel performansını artıracağını görmek için MyISAM'den InnoDB'ye 500MB veritabanının tüm tablolarını dönüştüreceğim. Ben dönüşüm yapmak için en iyi (yani en güvenli / en kolay / en hızlı) yolu merak ediyorum.


Bu Drupal ile ilgili bir soru gibi görünmüyor mu?
tostinni

2
Doğrudan değil, ama Drupal yöneticilerinin ara sıra yapması gereken bir şey.
mpdonadio

Cevabımı FULLTEXT dizinleri olan MyISAM tablolarını filtrelemek için yeni bir SQL komutu kullanmak üzere güncelledim. Lütfen güncellenmiş cevabımı kullanarak tüm adımları sıfırdan tekrar çalıştırın.
RolandoMySQLDBA

Drupal siteniz FULLTEXT dizinleri kullanarak arama yapacak şekilde yapılandırılmamışsa, FULLTEXT dizinleri olan tüm tablolara gitmek ve bu dizinleri bu tabloların dışına bırakmak isteyebilirsiniz. FULLTEXT dizinleri olan tüm tabloları bulmak için SELECT table_schema, table FROM information_schema.statistics WHERE index_type = 'FULLTEXT';
RolandoMySQLDBA

Yanıtlar:


7

Bir MySQL DBA olarak, MySQL'in betiği benim için yazmasını sağlayarak MySQL'e güveniyorum.

Bu komutu çalıştırmak için Linux komutunu oluşturun

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',db,'.',tb,' ENGINE=InnoDB;') FROM (SELECT A.db,A.tb,A.tbsize FROM (SELECT table_schema db,table_name tb,(data_length+index_length) tbsize FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) A LEFT JOIN (SELECT table_schema db,table_name tb FROM information_schema.statistics WHERE index_type='FULLTEXT') B USING (db,tb) WHERE B.db IS NULL) AA ORDER BY tbsize" > /root/ConvertMyISAM2InnoDB.sql

Komut dosyası önce en küçük tabloları dönüştürür. Bu komut dosyası, FULLTEXT dizinleri olan tüm MyISAM tablolarını da atladı.

Betiği inceledikten sonra, MySQL'de aşağıdaki gibi çalıştırabilirsiniz:

mysql -h... -u... -p... -A < /root/ConvertMyISAM2InnoDB.sql

veya her dönüşümün zamanlamasını görmek istiyorsanız, mysql'ye giriş yapın ve şunu çalıştırın:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Dönüşüm yürütülürken tam bir masa kilidi oluştuğu için bu durum karışıklığa neden olmamalıdır.

Tüm tablolar dönüştürüldükten sonra, InnoDB kullanımı için MySQL ayarlarını yapmanız ve key_buffer'ı küçültmeniz gerekir.

InnoDB Tampon Havuzunu ayarlamak için lütfen bunu okuyun: /dba/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Lütfen bunu da okuyun: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

Bir şans ver !!!


Roland, çözümünüzü denedim ancak veritabanına ConvertMyISAM2InnoDB.sql dosyasını aldıktan sonra şu hatayı alıyorum: "585 satırında ERROR 1214 (HY000): Kullanılan tablo türü FULLTEXT dizinlerini desteklemiyor". Bu yüzden, dönüşümün bazı tablolarda gerçekleşip gerçekleşmediğini bilmeliyim ve bu hatayı nasıl çözmeliyim? Teşekkürler
alfish

Bunun olacağından korkuyordum. Sadece bir MyISAM tablosunun bir FULLTEXT dizinine sahip olduğu anlamına gelir. MySQL'e giriş yapın ve zamanlamayı görmek istiyormuş gibi çalıştırın. Başka bir deyişle, çalışma kaynağı /root/ConvertMyISAM2InnoDB.sql
RolandoMySQLDBA

FULLTEXT dizinleri olan tabloları atlamak için SQL nesil komut dosyasını güncellemeye çalışacağım.
RolandoMySQLDBA

Bu arada, tüm bu adımları sıfırdan tekrarlayın. Yeniden oluşturulan dosyanın ilk satırında FULLTEXT dizinine sahip MyISAM dosyası bulunur. Bu ilk satırı silin ve komut dosyasını tekrar çalıştırın.
RolandoMySQLDBA

Eh, bu serin dönüşüm bash betiğini ( yoodey.com/… ) çalıştırarak, görünüşe göre veritabanımda Tam Metin kullanan tek tablonun 'search_index' olduğunu anladım. Bu, dönüşümün durmasına neden olur, ancak üzerindeki dönüşümü iptal ettikten sonra, geri kalanı sorunsuz bir şekilde devam etti. ConvertMyISAM2InnoDB.sql kaynağını çalıştırarak suçluyu tam olarak saptayamadım. Neyse yardımın için minnettarım
alfish

4

Bir süre önce bunun için sert bir komut yazdım.

<?php
/**
 * Implements hook_drush_command().
 */
function convert_drush_command() {
  $items = array();

  // the key in the $items array is the name of the command.
  $items['convert-engine'] = array(
    // a short description of your command
    'description' => "Convert MYSQL Table Type",
  );
  return $items;
}

function drush_convert_engine() {
  $args = func_get_args();
  $engine = $args[0];

  $result = db_query("SHOW TABLES");
  while ($row = db_fetch_array($result)) {
    $table = array_shift($row);
    drush_log(dt('Converting @table to @engine', array('@table' => $table, '@engine' => $engine)), 'success');
    db_query("ALTER TABLE $table ENGINE = $engine");
  }
}

Benim için bir yıl önce çalıştı, o zamandan beri drush API'nın değişip değişmediğinden emin değilim.

Bunu bir convert.drush.inc dosyasına örneğin .drush klasörüne yerleştirebilir veya sitenizde bir şekilde yürütebilirsiniz, örneğin devel execute php block ile. Bir drush komut dosyası olarak şöyle diyebilirsiniz:

drush convert-engine InnoDB

Uyarı : Birisi bu komutlar çalışırken veritabanında bir şey yaparsa, veritabanınız tamamen bozulur. Unrecoverably. Bu nedenle, sitenizi bakım moduna geçirin ve bunu denemeden önce yedekleyin! Ve elbette, önce bir geliştirme / test sitesinde deneyin :)


5
Berdir ile aynı fikirde olun, sitenizi yedekleyin. Bu işlem devam ederken veritabanınız KİLİTLENİR. Bunu yapabilen bir modül istiyorsanız, DB Tuner'ı deneyin.
mikeytown2

@ mikeytown2: Bu çok güzel bir modül :)
Berdir

1
Güzel komut dosyası ama bu doğrudan un MySQL istemcisi yapmak yerine oldukça abartılı görünüyor.
tostinni

2
Betik tam olarak 5 satırlık bir koddur. Geri kalanı bunu drush ile entegre etmektir. Bunu MySQL'de tek bir sql komutunda yapmanın bir yolu var. Öyle ya da böyle , bir senaryo yazmalısınız.
Berdir
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.