以最小的停机时间改变大Innodb表上的列长度

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

当我尝试运行alter query时,数据库搅动了一个小时,并没有完成任务。 访问系统的用户(需要写入表的用户)被locking。 这是一个现场系统,所以我结束了ctrl-c的请求,让用户访问该网站。

(这是在半夜 – 使用量很小,但我感到紧张)。

我在MySQL 5.0.77。

有关如何以最less的停机时间更改列的任何build议?

你最好的select是使用mysql复制设置一个从数据库。 假设您的模式更改是附加的,那么您可以在该副本上发出更新,该更新在更新期间将被阻止。 一旦完成,并检查你的奴隶赶上了所有的更新,然后宣布一个小的停机时间,以促进你的奴隶数据库的主人。

你可以在这里find设置mysql复制的说明。

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

  • 用所需的定义创build一个新表。
  • 将旧数据复制到新表(确保指定nolock)
  • closures访问旧表
  • 做一个从旧到新的增量更新,只是为了捕获在复制时插入的内容。
  • 将旧表重新命名,并将新表重新命名
  • 恢复访问

当然,这需要很长时间。 你应该明白,改变列数据types,你改变了底层的数据结构,所以数据必须在物理上移动,这可能需要相当长的时间。 我不知道你的硬件的容量,但无论如何,这将花费一个多小时(想想,一夜之间)。

至于减less停机的方法, – 你不能直接做。 我想你没有数据库的备份实例,是吗?

当提到在虚拟机中运行数据库时,我听到很多人畏缩。 事实是,这取决于虚拟机。 如果你不是硬件虚拟化,你不会遭受他们担心的性能损失。 通过Xen使用半虚拟化(我已经听说了关于OpenVZ的好处,但没有使用它),你可以做Dave Cheney所说的(这是正确的方法),只需要使用一个硬件。

游戏中的工具/概念将是:

  1. Xen虚拟化(半虚拟化)
  2. LVM(用于通过快照复制数据)
  3. 虚拟接口(eth0:1,eth0:2等),ifup&ifdown实现…
  4. STONITH

这当然不是一个完整的指南,而是一个技术的完美结合的build议,你可以根据你的需要进行研究和实施。 我的方法更多的是为未来做准备,戴维·切尼(Dave Cheney)正在处理你(可能)今天的事情。