mysql 如何给大表添加字段
1. 能不加字段就不要加, 能不修改字段就不要修改, 能不删除字段就不要删除, 等等为什么要删除字段呢? 如果没事,不要蛋疼的找事。 实际上,我们那次更新失败后, 我们并没有增加那个字段, 然后我们一直运行到今天, 但是后来还是增加了其他字段
2. 增加字段的情况下, 如果可以通过增加一个新的表来增加这个字段, 那么就增加一个新的表, 通过cache 或 程序来实现join 的效果
3. 如果能停机, 并且停机的时间在你容忍范围之内, 数据备份之后停机来做。 如果是主从备份,做这样大的操作的时候,停掉主从备份, 万一你挂了, 备份数据库可以救你。 等到一切安全了, 重启主从备份;
4. 如果上面都不行, 这个字段还是要改,要加, 需要用到下面的方法, 也是扇贝网正在使用的方法;
修改大数据表的方法:
1. 被修改的表 Table A 需要有一个记录时间戳的字段, 这个时间戳就是每次数据更新,都会更新的字段, 这个字段需要有索引,在django里可以使用 auto_now=True
2. 创建一个新的临时表 Table B, 不是tmp_table, 是一个新的表,但是是临时使用的。 这个表和要修改的表拥有一模一样的数据结构, 加上你要修改的部分, 比如增加的字段;
3. 记录下Table A 的索引
4. 删除 Table B 的全部索引
5. 把Table A 的数据全部复制到Table B, 是不是执行 INSERT INTO B(field1, field2) SELECT field1, field2 FROM A? 当然不是, 这么做不还是锁死了Table A 么, 这里的迁移就是一个需要细分的地方,需要写一个脚本, 让程序每次读取比如5000条数据出来, 插入到Table B里面, 因为Table B 是没有索引的, 所以要当心不要使用多进程来做; 如果是多进程, 要确保插入到B的时候是不会有重复数据的; 如果是1000万的数据,每次5000条, 假设这个操作需要500ms, 那么 2000*200ms = 16 分钟。 这只是一个估值, 具体情况和服务器当时的情况有关, 不好细说。 另外, 我们要记录这个迁移开始的时间点,记为t1;
6. 那么这个时候Table A 的数据是不是都进入了Table B 呢, 应当说差不多大部分都进入了, 但5中说, 这大概需要16分钟, 这么长的时间里, 可能有新的数据进入了, 也有可能已有的数据发生了更新, 所以我们要把Table A 中在t1 之后发生变化的数据查找出来, 然后更新到Table B 中, 我们的做法是:
记录这个操作对应的时间点 t2
BEGIN;
DELETE FROM B WHERE updated_time > t1;
INSERT INTO B(field1, field2) SELECT field1, field2 FROM A WHERE updated_time >t1;
COMMIT;
7. 现在A 和 B 差不多该同步了吧? 差不多了, 但是6 执行完之后, A仍然在写, 子子孙孙无穷尽也 ... , 但这个时候 A 和 B 的差异已经非常非常小了, 所以在下一步,我们在一个transaction 里执行下面的操作:
BEGIN;
DELETE FROM B WHERE updated_time > t2;
INSERT INTO B(field1, field2) SELECT field1, field2 FROM A WHERE updated_time >t2;
ALTER TABLE A RENAME TO C;
ALTER TABLE B RENAME TO A;
COMMIT;
8. Done
PS: 如果A表没有时间戳, 实际上没有先见之明的人大概不会想到要预留一个时间戳的字段, 那么几乎是没有办法快速比较两个表的差异的, 这个时候我选择的做法就是放弃修改的数据, 只管新的数据了, 所以只要把t1, t2 换成id 就可以了, 这样delete 语句也省略了, 因为没啥好delete的;
千万不要想着根据ID 来JOIN 然后更新B表的字段来补齐新的数据, 如果能把两个千万级别的表JOIN起来, 内存有多大呢?
9. 上面的解决方案是我们第二次尝试之后犯下了一个巨大的错误,这个错误导致网站瘫痪了大概20分钟, 如果你和我一样没有发现问题,那么这就是悲剧的地方。 问题就在于我是根据上面的PS来操作的, 然后B就华丽地变成了A. B 表至今身上是没有索引的, 立即悲剧。 所以应当在第5步之后按照A的索引为B建立索引, 待索引全部好了之后, 再继续6。 如果不是走PS这条路, 而是有时间戳的字段的话, 在6的时候会发现这个问题, 因为那条Delete 慢的超出想像, 会明白这里是有问题的
10. 新手, 请在本地练习之后, 再实际操作; 可以多操作几次, 写一个脚本,服务器上直接执行脚本.
转载:https://zhidao.baidu.com/question/917987491401145099.html
mysql 如何给大表添加字段的更多相关文章
- oracle大表添加字段default经验分享
当oracle单表数据量上亿时,对表进行alter table aa add column_1 varchar2(2) defalut 'Y';时,效率及安全性是必须考虑的因素. 本帖以2亿的数据表a ...
- 如何优化MySQL千万级大表
很好的一篇博客,转载 如何优化MySQL千万级大表 原文链接::https://blog.csdn.net/yangjianrong1985/article/details/102675334 千万级 ...
- Mysql千万级大表优化
Mysql的单张表的最大数据存储量尚没有定论,一般情况下mysql单表记录超过千万以后性能会变得很差.因此,总结一些相关的Mysql千万级大表的优化策略. 1.优化sql以及索引 1.1优化sql 1 ...
- 【MySQL】删除大表的讨论【转】
转自http://tech.ddvip.com/2013-07/1373269453198566.html 微博上讨论MySQL在删除大表engine=innodb(30G+)时,如何减少MySQL ...
- MySQL 存储过程删除大表
1.权限问题 alter routine 编辑或删除存储过程 create routine 建立存储过程 execute 创建存储过程 2.存储过程相关的一些命令 show procedure sta ...
- 在高并发、高负载的情况下,如何给表添加字段并设置DEFAULT值?
在高并发.高负载的情况下,如何给表添加字段并设置DEFAULT值? 在Oracle 12c之前,当Oracle表数据量上亿时,对表执行“ALTER TABLE XXX ADD COLUMN_XX VA ...
- ruby数据库表添加字段、修改字段类型、修改字段名称
Rails 手册 3.8 使用 change 方法 1.为表添加字段 rails g migration add_column_to_d_groups_equip_num class AddColum ...
- Yii2给数据库表添加字段后对应模型无法识别到该属性的原因和解决办法
Yii2给数据库表添加字段后对应模型无法识别到该属性的原因和解决办法 应为数据库表的结构被缓存了.删除runtime文件夹或者执行 //清理指定表结构缓存数据 Yii::$app->db-> ...
- MySQL千万级大表优化解决方案
MySQL千万级大表优化解决方案 非原创,纯属记录一下. 背景 无意间看到了这篇文章,作者写的很棒,于是乎,本人自私一把,把干货保存下来.:-) 问题概述 使用阿里云rds for MySQL数据库( ...
随机推荐
- asterisk搭建goip
利用asterisk来搭建goip使用,步骤如下: 第一步:先需要搭建centos服务器并优化 搭建centos服务器就省略: 优化centos服务器,进行如下步骤: 关闭防火墙:systemctl ...
- bug是前端还是后端
分析bug是前端还是后端的 如何分析一个bug是前端还是后端的? 平常提bug的时候,前端开发和后端开发总是扯皮,不承认是对方的bug这种情况很容易判断,先抓包看请求报文,对着接口文档,看请求报文 ...
- java8 stream两个集体交集、差集、并集操作
业务场景: 页面左右两个datagrid,双击左边datagrid行,移动到右边datagrid,右边datagrid行双击,移动到左边datagrid 点击保存,提交修改的数据到后台 后台要把查询到 ...
- C++踩坑记录(一)std:;string的析构
之前写服务端程序有一个往消息队列里面推json的过程,然后发现推进去C#端取到的无论如何都是个空指针 简单复现一下现场 string str1 = string("hello1") ...
- hg如何回退到某个版本
hg 如何回退 hg ... ? ? ?
- 微信小程序审核不通过的解决方法
前言 近来,微信小程序一直活跃在开发者的眼球中.很多开发者都投身微信小程序的开发中,而这些开发者,总是需要面对最后一道难题:如何以一种优雅的姿势来通过微信官方的审核.本文基于几天前提交审核的一次总结, ...
- bzoj1497: [NOI2006]最大获利(最小割)
传送门 第一眼看去:好难 第二眼:不就是个裸的最大权闭合子图么…… 我们从源点向所有用户连边,容量为收益,用户向自己的中转站连边,容量为INF,中转站向汇点连边,容量为费用 那么总收益-最小割就是答案 ...
- .net System.Net.Mail 之用SmtpClient发送邮件Demo
private static bool sendMail() { try { //接收人邮箱 string SendTo = "XXXXX@163.com ...
- springboot2.0入门(二)-- 基础项目构建+插件的使用
一.idea中新建第一个HelloWorld项目 点击next: 下一步 在这里可以选择我们需要依赖的第三方软件类库,包括spring-boot-web,mysql驱动,mybatis等.我们这里暂时 ...
- @EnableScheduling