如何将数据库从MyISAM转换为InnoDB?


9

我将把500MB数据库的所有表从MyISAM转换为InnoDB,以查看它是否将改善繁忙的Drupal 6站点的整体性能。我想知道什么是最好的(即最安全/最容易/最快)的转换方式。


这似乎不是与Drupal有关的问题吗?
tostinni 2011年

2
不是直接的,但这是Drupal管理员有时需要做的事情。
mpdonadio

我更新了答案,以使用新的SQL命令来筛选出具有FULLTEXT索引的MyISAM表。请使用我更新的答案从头开始重新执行所有步骤。
RolandoMySQLDBA 2011年

如果未将Drupal站点配置为使用FULLTEXT索引进行搜索,则可能要转到具有FULLTEXT索引的所有表,然后将这些索引从这些表中删除。要查找所有具有FULLTEXT索引的表,请运行SELECT table_schema,table FROM information_schema.statistics WHERE index_type ='FULLTEXT';
RolandoMySQLDBA 2011年

Answers:


7

作为MySQL DBA,我相信MySQL通过让MySQL为我编写脚本来进行转换。

形式Linux命令运行此查询

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

该脚本将首先转换最小的表。该脚本还绕过了具有FULLTEXT索引的任何MyISAM表。

查看脚本后,您可以按照以下步骤在MySQL中运行它:

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

或者,如果您想查看每次转换的时间,请登录mysql并运行以下命令:

mysql> source /root/ConvertMyISAM2InnoDB.sql

这应该不会弄乱,因为执行转换时会发生全表锁定。

转换完所有表后,您需要针对InnoDB使用情况调整MySQL设置,并缩小key_buffer。

请阅读以下内容以设置InnoDB缓冲池:https : //dba.stackexchange.com/questions/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

请仔细阅读本:/drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

试试看 !!!


Roland,我尝试了您的解决方案,但是将ConvertMyISAM2InnoDB.sql导入数据库后,出现以下错误:“错误1214(HY000)在第585行:使用的表类型不支持FULLTEXT索引”。因此,我应该知道转换是否发生在某些表上,如何解决该错误?谢谢
alfish

我担心那会发生。它仅表示一个MyISAM表具有FULLTEXT索引。登录到mysql并运行,就好像您要查看时间一样。换句话说,运行源代码/root/ConvertMyISAM2InnoDB.sql
RolandoMySQLDBA 2011年

我将尝试更新SQL生成脚本以跳过具有FULLTEXT索引的表。
RolandoMySQLDBA 2011年

同时,从头开始重复所有这些步骤。重新生成的文件的第一行包含带有FULLTEXT索引的MyISAM文件。只需删除第一行并重新运行脚本即可。
RolandoMySQLDBA 2011年

好吧,通过运行这个很酷的转换bash脚本(yoodey.com/…),我发现显然数据库中使用全文的唯一表是'search_index'。这导致转换停止,但是在取消转换后,其余转换继续进行。通过运行源ConvertMyISAM2InnoDB.sql,我无法查明罪魁祸首。无论如何,我感谢您的帮助。
alfish

4

前一段时间,我为此写了一个drush命令。

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

一年前左右为我工作,不确定此后drush API是否已更改。

您可以将其放置在convert.drush.inc中,例如.drush文件夹中,或以某种方式在您的网站上执行,例如使用devel execute php块。作为草稿脚本,您可以这样调用它:

drush convert-engine InnoDB

警告:如果在执行这些命令时有人对数据库执行某些操作,则数据库将完全混乱。无法恢复。因此,在尝试此操作之前,请将您的网站置于维护模式并进行备份!当然,请先在开发/测试网站上尝试:)


5
同意Berdir,备份您的网站。进行此操作时,数据库将被锁定。如果您想要一个可以做到的模块,请尝试一下DB Tuner
mikeytown2 2011年

@ mikeytown2:这是一个非常酷的模块:)
Berdir 2011年

1
不错的脚本,但与直接在MySQL客户端上执行此操作相比似乎有些过头了。
tostinni 2011年

2
该脚本正好是5行代码。剩下的就是将它与匆忙整合在一起。有一种方法可以在MySQL中的单个sql命令中执行此操作。一种或另一种方式,您必须编写脚本。
Berdir 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.