转换表的引擎

有很多种方法可以将表的存储引擎转换成另外一种引擎。每种方法都有其优缺点,下面介绍三种方法。

① ALTER TABLE

将表从一个引擎修改为另一个引擎最简单的方法就是使用ALTER TABLE语句,例:

ALTER TABLE table_name ENGINE = InnoDB;

上述语法可以适用于任何存储引擎。但是有一个问题:当数据过多时,会需要执行很长时间,期间可能会消耗系统所有的I/O能力,同时会在原表上加读锁。MySQL会按行将数据从原表复制到一张新的表中,在数据量大的表上执行此操作需要注意这一点。

另外需要注意的是转换表的引擎之后,将会失去原有引擎相关的所有特性。

② 导入与导出

为了更好的控制转换的过程,可以使用mysqldump工具将数据导出到文件,然后修改文件中CREATE TABLE语句的存储引擎选项,注意同时修改表名,因为在一个数据库中即使它们的存储引擎不同,表名也不能重复。同时要注意mysqldump默认会自动在CREATE TABLE语句前加上DROP TABLE语句,一定要把这行sql删除,否则后果你懂得。

③ 创建于查询

第三种转换的技术综合了第一种方法的高效和第二种方法的安全。不需要导出整个表的数据,而是先创建一个新的表,然后利用insert ... select ... 语法来导数据:

start transaction;
insert into innodb_table select id,name from myisam_table where id between x and y;
commit;

这样操作完成以后,新的表时原表的一个全量赋值,原表还在,如果需要可以删除原表。如果有必要可以在执行过程中对原表加锁以保证数据的一致性。

Percona Toolkit提供了一个pt-online-schema-change的工具(基于Facebook的在线schema变更),可以比较简单的执行这个过程,以避免手工操作导致的失误。

总结

MySQL拥有分层的架构。上层是服务器层的服务和查询执行引擎,下层则是存储引擎。虽然有很多不同作用的插件API,但存储引擎API还是最重要的。如果能理解MySQL在存储引擎和服务层之间处理查询时如何通过API来回交互,就能抓住MySQL的核心基础架构的精髓。

MySQL最初基于ISAM构建后来被MyISAM取代,其后陆续添加了更多的存储引擎和事物支持。MySQL有一些怪异的行为是由于历史遗留导致的。例如,在执行ALTER TABLE时,MySQL提交事物的方式是由存储引擎的架构直接导致的,并且数据字典也保存在.frm文件中,但这并不是说InnoDB此时会变成非事物型的。对于InnoDB来说,所有的操作都是事物。

当然,存储引擎API的架构也有一些缺点。有时候选择多并非好事,而在MySQL5.0和MySQL5.1中有太多的存储引擎可以选择。InnoDB对于95%以上的用户来说都是最佳的选择,所以其他的存储引擎可能只是让事情变得复杂难搞,当然也不可否认某些情况下某些存储引擎能更好的满足需求。