Chinaunix首页 | 论坛 | 博客
  • 博客访问: 426384
  • 博文数量: 137
  • 博客积分: 5190
  • 博客等级: 大校
  • 技术积分: 997
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-21 16:19
文章存档

2011年(17)

2010年(120)

我的朋友

分类: Mysql/postgreSQL

2010-03-08 17:51:30

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 说:
 
 呵呵  我只是看到了 供大家参考  其实我很希望能听到他的答案的
 毕竟这种经验很宝贵
 我们分享一下 大家也能通过交流学到不少东西
 下班了 回家
 有答案了 记得招呼一生
 大家也多去问问朋友 期待精彩解答~
阅读(1900) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~