更改大型MySQL InnoDB表

时间:2012-07-12 10:40:39

标签: mysql performance optimization

为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命令的用途呢?

2 个答案:

答案 0 :(得分:64)

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

今天有几个工具允许你在线进行在线alter table。这些是:

让我们考虑一下" normal" `ALTER TABLE`:

大型表格需要很长时间才能ALTERinnodb_buffer_pool_size很重要,其他变量也很重要,但在非常大的表上它们都可以忽略不计。这需要时间。

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

考虑一下你自己的建议:

它很可能会执行最糟糕的选择。这是为什么?因为您正在使用InnoDB表,所以INSERT INTO tablename_tmp SELECT * FROM tablename会进行交易。一个巨大的交易。它会产生比普通ALTER TABLE更多的负载。

此外,您必须在此时关闭您的应用,以便它不会将(INSERTDELETEUPDATE)写入您的表格。如果确实如此 - 您的整个交易毫无意义。

在线工具提供的内容

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

  • 他们创造了一个"阴影"具有更改架构的表
  • 他们创建并使用触发器将更改从原始表传播到ghost表
  • 他们慢慢将表中的所有行复制到影子表。他们是这样做的:比如说,每次1000行。
  • 当您仍然可以访问和操作原始表时,他们会执行以上所有操作。
  • 如果满意,他们会使用RENAME交换两者。

openark-kit 工具已经使用了3。5年。 Percona工具已有几个月的历史,但可能比前者更耐用。据说Facebook的工具适用于Facebook,但没有为普通用户提供通用解决方案。我自己还没有用过它。

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

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

保守的方式

保守的方法是使用主动 - 被动Master-Master复制,在备用(被动)服务器上执行ALTER,然后切换角色并再次执行ALTER以前的操作活动服务器,现在变为被动。这也是一个不错的选择,但需要额外的服务器,以及更深入的复制知识。

答案 1 :(得分:0)

重命名螺旋参考表。

如果您在table_2上说tablenameALTER TABLE tablename RENAME tablename_old;的孩子,请table_2 tablename_old将开始指向tablename

现在没有改变table_2,你就无法将它指回 'Creating the root node ' Main Node - All Treeview MUST have at least ONE. Dim root = New TreeNode("Application") ' Add a node under it. TreeView1.Nodes.Add(root) TreeView1.Nodes(0).Nodes.Add(New TreeNode("First Child from Root")) 'Creating child nodes under the first child For loopindex As Integer = 1 To 4 TreeView1.Nodes(0).Nodes(0).Nodes.Add(New TreeNode("Childs" & Str(loopindex))) Next loopindex ' creating child nodes under the root (0) TreeView1.Nodes(0).Nodes.Add(New TreeNode("Second Child from Root")) 'creating child nodes under the created child node For loopindex As Integer = 1 To 3 TreeView1.Nodes(0).Nodes(1).Nodes.Add(New TreeNode("Childs from Node 1 - " & Str(loopindex))) Next loopindex 。你必须继续改变每个孩子和参考表。