上周值班,碰到这样的一个客户问题,表结构简化如下:
CREATE TABLE `aa` (
`c1` int(10) unsigned NOT NULL AUTO_INCREMENT,
`c2` int(11) DEFAULT NULL,
`c3` int(11) DEFAULT '0',
`c4` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
在使用如下的语法时,怎么会插入两条 c2 = 1007 and c3 = 1的记录?
insert into aa(c2,c4) select 1007, 8 from dual where not exists(select * from aa where c2 = 1007 and c3 = 1);
毫无疑问,先排查一下用户实例的binlog,发现确实一前一后有两条插入语句。
那会不会是MySQL的bug呢?即使是bug,也得要先复现出来吧。
如何复现呢?
session 1:
begin work;
insert into aa(c2,c4) select 1007, 8 from dual where not exists(select * from aa where c2 = 1007 and c3 = 1);
这时先不commit
session 2:
begin work;
insert into aa(c2,c4) select 1002, 5 from dual where not exists(select * from aa where c2 = 1002 and c3 = 0);
commit
session1:
commit
ok,有点眉目了。在这种情况下,是可以稳定复现的。用户反映他的业务是自动提交的。如果两个insert来自不同的服务器,第一次执行的时间很长还未提交,第二个就开始执行了。也是可能出现的。后来从SQL审计日志从验证了的确如此。
不过客户去复现时,却依然复现不出来。这时想到可能