需要操作一个线上的表,添加字段,先查看磁盘占据大小以及记录数,500W记录,3.3G磁盘空间
hy:3306:orcl20:53:33> select table_name,table_rows,(data_length+index_length)/1024/1024/1024 as disksize from information_schema.tables where table_name='goods_recheck'; +---------------+------------+----------------+
| table_name | table_rows | disksize | +---------------+------------+----------------+
| goods_recheck | 5117547 | 3.301101684570 | +---------------+------------+----------------+
1 row in set (0.00 sec)
hy:3306:orcl20:53:46>
还好,不算大,估计在10分钟内完成,mysql 5.6 add字段不阻塞其它线程,所以可以搞起,先来add columns
hy:3306:orcl20:31:42> alter table orcl.courege add column cgid bigint default null;
Query OK, 0 rows affected (5 min 10.68 sec)
Records: 0 Duplicates: 0 Warnings: 0
hy:3306:orcl20:38:35>
但是,但是后面还有add index操作,那么显然default null就不合适了,咋办咋办?一种方案是直接drop字段,然后重新加字段,这样会短暂阻塞,而且drop的时间比起add来说基本差不多,与开发人员沟通了之后,目前业务低峰期,而且是新字段,业务没有使用,可以直接drop字段然后重新加,于是开始操作:
hy:3306:orcl20:43:29> ALTER TABLE goods_recheck DROP COLUMN goods_id;
Query OK, 0 rows affected (5 min 6.19 sec)
Records: 0 Duplicates: 0 Warnings: 0
hy:3306:orcl20:51:36>
PS:操作的过程中,频繁执行select * from information_schema.processlist t where info is not null order by time ;查看阻塞的线程情况,南无阿弥陀佛,幸好,执行过程中,没有出现阻塞。
再重新加字段:
hy:3306:orcl20:55:36> alter table orcl.courege add column cgidbigint not null default 0;
Query OK, 0 rows affected (5 min 12.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
hy:3306:orcl21:01:05>
然后加索引:
hy:3306:orcl21:02:16> alter table orcl.courege add index `goods_recheck_goods_id_index` (`goods_id`);
Query OK, 0 rows affected (12.91 sec)
Records: 0 Duplicates: 0 Warnings: 0
hy:3306:orcl21:02:59>
思考:如果不drop的情况,该怎么弄呢?还要一个折中的办法,有一个前提是代码中没有select *等不规范的sql语句:
(1)change goods_id字段为goods_id_temp1一个临时废弃字段
alter table orcl.courege change column cgidgoods_id_temp1 bigint default null;
(2)然后再添加字段goods_id alter table orcl.courege add column cgidbigint not null default 0;