5月MySQL问题合集

好的,回到今天的主题,这一篇文章,来分享一些这个月朋友问到的一些MySQL问题,以及自己的见解,当然,不一定对,欢迎大家在留言区讨论。

问题1

在使用pt-osc有没有遇到过什么问题?

以前遇到过,某个表一个字段有重复记录,如果给这个字段加唯一索引,会丢数据。

为什么会出现这种情况,我们再来复习一下pt-osc的原理:

1 创建一张与原始表结构相同的临时表

2 然后对临时表进行表结构变更

3 通过触发器实现增量数据处理

delete =delete ignore

insert  = replace into

update=delete ignore + replace into

4 将原始表中的行复制到新表中

copy rows = insert ignore into

5 复制完成后,把原始表重命名为_xxx_old,将临时表重命名为xxx,再删除_xxx_old表


结合pt-osc的原理,再来分析上面的问题。

使用pt-osc添加唯一索引的时候,因为创建的临时表会先进行表结构变更,也就是添加唯一索引,再从原始表把数据复制到新表里。

这个时候,临时表因为有唯一索引,并且迁移数据是使用的 insert ignore into,也就是只会保留唯一索引这个字段的第一行,后面的全会忽略掉。

这也就是通过pt-osc添加唯一索引会丢数据的原因。


当然,有人会说,既然这个字段要添加唯一索引,那唯一索引的字段重复数据本身就应该处理掉。

实际情况是,这些重复数据,需要研发确定,然后自己处理,决定保留哪些行,而不是我们简单粗暴的insert ignore into掉。


问题2

session1:

begin;

update test_gap set name='cc' where name='c';

session2:

insert into test_gap values(51,'a');  会lock住

insert into test_gap values(41,'a');  不会lock住

RR隔离级别下,为什么name相同只要插入id>50的就会被lock住呢?二级索引对应的主键索引不会加gap lock吧?

表结构和数据如下:

5月MySQL问题合集-1


这个问题可以结合这张图理解:

5月MySQL问题合集-2


再结合问题的这张表,name和id一起看。

锁的范围是a 50 到 e 30这个区间。

也就是:

    a 5
    a 10
    a 50
    gap lock
    c 20
    gap lock
    c 60
    gap lock
    e 30
    ...