Come posso convertire un database da MyISAM a InnoDB?


9

Ho intenzione di convertire tutte le tabelle del database da 500 MB da MyISAM a InnoDB per vedere se migliorerà le prestazioni complessive di un sito Drupal 6 occupato. Mi chiedo quale sia il modo migliore (ovvero più sicuro / più semplice / più veloce) per fare la conversione.


Questa non sembra essere una domanda relativa a Drupal, vero?
tostinni,

2
Non direttamente, ma è qualcosa che gli amministratori di Drupal devono fare occasionalmente.
mpdonadio

Ho aggiornato la mia risposta per utilizzare un nuovo comando SQL per filtrare le tabelle MyISAM che hanno indici FULLTEXT. Rieseguire tutti i passaggi da zero utilizzando la mia risposta aggiornata.
RolandoMySQLDBA,

Se il tuo sito Drupal non è configurato per la ricerca utilizzando gli indici FULLTEXT, potresti voler andare a tutte le tabelle con indici FULLTEXT e eliminare quegli indici da quelle tabelle. Per trovare tutte le tabelle con indici FULLTEXT, eseguire SELECT table_schema, tabella FROM information_schema.statistics DOVE index_type = 'FULLTEXT';
RolandoMySQLDBA,

Risposte:


7

In qualità di DBA MySQL, mi fido di fare la conversione facendo in modo che MySQL scriva lo script per me.

Formare il comando Linux eseguire questa query

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

Lo script convertirà prima le tabelle più piccole. Questo script ha inoltre ignorato qualsiasi tabella MyISAM che ha indici FULLTEXT.

Dopo aver esaminato lo script, puoi semplicemente eseguirlo in MySQL come segue:

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

o se vuoi vedere i tempi di ogni conversione, accedi a mysql ed esegui questo:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Questo non dovrebbe essere incasinato perché si verifica un blocco completo della tabella durante l'esecuzione della conversione.

Una volta convertite tutte le tabelle, è necessario ottimizzare le impostazioni di MySQL per l'utilizzo di InnoDB e ridimensionare il key_buffer.

Si prega di leggere questo per impostare il pool di buffer InnoDB: /dba/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Si prega di leggere anche questo: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

Provaci !!!


Roland, ho provato la tua soluzione ma dopo aver importato ConvertMyISAM2InnoDB.sql nel database, ho visualizzato questo errore: "ERRORE 1214 (HY000) alla riga 585: il tipo di tabella utilizzata non supporta gli indici FULLTEXT". Quindi dovrei sapere se la conversione è avvenuta su alcune tabelle e come devo risolvere questo errore? Grazie
alfish il

Avevo paura che potesse succedere. Significa semplicemente che una tabella MyISAM aveva un indice FULLTEXT. Accedi a mysql ed esegui se come se volessi vedere i tempi. In altre parole, esegui source /root/ConvertMyISAM2InnoDB.sql
RolandoMySQLDBA

Proverò ad aggiornare lo script di generazione SQL per saltare le tabelle che hanno indici FULLTEXT.
RolandoMySQLDBA,

Nel frattempo, ripeti tutti questi passaggi da zero. La prima riga del file rigenerato contiene il file MyISAM con l'indice FULLTEXT. Elimina semplicemente quella prima riga ed esegui nuovamente lo script.
RolandoMySQLDBA,

Bene, eseguendo questo fantastico script bash di conversione ( yoodey.com/… ), ho capito che apparentemente l'unica tabella sul mio database che utilizza Full Text è 'search_index'. Ciò causa l'interruzione della conversione, ma dopo aver annullato la conversione, il resto è andato liscio. Eseguendo il convertitore ConvertMyISAM2InnoDB.sql non sono riuscito a individuare il colpevole. Comunque apprezzo il tuo aiuto.
alfish

4

Ho scritto un comando drush per questo qualche tempo fa.

<?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");
  }
}

Ha funzionato per me circa un anno fa, non sono sicuro se l'API Drush sia cambiata da allora.

Puoi inserirlo in un file convert.drush.inc, ad esempio nella cartella .drush o eseguirlo in qualche modo sul tuo sito, ad esempio con il blocco php deve execute. Come drush script, puoi chiamarlo così:

drush convert-engine InnoDB

Avviso : se qualcuno fa qualcosa con il database mentre questi comandi sono in esecuzione, il tuo database sarà completamente incasinato. Unrecoverably. Quindi, imposta il tuo sito in modalità manutenzione ed esegui un backup prima di provare questo! E, naturalmente, prova prima su un sito di sviluppo / test :)


5
Accetto con Berdir, esegui il backup del tuo sito. Durante questa operazione, il database sarà BLOCCATO. Se vuoi un modulo in grado di farlo, dai un'occhiata a DB Tuner .
mikeytown2,

@ mikeytown2: è un modulo davvero interessante :)
Berdir,

1
Script piacevole ma sembra abbastanza eccessivo rispetto a farlo direttamente su un client MySQL.
tostinni,

2
Lo script è esattamente 5 righe di codice. Il resto è integrarlo con la droga. C'è modo di farlo in un singolo comando sql in MySQL. In un modo o nell'altro, si devono scrivere uno script.
Berdir,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.