MySQL:如何在生产数据库中将许多 MyISAM 表转换为 InnoDB?

MySQL:如何在生产数据库中将许多 MyISAM 表转换为 InnoDB?

我们有一个完全由 MyISAM 表组成的生产数据库。我们正在考虑将它们转换为 InnoDB,以获得更好的并发性和可靠性。

  1. 我可以不关闭 MySQL 而直接将 myISAM 表更改为 InnoDB 吗?这里推荐的程序是什么?

  2. 这样的转换需要多长时间?所有表的总大小约为 700MB

  3. 表的数量相当多。有没有办法ALTER TABLE一次性应用到所有 MyISAM 表,而不是逐个应用?

  4. 我需要注意哪些陷阱?

谢谢

答案1

您可以做到。从 MyISAM 转换为 InnoDB 应该不是问题,因为 InnoDB 具有 MyISAM 所不具备的更多功能,例如事务。

您可以在数据库运行时更改表。无需关闭,但此操作将锁定表。

所需时间取决于服务器规格/负载/数据库大小等。

您可以使用脚本来自动化该过程。使用命令show tables,您可以获取表列表。然后,使用简单的脚本,您可以读取此列表并执行 alter table 命令。

这是一个简单的 perl 脚本,它将从文件中读取表列表并在另一个文件中写入 SQL 查询。调用此脚本后,您可以将输出文件提供给mysql命令以进行所需的更改。

open(INFILE, "< tables_list.txt");
open(OUTFILE, "> alter_tables.sql");
foreach my $name (<INFILE>) {
   chomp($name);
   print OUTFILE "ALTER TABLE $name engine=InnoDB;\n";
}
close(INFILE);
close(OUTFILE);

答案2

我使用 CREATE 和 SELECT:

 mysql> CREATE TABLE i_table LIKE table;
 mysql> ALTER TABLE i_table ENGINE=InnoDB;
 mysql> INSERT INTO i_table SELECT * FROM table;
 mysql> RENAME TABLE table TO b_table;
 mysql> RENAME TABLE i_ TO other_db.tbl_name;

如果你没有太多数据,这种方法很有效。最好使用

mysql> ALTER TABLE table ENGINE = InnoDB;

在繁忙的数据库上尝试此方法之前请务必小心。

您还可以转储数据库,更改转储文件中的 ENGINE 和转储文件中的 DATABASE 名称。恢复数据库,然后重命名数据库。

答案3

我有一个使用 MySQL 自动将 MyISAM 转换为 InnoDB 的方法

以下是为每个数据库中的 MyISAM 表生成 SQL 的查询:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL
FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length);

在 Linux 提示符下,像这样运行脚本创建:

mysql -h... -u... -p.... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length)" > MyISAM_To_InnoDB.sql

这将生成 SQL 来将所有数据库中的每个 MyISAM 表从最小表转换为最大表。

您可以轻松调整 SQL 以将所有 MyISAM 表转换为特定数据库内的 InnoDB,如下所示(例如数据库 mystuff):

mysql -h... -u... -p.... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema = 'mystuff' ORDER BY (data_length+index_length)" > MyISAM_To_InnoDB.sql

答案4

Khaled 和 ooshro 已经为您讲解了语义;问题 2 和问题 4 更难判断,因为这取决于您的配置和硬件。对于问题 2,您可以做的是将数据库转储到文件中,并将其导入工作站或其他服务器(如果有必要,可以花 5 美元购买一个云切片并使用它),然后尝试在其上执行您的更改选项,以查看总体上需要多长时间。这实际上并不是一个完美的测试,但总比没有好 - 700MB 不是很大,如果您的 MySQL 位于功能强大的专用服务器上(例如,带 16gig RAM 的戴尔 2970),则不会花费很长时间。

对于 #4 - 不要将 mysql/ 数据库转换为 InnoDB。:) 总体而言,该过程在运行时会导致全表锁定(实际上,在后台它只是创建新表、传输数据,然后删除/重命名它),因此您需要在晚上下班时间更改引擎。确保获得完整转储,以防出现问题。(mysqldump -A --flush-privileges > dbdump.sql)。

相关内容