草庐IT

mysql - 更改大型 MySQL InnoDB 表

coder 2023-06-10 原文

对于 MySQL 中超过 1000 万行的大型 innodb 表,添加新列或添加新索引可能需要数小时和数天。在这两种情况下,提高大型 innodb 表性能的最佳方法是什么?更多内存,调整配置(例如增加 sort_buffer_sizeinnodb_buffer_pool_size ),还是某种技巧?无需直接更改表,而是可以创建一个新表,对其进行更改,然后将旧数据复制到新表中,就像这样对 ISAM tables 很有用和 multiple 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,修改了我的答案以反射(reflect)它。

今天有几个工具可以让你为 MySQL 做在线修改表。它们是:

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

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

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

考虑您自己的建议:

它很可能会在所有选项中表现最差。这是为什么?因为您使用的是 InnoDB 表,所以 INSERT INTO tablename_tmp SELECT * FROM tablename 会产生事务。 巨大的交易。它会比普通的 ALTER TABLE 产生更多的负载。

此外,您必须在那时关闭您的应用程序,以便它不会写入(INSERTDELETEUPDATE)到你的 table 。如果是这样 - 你的整个交易都是毫无意义的。

在线工具提供什么

这些工具的工作方式不尽相同。但是,基础是共享的:

  • 他们创建了一个改变架构的“影子”表
  • 他们创建并使用触发器将更改从原始表传播到幽灵表
  • 他们慢慢地将所有行从您的表复制到影子表。他们分 block 进行:比如说,一次 1,000 行。
  • 当您仍然能够访问和操作原始表格时,它们会执行上述所有操作。
  • 如果满意,他们会使用 RENAME 交换两者。

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

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

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

保守的方式

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

关于mysql - 更改大型 MySQL InnoDB 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11450089/

有关mysql - 更改大型 MySQL InnoDB 表的更多相关文章

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  4. ruby - 更改 ActiveRecord 中对象的类 - 2

    假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。

  5. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  8. ruby - 是否可以将 IRB 提示配置为动态更改? - 2

    我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO

  9. ruby - Watir 更改 Mozilla Firefox 首选项 - 2

    我正在使用Watir运行一个Ruby脚本来为我自动化一些事情。我试图自动将一些文件保存到某个目录。因此,在我的Mozilla设置中,我将默认下载目录设置为桌面并选择自动保存文件。但是,当我开始运行我的脚本时,这些更改并没有反射(reflect)出来。似乎首选项恢复为默认值。我已经包括以下内容require"rubygems"#Optional.require"watir-webdriver"#Forwebautomation.require"win32ole"#Forfilesavedialog.并打开一个新的firefox实例:browser=Watir::Browser.new(:

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐