以最少的停机时间更改大型 Innodb 表上的列长度

以最少的停机时间更改大型 Innodb 表上的列长度

我需要更改 MySQL innodb 表中 164M 行的列的长度。这是我要运行的脚本:ALTER TABLE SESSION_DECISION CHANGE COLUMN NAME NAME VARCHAR(255);

当我尝试运行 alter 查询时,数据库混乱了一个小时,没有完成任务。访问系统的用户(需要写入表的用户)被锁定。这是一个实时系统,所以我最终按下 Ctrl-C 键来让用户访问网站。

(这是在半夜——使用次数很少,但我开始紧张)。

我使用的是 MySQL 5.0.77。

关于如何以最少的停机时间更换列,有什么建议吗?

答案1

最好的选择是使用 mysql 复制设置从属数据库。假设您的架构更改是附加的,那么您可以在该副本上发出更新,该副本将在更新期间被阻止。完成后,检查您的从属数据库是否已赶上所有更新,然后声明短暂的停机时间以将您的从属数据库提升为主数据库。

您可以找到有关设置的说明mysql 复制在这里。

答案2

如果您的数据是严格插入(而不是更新)的,您可能会执行以下操作:

  • 创建一个具有所需定义的新表。
  • 将旧数据复制到新表(确保指定 nolock)
  • 关闭对旧表的访问
  • 进行从旧到新的增量更新,只是为了捕获复制过程中插入的任何内容。
  • 重命名旧表并将新表放到位
  • 恢复访问

答案3

当然,这需要很长时间。您应该明白,更改列数据类型会更改底层数据结构,因此必须物理地移动数据,这可能需要很长时间。我不知道您的硬件容量如何,但无论如何,这都将花费一个多小时(想想,一整夜)。

至于减少停机时间的方法,您无法直接做到这一点。我想您没有数据库的备份实例,对吧?

答案4

我听说很多人在提到在虚拟机中运行数据库时会感到畏缩。事实是,这取决于虚拟机。如果您没有虚拟化硬件,那么您就不会遭受他们担心的性能损失。通过 Xen 使用半虚拟化(我听说过 OpenVZ 的好处,但没有用过。)您可以完全按照 Dave Cheney 所说的去做(这是正确的方法),并且只需使用一个硬件。

所使用的工具/概念包括:

  1. Xen 虚拟化(用于半虚拟化)
  2. LVM(用于通过快照复制数据)
  3. 虚拟接口(eth0:1、eth0:2 等),ifup 和 ifdown 来实现...
  4. 斯托尼特

当然,这不是一份完整的指南,而是一个关于合理技术组合的建议,您可以根据自己的需要进行研究和实施。我的方法更多的是为未来做好准备,而 Dave Cheney 的方法则是处理您(可能)今天所拥有的东西。

相关内容