[ruby on rails]mysql百万千万级表加字段操作

场景

某表users已有数据上千万,或者由于有很多text字段存入大量内容,导致表大小达到TB级,我们再直接给该表新加字段时候,很长时间都加不上(实际操作过2个小时加不上一个字段),甚至表被锁死

注意:

  • 在业务低峰期做,将影响降到最低, 能停机做更好
  • 删除索引后再修改表结构,效率将大大提升

解决方案:

  • 思路1:建一个和该表一样的新表,给新表添加好字段,再将老表数据导入到新表, 在Navicat操作就行
  • 具体操作:
# 生成新表
create table new_users like users;

## 生成删除索引语句
SELECT CONCAT('ALTER TABLE ',i.TABLE_NAME,' DROP INDEX ',i.INDEX_NAME,';') FROM INFORMATION_SCHEMA.STATISTICS i WHERE TABLE_SCHEMA = '库名' AND TABLE_NAME='users' AND i.INDEX_NAME != 'PRIMARY';

## 生成添加索引语句
SELECT CONCAT('ALTER TABLE ',i.TABLE_NAME,' ADD INDEX ',i.INDEX_NAME,'(',i.COLUMN_NAME,');') FROM INFORMATION_SCHEMA.STATISTICS i WHERE TABLE_SCHEMA = '库名' AND TABLE_NAME='users' AND i.INDEX_NAME != 'PRIMARY';

### 删除新表索引
ALTER TABLE new_users DROP INDEX product_id;

### 新表添加字段
alter table new_users  add content text;
alter table new_users  add seperate_type int(11) DEFAULT 1;

## copy数据 
insert into new_users(字段1, 字段2, 除了created_at和updated_at字段, ......) select 字段1, 字段2, 除了created_at和updated_at字段, ...... from users;
 如果有字段和数据库保留字符冲突,例如desc, 则用`desc` 表示
 
#有被锁的话就解锁
UNLOCK TABLES;

## 删除旧表
drop table users;
如果有外键影响,删不掉,SET FOREIGN_KEY_CHECKS=0; DROP TABLE variables; SET FOREIGN_KEY_CHECKS=1;

## rename新表
rename table new_users to users;

## 添加索引  3min+
ALTER TABLE users ADD INDEX index_users_product_id(product_id);    
  • 思路2:使用pt-online-schema-change

1.介绍:
pt-online-schema-change是percona公司开发的一个工具,在percona-toolkit包里面可以找到这个功能,它可以在线修改表结构

2.原理:

  • 首先它会新建一张一模一样的表,表名一般是_为前缀_new后缀,例如原表为t_user 临时表就是_t_user_new
  • 然后在这个新表执行更改字段操作
  • 然后在原表上加三个触发器,DELETE/UPDATE/INSERT,将原表中要执行的语句也在新表中执行
  • 最后将原表的数据拷贝到新表中,然后替换掉原表

使用:
没用过,具体上网查

猜你喜欢

转载自blog.csdn.net/qq_41037744/article/details/107897134
今日推荐