故障说明:
1.线上使用pt-online-schema-change进行表结构变更:将goods的num字段设置为NOT NULL,但是goods表的num已经存在为NULL的数据,执行前没有检测是否存在空值且没有调整为非空。
2.在使用pt-online-schema-change修改表结构过程的同时服务还有在写入num字段为NULL的数据,因此触发器执行插入_goods_new表失败,由于触发器需保证新、旧表的原子性,导致服务写入失败
还原问题
创建表:
create table goods(
gid int,
name varchar(20),
num smallint
);
造三条数据:
insert into goods values(1,'cat',40);
insert into goods values(2,'dog',63);
insert into goods values(2,'dog',63);
pt-online-schema-change执行过程
1.复制创建原表
create table _goods_new(
gid int,
name varchar(20),
num smallint
);
2.修改_goods_new表结构
Alter table `_goods_new` modify column num smallint not null
3.创建触发器
DROP TRIGGER IF EXISTS t1;
create trigger t1 after
insert on test.goods for each row
begin
replace into test._goods_new(gid,name,num)values(new.gid,new.name,new.num);
end
4.插入数据
INSERT LOW_PRIORITY IGNORE INTO test._goods_new(...)values(...)
模拟业务写入
insert into goods values(4,'pig',88);
select * from goods;
select * from goods_bak;
insert into goods values(4,'pig',null);
插入num为null的字段报错:SQL错误 [1048] [23000]: Column 'num' cannot be null