web-dev-qa-db-fra.com

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

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 occupé Drupal 6. Je me demande quel est le meilleur (c'est-à-dire le plus sûr/le plus simple/le plus rapide) pour effectuer la conversion.

9
alfish

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 été contourné 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 lorsque la conversion est en cours d'exécution.

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: https://dba.stackexchange.com/questions/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

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

Essaie !!!

7
RolandoMySQLDBA

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 le placer dans un fichier 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 :)

4
Berdir
#!/bin/sh
DBNAME="your-database"
DBUSER="your-username"
DBPWD="your-password"
for t in $(mysql -u$DBUSER -p$DBPWD --batch --column-names=false -e "show tables" $DBNAME);
do
echo "Converting table $t"
mysql -u$DBUSER -p$DBPWD -e "alter table $t engine=InnoDB" $DBNAME;
done

source

2
alfish