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吧?
表结构和数据如下:
这个问题可以结合这张图理解:
再结合问题的这张表,name和id一起看。
锁的范围是a 50 到 e 30这个区间。
也就是:
a 5
a 10
a 50
gap lock
c 20
gap lock
c 60
gap lock
e 30
...