Comment convertir une base de données de MyISAM en InnoDB?

9

Je vais convertir toutes les tables de la base de données de 500 Mo de MyISAM en InnoDB pour voir si cela améliorera les performances globales d'un site Drupal 6 occupé. Je me demande quelle est la meilleure façon (c'est-à-dire la plus sûre / la plus facile / la plus rapide) de faire la conversion.

alfish
la source
Cela ne semble pas être une question liée à Drupal, n'est-ce pas?
tostinni
2
Pas directement, mais c'est quelque chose que les administrateurs Drupal doivent faire à l'occasion.
mpdonadio
J'ai mis à jour ma réponse pour utiliser une nouvelle commande SQL pour filtrer les tables MyISAM qui ont des index FULLTEXT. Veuillez réexécuter toutes les étapes à partir de zéro en utilisant ma réponse mise à jour.
RolandoMySQLDBA
Si votre site Drupal n'est pas configuré pour effectuer une recherche à l'aide des index FULLTEXT, vous souhaiterez peut-être accéder à toutes les tables avec des index FULLTEXT et supprimer ces index de ces tables. Pour trouver toutes les tables ayant des index FULLTEXT, exécutez SELECT table_schema, table FROM information_schema.statistics WHERE index_type = 'FULLTEXT';
RolandoMySQLDBA

Réponses:

7

En tant que DBA MySQL, je fais confiance à MySQL pour effectuer la conversion en demandant à MySQL d'écrire le script pour moi.

Formez la commande Linux exécutez cette requête

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

Le script convertira d'abord les plus petites tables. Ce script a également ignoré toutes les tables MyISAM qui ont des index FULLTEXT.

Après avoir regardé le script, vous pouvez simplement l'exécuter dans MySQL comme suit:

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

ou si vous voulez voir le calendrier de chaque conversion, connectez-vous à mysql et exécutez ceci:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Cela ne devrait pas être gâché car un verrouillage complet de la table se produit lors de l'exécution de la conversion.

Une fois que toutes les tables sont converties, vous devez ajuster les paramètres MySQL pour l'utilisation d'InnoDB et réduire le key_buffer.

Veuillez lire ceci pour définir le pool de tampons InnoDB: /dba/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Veuillez également lire ceci: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

Essaie !!!

RolandoMySQLDBA
la source
Roland, j'ai essayé votre solution mais après avoir importé ConvertMyISAM2InnoDB.sql dans la base de données, j'obtiens cette erreur: "ERREUR 1214 (HY000) à la ligne 585: le type de table utilisé ne prend pas en charge les index FULLTEXT". Dois-je donc savoir si la conversion a eu lieu sur certaines tables et comment dois-je résoudre cette erreur? Merci
Alfish
J'avais peur que cela se produise. Cela signifie simplement qu'une table MyISAM avait un index FULLTEXT. Connectez-vous à mysql et exécutez comme si vous vouliez voir le timing. En d'autres termes, exécutez la source /root/ConvertMyISAM2InnoDB.sql
RolandoMySQLDBA
Je vais essayer de mettre à jour le script de génération SQL pour ignorer les tables qui ont des index FULLTEXT.
RolandoMySQLDBA
En attendant, répétez toutes ces étapes à partir de zéro. La première ligne du fichier régénéré contient le fichier MyISAM avec l'index FULLTEXT. Supprimez simplement cette première ligne et relancez le script.
RolandoMySQLDBA
Eh bien, en exécutant ce script bash de conversion sympa ( yoodey.com/… ), j'ai compris que, apparemment, la seule table de ma base de données qui utilise le texte intégral est 'search_index'. Cela provoque un arrêt de la conversion, mais après avoir annulé la conversion, le reste s'est déroulé sans problème. En exécutant la source ConvertMyISAM2InnoDB.sql, je n'ai pas pu identifier le coupable. Quoi qu'il en soit, j'apprécie votre aide.
alfish
4

J'ai écrit une commande drush pour cela il y a un moment.

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

A travaillé pour moi il y a un an environ, je ne sais pas si l'API drush a changé depuis.

Vous pouvez placer cela dans un convert.drush.inc par exemple dans le dossier .drush ou l'exécuter d'une manière ou d'une autre sur votre site, par exemple avec le bloc devel execute php. En tant que script drush, vous pouvez l'appeler comme ceci:

drush convert-engine InnoDB

Avertissement : si quelqu'un fait quelque chose avec la base de données pendant l'exécution de ces commandes, votre base de données sera complètement gâchée. Irrécupérable. Alors, mettez votre site en mode maintenance et faites une sauvegarde avant d'essayer! Et bien sûr, essayez d'abord un site de développement / test :)

Berdir
la source
5
D'accord avec Berdir, sauvegardez votre site. Pendant cette opération, votre base de données sera VERROUILLÉE. Si vous voulez un module qui peut le faire, essayez DB Tuner .
mikeytown2
@ mikeytown2: C'est un module assez cool :)
Berdir
1
Beau script mais il semble assez exagéré par rapport à faire cela directement sur un client MySQL.
tostinni
2
Le script est exactement 5 lignes de code. Le reste est de l'intégrer avec drush. Il y a moyen de le faire dans une seule commande sql dans MySQL. D'une manière ou d'une autre, vous devez écrire un script.
Berdir