Saver 说:
大家给解答下
一亿条以上记录的表,在线增加column,不锁表,不下线,怎么搞定,而且是很迅速
拉风~zhang 说:
增加一个空字段
目木 说:
...不知道,上次我300W增加一个字段都下线了
Saver 说:
嗯,人不下线
不锁表
不停业务
很快
拉风~zhang 说:
创建一个表呗,里面就这个字段
目木 说:
...
wybjbjbj 说:
我很期待这题的答案
目木 说:
我也是
拉风~zhang 说:
或是,人家原来的表里面就有多余的字段,直接改名字
saver....你怎么回答
目木 说:
那应该不是这个题目的本意
isql 说:
有没有限定数据库?
mysql?
拉风~zhang 说:
isql,sql server怎么实现?
Saver 说:
mysql
isql 说:
你是说达到他的要求?
Saver 说:
no
我提的几个方案人都说不对
少坡 说:
刚才那个怎么实现的呀?
seacoastboy->海~ 说:
在等 答案
wybjbjbj 说:
把这题发到cu上请大牛们给答一下吧
目木 说:
是啊
isql 说:
单库?
没有slave?
少坡 说:
zyy,叶哥在不在,出来解答
Saver 说:
另外一个问题,对那种一天一两亿数据膨胀的表,如何维护
isql 说:
限制好所有条件,我到推上问问几个超级大牛
Saver 说:
就那些条件了
目木 说:
..
isql 说:
单机的?
Saver 说:
没说
多机我提了,人说不对
说:
什么问题?
我刚才掉线了……
Saver 说:
不管是主从复制,还是另建新表导入数据rename
拉风~zhang 说:
这单双没有关系
Saver 说:
zzy
isql 说:
备用master先增加再切换呢?
目木 说:
没用的,不能改表名
拉风~zhang 说:
人家说迅速!!!
说:
完全不知道你们在说什么
拉风~zhang 说:
直接增加
Saver 说:
一亿条数据,并且在线不断增长的一个表,如果不锁表,不下线,增加新列
wybjbjbj 说:
快把问题粘贴给zyy
拉风~zhang 说:
大家,安静下
目木 说:
直接增加会锁表的
说:
有查询吗?
Saver 说:
肯定不是直接增加,直接就挂掉了
有
有查询也有插入
说:
意思是,增加新列的情况下,不阻塞读和写?
Saver 说:
嗯
wangping(提供方便易用的沟通工具) 说:
我觉得mysql本身肯定没有提供这种联机修改的能力,所以肯定要从架构上考虑,比如最简单的,通过新建一张表(多一个字段),把原来的数据补进去,然后用存储过程或者函数在更新原来的表同时更新新建表。等数据完全一致,就可以停止向原来的表写数据了,即可以把原来那个表下线了。
说:
是单库?
没有备库吗?
Saver 说:
单机吧
我说了新表新库,另起替换的方案,人说,不对
雨丝中的眼泪 说:
建个空表tb1, 然后从tb倒数据到TB1 最后该程序从新表里读取。这方法可行吗
目木 说:
新表新库业务肯定要停一下
Saver 说:
双主结构应该是不支持表结构不同的表数据同步的
目木 说:
建个空表tb1, 然后从tb倒数据到TB1 最后该程序从新表里读取 这个也要停啊
说:
……
雨丝中的眼泪 说:
不用吧。只要上传程序那几秒钟就完成了
说:
如果有主备两个库的话,会容易点
说:
那不是停么?
雨丝中的眼泪 说:
想不出来了 看看别人有没有奇妙的方法
目木 说:
条件已经是不下线了
说:
有主备不需要下线的
少坡 说:
这样行不行,导出该表结构和数据,修改表结构,数据,导入
isql 说:
迅速阿
说:
这样数据会丢掉一部分的
说:
这样会锁表的
拉风~zhang 说:
目木 说:
这样要改表名
锅巴GG 说:
我知道方案
说:
少坡说的那个是不会锁表的
isql 说:
是啊
目木 说:
少坡说的会改表名
说:
导出的时候不锁表?
那样丢数据
isql 说:
就是select阿
目木 说:
导出的时候可以不锁表
isql 说:
怎么会锁表
拉风~zhang 说:
什么引擎?
用什么工具?
说:
mysqldump读取innodb的表,是不会锁住的
目木 说:
en
拉风~zhang 说:
说:
但是还是会丢数据的,你改表结构的时候,插入的数据没了。
说:
这个数据可以补的
说:
导入的时候呢?
少坡 说:
是的,这样会丢失数据,谁还知道别的办法?
补就要修改表名
目木 说:
关键是改两个表名的时候
说:
MS结构可以做到的
先更改备库的表结构
拉风~zhang 说:
关键,不是丢不丢数据
Saver 说:
丢不丢数据,这个表就是已经下线了
你们不管是咋搞
锅巴GG 说:
错错错...
说:
单机,不是ms
说:
我觉得没有对错问题,关键是那人也没说清楚具体的场景
和应用类型也有关系的
锅巴GG 说:
....
少坡 说:
锅巴GG,知道方案就说
锅巴GG 说:
这个是一个常见案例
一般会这么操作
前提是这张表有PK 能确定记录唯一性
Saver 说:
搬凳子~
锅巴GG 说:
然后根据这个PK 新建一张表
PK + 新字段
然后select into pk到新表
就达到业务需求量
然后等有机会下线的时候 合并这个字段
这是一种最常用的方案
拉风~zhang 说:
没机会下线
说:
select into
锅巴GG 说:
没机会下线也不影响业务
isql 说:
恩
Saver 说:
这个也否了。。。
锅巴GG 说:
否啥啊
Saver 说:
我提过了
锅巴GG 说:
如果是oracle的话
Saver 说:
多表JOIN
锅巴GG 说:
可以用DBMS_REDEFINITION
Saver 说:
根据pk
mysql
目木 说:
先pk insert,再根据pk update ?
锅巴GG 说:
默认值呢?
拉风~zhang 说:
锅巴,为什么要保证记录唯一呢?
Saver 说:
不唯一咋对应记录呢?
zyy
汗,看错了。。
拉风
少坡 说:
这个可以做在新表外键,根据外间跟新新表
拉风~zhang 说:
不就是,数据的导入导出吗
少坡 说:
不是,是说的 锅巴GG 的方法
拉风~zhang 说:
我还不能体会锅巴的精髓
锅巴GG 说:
这种是最常见的做法了
说:
我比较同意外键的做法
Saver 说:
嗯,问题是这样的话,需要设计个视图提供查询
表倒是不下线了
拉风~zhang 说:
锅巴,你的新表,事实上就是pk字段和新增字段
Saver 说:
嗯
锅巴GG 说:
对
Saver 说:
没错
锅巴GG 说:
这种是影响最小 最保险的做法
而且快速
拉风~zhang 说:
saver,一开始就说不对
Saver 说:
这个方案已经被否了,我面试的时候提过了
锅巴GG 说:
默认值也否了?
Saver 说:
人说不能添加表
默认值是什么
这个我没说
说:
晕死,不能用视图吧,用视图不是太简单了?
锅巴GG 说:
加一个字段 默认允许null
锅巴GG 说:
呵呵 也至少是一次经验
没啥的
他给你结果了吗?
拉风~zhang 说:
视图也的另建表
Saver 说:
这样就可以不用临时表锁表么?
锅巴~~
锅巴GG 说:
当然
因为select into from select
这种系统自己完成时最快的
因为数据不一致都在内存里面
其他数据只是物理copy而已
Saver 说:
alter table icecream add column flavor varchar (20) ;
锅巴GG 说:
系统只要在复制后只要根据日志做一下redo就行了
锅巴GG 说:
嗯?
怎么
这样新数据会物理写
老数据默认就是null啊
表schema也改好了
拉风~zhang 说:
这一条语句就完成了,不是。
Saver 说:
ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
这个不锁表?
不阻塞读写?
说:
不可能吧
Saver 说:
读不阻塞可能
写不阻塞?
这个我没试过。。
说:
恩,肯定锁的
s锁
Saver 说:
这个思路我研究下
拉风~zhang 说:
锅巴,select into from select 这个操作很快吗?
锅巴GG 说:
嗯 是ide
是的
不用锁表啊
少坡 说:
1亿的数据肯定不能直接alter的
Saver 说:
嗯
锅巴GG 说:
alter必死 肯定不行的
Saver 说:
这个肯定的
少坡 说:
恶报的
锅巴GG 说:
ALTER TABLE `customer`
ADD COLUMN `test` mediumint NULL DEFAULT NULL AFTER `creation`;
拉风~zhang 说:
但是,alter一个空字段是可以地
少坡 说:
恩的
打错一字了
锅巴GG 说:
如果说null允许 并且default null
我试下来效果不错
但是没上亿的试过
少坡 说:
而且肯定会阻塞写
锅巴GG 说:
这样不知道好不好 说不好 要看mysql怎么实现了
因为null default null 应该不用影响写操作的
因为完全不影响现在这些数据
拉风~zhang 说:
该表结构是要锁那么一下的,吧
Saver 说:
比如说你alter的时候同时在插入数据
他咋插
按哪个结构插?
说:
这样是会锁表的
Saver 说:
嗯,应该是锁表的
少坡 说:
会阻塞
说:
mysql修改表结构,是通过创建一个新表,全量插入数据,最后rename来实现的
Saver 说:
这样的话,如果临时表容量不够,那么这个alter是无法实现的吧
说:
是的
MySQL会报table is full
说:
对于这种应用上的需求,用外键,不合并进去,可能更好一点,当然,和题目要求不符。
锅巴GG 说:
....
这流氓 一点风度也没有
tony 说:
一亿条的数据,这个数据量太大了。就算插入1000次/秒,也要插入27个小时。而且mysql在有索引插入的时候200w是个分水岭,200w之后,无索引插入比有索引插入还要快。
&FROST(simple world simple life!~) 说:
。。。
说:
其实他的意思是:“老子就看不过你这么帅的,就不让你过”^_^
锅巴GG 说:
什么啊
说:
……
锅巴GG 说:
哪有inert这么做的
直接data copy好吧
Saver 说:
都是批量插入吧
说:
大量数据还是load快。
Saver 说:
一条一条插,估计早死掉了
tony 说:
如果是Inondb的表,你怎么data copy呀?
说:
恩
Saver 说:
load infile
锅巴GG 说:
晕
说表引擎了吗?
没说啊
说:
他说如果
锅巴GG 说:
再说 即便是innodb
也没有关系的 绝对不可能是insert机制的
都是数据块复制的
这时候哪有逻辑概念
拉风~zhang 说:
顶你,锅巴
锅巴GG 说:
insert难道你还要写log?
说:
-_-!你的意思是物理复制?
锅巴GG 说:
如果算上产生log的时间
这事不用干了
Saver 说:
产生log。。。
tony 说:
恩,数据块复制1亿的数据量,你有测试过要多长时间吗?
锅巴GG 说:
如果要log的话
没有测试过
说:
然后binlog、log、slowlog全开^_^
锅巴GG 说:
但是如果是pk 肯定是最快的
因为索引是独立区域
当然我对mysql了解不深 我只能去类比
Saver 说:
inndb的话,pk就死了
要是无顺序,那更惨
锅巴GG 说:
他说表引擎了不?
Saver 说:
没说
拉风~zhang 说:
myisam是分index data
Saver 说:
但是看这样,这玩意应该是做数据分析的
表的出处是这样的,我来介绍下背景
锅巴GG 说:
如果说OLAP的 不可能不让下线的
我觉得他的前提是OLTP的
Saver 说:
嗯
使用它们的客户端
tony 说:
我觉得这个面试题就是用这个1亿多条的数据量吓唬人的。什么场景、应用都不给,很难回答。
Saver 说:
然后客户端会去分析你的系统内存运行的exe程序
然后,生成md5
第一次会完全上传系统内没记录的内存EXE程序
然后记入数据库,并分析你的EXE文件是否有害
或者是否和系统冲突
当用户基数很大的时候
那么,轻松就上亿了
锅巴GG 说:
恩 也许他自己也不知道 甚至他的答案也可能是错误的 他也不知道...
哦
tony 说:
如果是只讨论方法的话,锅巴说的是对的。
锅巴GG 说:
呵呵 我只是看到了 供大家参考 其实我很希望能听到他的答案的
毕竟这种经验很宝贵
我们分享一下 大家也能通过交流学到不少东西
下班了 回家
有答案了 记得招呼一生
大家也多去问问朋友 期待精彩解答~
阅读(1911) | 评论(0) | 转发(0) |