InnoDB上的MySql数字类型迁移

InnoDB上的MySql数字类型迁移,mysql,database,Mysql,Database,我们使用InnoDB引擎在MySql中存储了一个非常大的(1000多万)行表。列“x”定义为“smallint(5)unsigned not null” 自几年前的原始设计以来,需求现在已经发生了变化,“x”列需要存储最小数据类型大小为“int unsigned not null” 我们允许“短暂”的停机时间来部署应用程序(少于5分钟),因此,如果数据库表需要以任何方式暂时不可用(例如,完全表锁定),则任何数据库更改都需要在此时间窗口内进行。如果更改可以“在线”完成,那么我们可能可以在更长的时间

我们使用InnoDB引擎在MySql中存储了一个非常大的(1000多万)行表。列“x”定义为“smallint(5)unsigned not null”

自几年前的原始设计以来,需求现在已经发生了变化,“x”列需要存储最小数据类型大小为“int unsigned not null”

我们允许“短暂”的停机时间来部署应用程序(少于5分钟),因此,如果数据库表需要以任何方式暂时不可用(例如,完全表锁定),则任何数据库更改都需要在此时间窗口内进行。如果更改可以“在线”完成,那么我们可能可以在更长的时间内接受性能下降

这里有没有人有过在一个非常大的表上更改MySql/InnoDB中的列类型的经验?如果是这样的话,它运行正常吗?大概需要多长时间(我意识到这取决于硬件,我只是想了解我们在时间窗口中要求做的事情是否有可能)


提前谢谢,

这是我用过的食谱

在你有旧专栏的地方,一个

  • 创建一个新的列b
  • 创建一个触发器,在a上更新/插入时更新b
  • 更新b=a
  • 删除引用对象的所有fkey关系
  • 为b创建fkey关系
  • 更新代码以使用列b而不是列a(部署)
  • 在a列上放置触发器
  • 删除a列

  • 如果必须重新更改列名,请重复所有步骤。

    您可以通过创建一个新表作为原始布局的克隆,在线执行此操作

    CREATE TABLE newtable LIKE oldtable;
    
    接下来,修改新表的列以符合新规范

    ALTER TABLE newtable ... ;
    
    完成后,复制数据

    INSERT INTO newtable SELECT * FROM oldtable;
    
    最后,利用几分钟的停机时间将旧表重命名为其他表,然后为新表指定旧表的名称

    当然,您需要有足够的存储空间来存储两份可用的表。此外,您可能希望在执行复制时禁用新表上的索引,以减少复制操作期间服务器上的压力

    一旦您确信旧表中的所有数据都已复制到新表中而没有任何丢失,您就可以最终完全删除旧表

    编辑:

    实际上,更好的方法可能是只向现有表中添加一个满足要更新列的新要求的新列,将旧列的值复制到新列,删除旧列,并将新列重命名为旧列的名称。这肯定会降低对存储的要求


    此外,如果有任何FK约束依赖于所讨论的列,则需要在启动之前删除它们,并在启动后在新列上恢复它们

    您目前有什么样的高可用性解决方案

    我这样问是因为,5分钟的停机时间不足以让操作系统更新等正常任务重新启动

    因此,您必须有某种高可用性解决方案,以允许这些定期(我假设您的运营团队继续不时应用补丁)更新

    应该可以使用这样的系统来实现这一点

    但是,ALTER TABLE允许表在整个运行过程中保持可用于读取操作,并且在结束时仅在短时间内(在大多数系统上,远少于五分钟)阻止读取

    所以,问一下,什么时候可以合理地阻止写入


    而且,10万行不是一张大桌子,不管你怎么想。它可能适合ram,因此更改速度非常快。

    这种方法非常快

    Query OK, 10000000 rows affected (6 min 0.14 sec)
    

    那么在复制操作期间添加到表中/修改的数据又如何呢?谢谢,但我也有@fvu的担忧,因为每次点击应用程序服务器的交易都会更新此表(即一分钟多次)。好的,这是一个很好的观点,我没有想到这一点。我想您可以实现一个触发器来保持两个列/表的同步,直到您准备好切换为止。当您将ALTER TABLE应用到测试实验室中生产级硬件上大小类似的表时,需要多长时间?@MarkR-正在进行中,但可能需要一段时间才能将环境设置为我的团队无法控制的状态。因此,试图同时获得可行性的想法……对于HA来说:负载平衡器后面的两个无状态应用服务器意味着它们可以独立关闭,以便进行操作系统修补等。然而,两个应用程序服务器共享相同的DB for state,这正是我所关心的,因为当应用程序服务器启动时,我们根本无法阻止对此表的写入,如果它们关闭,则会出现5分钟(ish)窗口。关于大小:很高兴知道10M不是“大”,我们正在对此进行一些性能测试,因此,如果这不是一个问题,我们将非常感兴趣……谢谢!这是一个非常有趣的想法-我需要考虑一下,但它可能只适合我们。。。