持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情
生产大表加字段/索引
为表增加索引是会对表进行加锁处理的。
稍有不慎,可能会导致表被锁后,业务被阻塞,严重的可能导致服务雪崩
最笨的办法,对于是千万以内的表,生产可以暂停的,就暂停服务直接在原表上操作. 下下策
1 如何给千万级的表增加字段或者索引 gh~host pt 工具 先创建一个旧表结构一样的表然后 给新表加索引 然后将旧表的数据导入到新表 然后rename 旧表 ,再将新表表名改成旧表的表名
#操作步骤: #1、创建一张和原表结构一样的空表,只是表名不一样 create table tb_name_tmp like tb_name;
#2、把新建的空表非主键索引都删掉,因为这样在往新表导数据的时候效率会很快(因为除了必要的主键以外,不用再去建立其它索引数据了) alter tb_name_tmp drop index index_name;
#3、从旧表往主表里导数据,如果数据太大,建议分批导入,只需确保无重复数据就行,因为导入数据太大,会很占用资源(内存,磁盘io, cpu等),可能会影响旧表在线上的业务。我是每批次100万条数据导入,基本上每次都是在 20s左右 insert into tb_name_tmp select * from tb_name where id between start_id and end_id;
#4、数据导完后,再对新表进行添加索引 create index index_name on tb_name_tmp(column_name);
#5、当大部分数据导入后,索引也建立好了,但是旧表数据量还是会因业务的增长而增长,这时候为了确保新旧表的数据一至性和平滑切换,建议写一个脚本,判断当旧表的数据行数与新表一致时,就切换。我是以 max(id)来判断的。 rename table tb_name to tb_name_tmp1; rename table tb_name_tmp to tb_name;
我们都知道,为表增加索引是会对表进行加锁处理的。稍有不慎,可能会导致表被锁后,业务无法进行读写操作而产生事故影响,通常都是报错Waiting for meta data lock。在对表进行修改时,特别是生产上,我们首先要观察对应的表此时是否在高并发读写(选择操作时机)、表的量级信息。
方案
整体思路是:
先创建一张表,结构和原表相同;
在新表上添加索引;
rename新表为原表的表名,原表换新的名称;
为原表新增索引;
待索引创建成功后,rename原表为原来的名称,并将新表里的数据导入到原表中 表有主键 然后把conversationid + id 做为二级索引 select * from t where conversationid = order by id 有时走主键索引,有时候走 二级索引 走主键索引时耗时长13秒