更改大型MySQL InnoDB表

添加新列或添加新索引可能需要几个小时和几天的MySQL中的大型innodb表超过1000万行。在这两种情况下,增加大型innodb表的性能的最佳方法是什么?更多的内存,调整配置(例如增加sort_buffer_sizeinnodb_buffer_pool_size),还是某种技巧?而不是直接修改表,可以创建一个新的,更改它,并复制旧的数据的新,像这对ISAM tablesmultiple changes是有用的:

CREATE TABLE tablename_tmp LIKE tablename;
ALTER TABLE tablename_tmp ADD fieldname fieldtype;
INSERT INTO tablename_tmp SELECT * FROM tablename;
ALTER TABLE tablename RENAME tablename_old;
ALTER TABLE tablename_tmp RENAME tablename;

也是对innodb表推荐的,还是它只是ALTER TABLE命令执行吗?

编辑2016年:我们最近(2016年8月)发布gh-ost,修改我的答案以反映它。

今天有几个工具,允许你做在线alter table for MySQL。这些是:

> edit 2016:gh-ost:GitHub的无触发模式迁移工具(免责声明:我是这个工具的作者)
> oak-online-alter-table,作为openark-kit的一部分(免责声明:我是这个工具的作者)
> pt-online-schema-change,作为Percona工具包的一部分
> Facebook的online schema change for MySQL

让我们考虑“正常”的“ALTER TABLE”:

一个大表将需要很长时间去ALTER。 innodb_buffer_pool_size是重要的,其他变量也很重要,但是在非常大的表上,它们都是可以忽略的。它只是需要时间。

MySQL对ALTER表进行的操作是创建一个具有新格式的新表,复制所有行,然后切换。在此期间,表完全锁定。

考虑你自己的建议:

它很可能会执行最糟糕的所有选项。这是为什么?因为您使用的是InnoDB表,所以INSERT INTO tablename_tmp SELECT * FROM tablename用于一个事务。一个巨大的交易。它将创建比正常的ALTER TABLE更多的负载。

此外,您必须关闭您的应用程序,以便它不写(INSERT,DELETE,UPDATE)到您的表。如果是这样 – 你的整个交易是毫无意义的。

在线工具提供

这些工具并不都一样。但是,基本知识是共享的:

>他们创建一个改变了模式的“阴影”表
>它们创建和使用触发器将更改从原始表传播到ghost表
>他们慢慢地从表中的所有行复制到影子表。他们这样做的块:一次,1000行。
>他们做所有上述,而你仍然能够访问和操纵原始表。
>当满意时,他们使用RENAME交换这两个。

openark-kit工具已经使用了3.5年了。 Percona工具是几个月大,但可能更多的测试,然后前者。 Facebook的工具据说对Facebook很好,但不提供一般的解决方案给普通用户。我没有自己使用它。

编辑2016:gh-ost是一个无触发解决方案,显着减少主机上的主机写负载,将迁移写入负载与正常负载分离。它是可审计的,可控的,可测试的。我们在GitHub内部开发了它,并将其作为开源发布;我们今天通过gh-ost做所有的生产迁移。查看更多here

每个工具都有自己的限制,仔细查看文档。

保守的方式

保守的方式是使用主动 – 被动主 – 主复制,在备用(被动)服务器上执行ALTER,然后切换角色,并对以前是主动服务器的ALTER再次执行ALTER,现在被动。这也是一个好的选择,但需要一个额外的服务器,以及更深入的复制知识。

翻译自:https://stackoverflow.com/questions/11450089/changing-large-mysql-innodb-tables

转载注明原文:更改大型MySQL InnoDB表