加快将MyISAM转换为InnoDB的速度


15

我有一个带有约450个表的数据库的mysql 5.1服务器,占用4GB。这些表中的绝大多数(除2个以外的所有表)都是MyIsam。这在大多数情况下都很好(不需要事务),但是应用程序一直在增加流量,并且某些表由于更新上的表锁定而受到影响。这就是表中的2个现在是InnoDB的原因。

较小的表(10万行)上的转换根本不需要花费很长时间,从而导致停机时间最少。但是,我的一些跟踪表接近5000万行。有没有一种方法可以加快ALTER TABLE...ENGINE InnoDB大桌子的摆放速度?如果不是,是否有其他方法可以在这些写繁重的表上进行转换以最大程度地减少停机时间?


1
要记住的事情:单个帖子中的多个问题往往会阻止那些可以回答一个问题的人发布答案。
2011年

我VtC,因为这很难回答。您应该单独打开几个问题。
jcolebrand

我很乐意接受建议,将其纳入一个问题,但是建议删除该问题并打开一个新问题?重写主要是删除后两个项目符号并更改第一个项目符号(我也更新了标题,以反映哪些存储引擎)
Derek Downey

都可以。通常,写下另外两个问题并删除一个问题会更容易。但是,您也可以像“这是我的总体目标”这样的问题一样轻松地将其作为“参考”,而另两个参考。
jcolebrand

将此项目编辑成一个项目符号,然后发布后续问题。
Brian Ballsun-Stanton,2011年

Answers:


10

首先,我讨厌ALTER。邪恶,恕我直言。

说,这是您当前的表架构-

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

这是我推荐的路径-

创建一个新的表对象,它将替换旧的对象:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

按名称将旧表中的所有行插入新表中:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

烟雾测试您的迁移:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

交换表名称,以便在需要回滚时可以进行备份。

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

进行回归测试。

对于具有多个索引和数百万行的表,此方法变得越来越可取。

有什么想法吗?


1
同意...尽管交易量很大,但在执行此操作时可能需要关闭数据库。(但更改表很可能会给您带来更长的停机时间)
Joe

是的,我认为对于更活跃的表,这将需要停机。我将不得不运行一些测试,但是为什么ALTER TABLE要花比INSERT INTO...SELECT5000万行更长的时间?
Derek Downey

不会的 基本上,MySQL在内部完全按照此发布者的建议进行操作。它创建该定义的副本,并将le流加载到副本中。
Morgan Tocker 2011年

我喜欢这种方法,因为它会跳过“复制到tmp”部分,这对于大型表可能会花费一些时间。
哈鲁克2012年

现在我要补充一点,在MySQL 5.7中,ALTER更快,更容易应对。
randomx

7

1)丢失保护是偏执狂的一种功能。始终进行备份。如果您真的很偏执,请进行备份,然后从备份中还原。

2)MySQL手册的此页面包含转换表类型的说明。

将表更改为InnoDB的最快方法是直接对InnoDB表进行插入。也就是说,使用ALTER TABLE ... ENGINE = INNODB,或创建具有相同定义的空InnoDB表,并使用INSERT INTO ... SELECT * FROM ...插入行。

3)PostgreSQL进行全文搜索Sphinx Engine似乎针对MySQL


我一定会研究狮身人面像,因为我最近才听说。
德里克·唐尼

3

如果仅使用一个引擎,则优化整个服务器(内存配置,缓存,索引)的难度将提高X倍。在大型数据库上将myisam与innodb混合总是会停留在某些折中的某个点上,以致两个引擎都无法正常工作(但效果不是很好:)

我建议您对一些专用的全文本搜索引擎(例如sphinx,lucene(solr))感兴趣,并从数据库层删除它。

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.