¿Cómo convierto una base de datos de MyISAM a InnoDB?


9

Voy a convertir todas las tablas de la base de datos de 500 MB de MyISAM a InnoDB para ver si mejorará el rendimiento general de un sitio ocupado de Drupal 6. Me pregunto cuál es la mejor manera (es decir, la más segura / más fácil / más rápida) de realizar la conversión.


Esto no parece ser una pregunta relacionada con Drupal, ¿verdad?
tostinni

2
No directamente, pero es algo que los administradores de Drupal deben hacer ocasionalmente.
mpdonadio

Actualicé mi respuesta para usar un nuevo comando SQL para filtrar las tablas MyISAM que tienen índices FULLTEXT. Vuelva a ejecutar todos los pasos desde cero utilizando mi respuesta actualizada.
RolandoMySQLDBA

Si su sitio de Drupal no está configurado para buscar utilizando índices FULLTEXT, puede ir a todas las tablas con índices FULLTEXT y eliminar esos índices de esas tablas. Para buscar todas las tablas que tengan índices FULLTEXT, ejecute SELECT table_schema, table FROM information_schema.statistics WHERE index_type = 'FULLTEXT';
RolandoMySQLDBA

Respuestas:


7

Como MySQL DBA, confío en MySQL para hacer la conversión haciendo que MySQL escriba el script por mí.

Forma el comando Linux ejecuta esta consulta

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

El script convertirá primero las tablas más pequeñas. Este script también omitió las tablas MyISAM que tienen índices FULLTEXT.

Después de revisar el script, simplemente puede ejecutarlo en MySQL de la siguiente manera:

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

o si desea ver el momento de cada conversión, inicie sesión en mysql y ejecute esto:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Esto no debería estropearse porque se produce un bloqueo completo de la tabla cuando se ejecuta la conversión.

Una vez que se convierten todas las tablas, debe ajustar la configuración de MySQL para el uso de InnoDB y reducir el key_buffer.

Lea esto para configurar el InnoDB Buffer Pool: /dba/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Lea esto también: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

Darle una oportunidad !!!


Roland, probé su solución, pero después de importar ConvertMyISAM2InnoDB.sql a la base de datos, aparece este error: "ERROR 1214 (HY000) en la línea 585: el tipo de tabla utilizado no admite índices FULLTEXT". Entonces, ¿debería saber si la conversión se realizó en algunas tablas y cómo debo resolver este error? Gracias
alfish

Tenía miedo de que eso suceda. Simplemente significa que una tabla MyISAM tenía un índice FULLTEXT. Inicie sesión en mysql y ejecútelo como si quisiera ver el tiempo. En otras palabras, ejecute source /root/ConvertMyISAM2InnoDB.sql
RolandoMySQLDBA el

Intentaré actualizar el script de generación de SQL para omitir tablas que tengan índices FULLTEXT.
RolandoMySQLDBA

Mientras tanto, repita todos estos pasos desde cero. La primera línea del archivo regenerado tiene el archivo MyISAM con el índice FULLTEXT. Simplemente elimine esa primera línea y vuelva a ejecutar el script.
RolandoMySQLDBA

Bueno, al ejecutar este genial script de conversión de bash ( yoodey.com/… ), descubrí que aparentemente la única tabla en mi base de datos que usa Texto Completo es 'search_index'. Esto hizo que la conversión se detuviera, pero después de cancelar la conversión, el resto continuó sin problemas. Al ejecutar la fuente ConvertMyISAM2InnoDB.sql no pude identificar al culpable. De todos modos aprecio tu ayuda.
alfish

4

He escrito un comando drush para esto hace un tiempo.

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

Trabajó para mí hace aproximadamente un año, no estoy seguro de si la API drush cambió desde entonces.

Puede colocarlo en un convert.drush.inc, por ejemplo, en la carpeta .drush o ejecutarlo de alguna manera en su sitio, por ejemplo, con el bloque de ejecución de desarrollo php. Como script drush, puedes llamarlo así:

drush convert-engine InnoDB

Advertencia : si alguien hace algo con la base de datos mientras se ejecutan estos comandos, su base de datos estará completamente desordenada. Irrecuperablemente. Por lo tanto, ponga su sitio en modo de mantenimiento y haga una copia de seguridad antes de intentar esto. Y, por supuesto, primero prueba en un sitio de desarrollo / prueba :)


55
De acuerdo con Berdir, haga una copia de seguridad de su sitio. Mientras esta operación continúa, su base de datos estará BLOQUEADA. Si desea un módulo que pueda hacerlo, pruebe DB Tuner .
mikeytown2

@ mikeytown2: Ese es un módulo genial :)
Berdir

1
Buen script, pero parece bastante exagerado en comparación con hacer esto directamente en un cliente MySQL.
tostinni

2
El script tiene exactamente 5 líneas de código. El resto es integrarlo con drush. Hay forma de hacer esto en un solo comando sql en MySQL. De una forma u otra, se tienen que escribir un script.
Berdir
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.