mysql 中,一张表里有 3 亿数据,未分表,要求是在这个大表里添加一列数据。数据库不能停,怎么做?

mysql 中,一张表里有 3 亿数据,未分表,要求是在这个大表里添加一列数据。数据库不能停,并且还有增删改操作。请问如何操作?

#福大大架构师每日一题#

回答·135
最热
最新
  • 玩过类似操作,数据一亿左右 1.建新表 2.做新表旧表实时同步(我用 canal 订阅 binlog,旧表变更实时同步到新表) 3.业务数据双写,同时写入新表和老表 4.旧表数据定时全量同步,实测一次 50w 条 IOPS 会占用 50%左右大概 3~5 秒,在业务低峰期可以操作,否则会影响到业务 5.数据同步完成后,比对没有问题,将所有读操作改到新表 6.取消双写,只写新表 7.取消同步,删除旧表
  • 1.新建一张表,把新增了的列字段加进来。 2.原来的数据记录标签,数据同时进入两张表。 3.原来的数据导入新表。 4.读取查询接口切换到新表。完成
  • 还在用关系型数据库的人,这些人要么是脑子进水了,要么不是专业的,他们的专业知识不支持他们与科技发展同步
  • 基本常识,mysql 单表有 500 到 700 万条数据就要分表,尝试过,在单表 900 多万条数据时查询,会卡死,一条简单查询,半小时不出结果。在 900 万条数据时还能 1 秒内出结果。
  • 说实话,我除了先建一张新表,然后做存量同步,再做增量同步直到完全一致,短暂中断业务,修改表名,再开启业务流量,我也没有其他办法。当然,你在此期间,如果有涉及新字段的操作,自己落文件,再同步进去吧。 But,Mysql 一张表 3 亿数据,搞不好还是宽表,还不拆分,这怎么想的,实在要 Sql 型数据库,就 oracle 吧。
  • 新建立一张一样的表,在新建表上修改字段,然后程序运行在这个新建的表上,最后把几亿的数据倒进来。 有 3 亿的数据,就别用关系型数据库了,这样的数据量除了大电商企业以外,基本上都是日志型数据,完全可以用一个非关系型数据库存储,然后预处理一下再放回到关系型数据库里,查询性能也有保障。
  • 最好是停机搞,假定停不了,3 亿数据也不是很大,聚簇索引也可以正常查询工作,做好备份,这个事情起码有 4 种解决方案可以做到。 1、阿里开源 dadax 工具可以做到快速搞定。先把原标备份到另一个表名备份,在拷贝一份作为同步源,然后新 datax 写个脚本 select insert 的 job 任务,跑完收工,单次可以在 10 万条,几扳手跑完收工。 2、kettle etl 解决方案可以搞定,搞个 kettle etl 脚本跑的要慢一点,灵活些,不过不影响结果。 3、cdc 数据同步方案+个性化程序可以搞定,复制个新表,同时 2 张表建立字段,然后建立个 max cdc 数据同步映射指向原表,然后正常操作新表,然后 maxwell 收到原标 binlog 日志变动,直接队列消费往 line 库里面搓就行了。本质是直接操作原表只是队列化,想怎么变更怎么变更,直接同步反应。 4、简单点,copy 表后,业务新增数据量不大的情况下,加字段后根据新增数据的具体性质直接写程序分段 update 可以搞定。
  • 对于大表可以使用 pt-online-schema-change 工具进行 alter table,修改大表不会锁表。 原理: 1. 创建一个和要执行 alter 操作的表一样的新的空表,后缀默认是 new。 2. 在原表中创建 3 个触发器分别对应 insert, update, delete 操作。 3. 以一定块大小从原表拷贝数据到临时表,拷贝过程中通过原表上的触发器在原表进行的写操作都会更新到新建的临时表,注意这里是 replace 操作。 4. 表名替换,将原表名 table 修改为 table_old, 将 table_new 表名修改为原表名 table 。 5. 如果有参考该表的外键,根据 alter-foreign-keys-method 参数的值,检测外键相关的表,做相应设置的处理。 6. 最后将旧原表删除。
  • 这个级别的表是千万不能直接修改数据库结构的,因为会会产生死锁,导致整个系统崩溃,需要建好一个新的空表加上字段,然后编写程序或者脚本把所有数据慢慢同步到这个新表,数据同步完成以后夜间迅速交换新表旧表表名就可以完成切换了。
  • 1.新建一个不可见的临时表 2.原始表 write lock 3.执行 insert…select…from… 4.同时重命名原始表和临时表,实现原子操作 注:使用 rename table…to…,…to… 5.删除原始表 6.释放 write lock