Como faço para converter um banco de dados do MyISAM para o InnoDB?


9

Vou converter todas as tabelas do banco de dados de 500 MB do MyISAM para o InnoDB para ver se ele melhorará o desempenho geral de um site do Drupal 6 ocupado. Gostaria de saber qual é a melhor maneira (ou seja, mais segura / mais fácil / mais rápida) de fazer a conversão.


Isso não parece ser uma pergunta relacionada ao Drupal, não é?
— tostinni

2
Não diretamente, mas é algo que os administradores do Drupal precisam fazer ocasionalmente.
— mpdonadio

Atualizei minha resposta para usar um novo comando SQL para filtrar as tabelas MyISAM que possuem índices FULLTEXT. Execute novamente todas as etapas do zero usando minha resposta atualizada.
— RolandoMySQLDBA

Se o seu site Drupal não estiver configurado para pesquisar usando índices FULLTEXT, convém ir a todas as tabelas com índices FULLTEXT e eliminá-los dessas tabelas. Para localizar todas as tabelas com índices FULLTEXT, execute SELECT table_schema, tabela FROM information_schema.statistics WHERE index_type = 'FULLTEXT';
— RolandoMySQLDBA

Respostas:


7

Como DBA do MySQL, confio no MySQL para fazer a conversão, fazendo com que o MySQL escreva o script para mim.

Forme o comando Linux, execute 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

O script converterá as tabelas menores primeiro. Esse script também ignorou as tabelas MyISAM que possuem índices FULLTEXT.

Depois de examinar o script, você pode simplesmente executá-lo no MySQL da seguinte maneira:

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

ou se você quiser ver o tempo de cada conversão, entre no mysql e execute:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Isso não deve ser confuso, porque um bloqueio de tabela completo acontece quando a conversão está sendo executada.

Depois que todas as tabelas forem convertidas, você precisará ajustar as configurações do MySQL para uso do InnoDB e reduzir o key_buffer.

Leia isso para configurar o InnoDB Buffer Pool: /dba/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Leia também: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

De uma chance !!!


Roland, tentei sua solução, mas depois de importar o ConvertMyISAM2InnoDB.sql para o banco de dados, recebo este erro: "ERRO 1214 (HY000) na linha 585: O tipo de tabela usado não suporta índices FULLTEXT". Então, devo saber se a conversão ocorreu em algumas tabelas e como devo resolver esse erro? Graças
— alfish

Eu tinha medo que isso acontecesse. Significa simplesmente que uma tabela MyISAM tinha um índice FULLTEXT. Faça o login no mysql e execute se quiser ver o tempo. Em outras palavras, execute source /root/ConvertMyISAM2InnoDB.sql
— RolandoMySQLDBA

Vou tentar atualizar o script de geração SQL para ignorar as tabelas que possuem índices FULLTEXT.
— RolandoMySQLDBA

Enquanto isso, repita todas essas etapas do zero. A primeira linha do arquivo regenerado possui o arquivo MyISAM com o índice FULLTEXT. Simplesmente exclua a primeira linha e execute novamente o script.
— RolandoMySQLDBA

Bem, executando esse script bacana de conversão ( yoodey.com/… ), descobri que aparentemente a única tabela no meu banco de dados que usa Texto Completo é 'search_index'. Isso causou a interrupção da conversão, mas depois de cancelar a conversão, o restante continuou sem problemas. Ao executar o ConvertMyISAM2InnoDB.sql de origem, não consegui identificar o culpado. De qualquer forma, agradeço a sua ajuda.
— alfish

4

Eu escrevi um comando drush para isso há um tempo atrás.

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

Trabalhou para mim há um ano, mais ou menos, não tenho certeza se a API drush mudou desde então.

Você pode colocar isso em um convert.drush.inc, por exemplo, na pasta .drush ou executá-lo de alguma forma no seu site, por exemplo, com o bloco devel execute php. Como um script drush, você pode chamar assim:

drush convert-engine InnoDB

Aviso : Se alguém fizer algo com o banco de dados enquanto esses comandos são executados, seu banco de dados será completamente destruído. Irrecuperavelmente. Portanto, coloque seu site no modo de manutenção e faça um backup antes de tentar isso! E, é claro, tente primeiro um site de desenvolvimento / teste :)


5
Concorde com o Berdir, faça backup do seu site. Enquanto esta operação estiver em andamento, seu banco de dados será BLOQUEADO. Se você deseja um módulo que possa fazer isso, experimente o DB Tuner .
— mikeytown2

@ mikeytown2: Isso é um módulo legal pretty :)
— Berdir

1
Bom script, mas parece um exagero em relação a fazer isso diretamente no cliente MySQL.
— tostinni

2
O script é exatamente 5 linhas de código. O resto é integrá-lo ao drush. Existe uma maneira de fazer isso em um único comando sql no MySQL. De uma forma ou de outra, você precisa escrever um script.
— Berdir
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.