你好,我是yes。 前段时间写了一篇关于 MySQL 锁的文章,一些小伙伴们在阅读之后产生了一些疑问,这些问题还挺有代表性的,所以在这里做个实验,来用事实探究一番。 那篇文章提到了记录锁(Record Locks),顾名思义锁的是记录,作用在索引上的记录。 锁是作用在索引上这句话可能不太好理解,并且对于在可重复读和读提交两个隔离级别下,关于是否命中二级索引的锁之间的阻塞也不太清晰。 这句话读着可能有点拗口,没事,我来给你看几个实验,对这一切就异常清晰了。 实验的 MySQL 版本为:5.7.26。 实验一:隔离级别为读提交,锁定非索引列的实验 先建个非常简单的表,只有主键索引,没有二级索引。 CREATE TABLE `yes` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT NULL, `address` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 隔离级别如下: 关闭自动提交事务: 已经准备好的数据: 此时,发起事务 A,执行如下语句,且事务未提交: 接着,再发起事务 B,执行如下语句: 你可能以为事务 B 不会被阻塞,因为事务 B 锁的是name=xx和事务A锁name=yes讲道理相互之间没有冲突,但是从结果来看,事务 B 被阻塞了,调用select * from innodb_lock_waits;看下谁等谁 可以看到,事务6517(B)在等待事务6516(A)。 此时,调用 SELECT * FROM innodb_locks; 查看相关锁的信息 锁的类型就是行级锁,此时的锁为 X 锁,锁的索引就是主键索引,这个结果表明的意思是事务 B(6517)想要 id 为 1 的记录锁,但是这个记录此时被事务A(6516)占有。 是的,这里的 1 其实不是指第一个记录的意思,是 id… Continue reading 57张图,13个实验,干死 MySQL 锁!
Tag: 间隙锁
一个MySQL锁和面试官大战三十回合,我霸中霸!
我,小Y。 又来面试了,还是之前那家公司,即将和之前那个老面试官进行第二次 battle,心情还是xue微有点忐忑。 没看过第一次 battle 的同学可以看这里,一个MVCC和面试官大战三十回合 又一抹光亮闪过,面试官推门而入,我抬头望去,没错,还是那味儿。 看到面试官头上那“傲然矗立”的头发,差点又想站起来给他敬了个礼,算了先稳住,低调一点。 面试官瞥了我一眼:来吧,咱们继续面试,上次没办法,女朋友就是粘人,这次问 MySQL InnoDB 的锁喔。 我:…..(行,我知道你有女朋友了),好的面试官,您请。 面试官:MySQL InnoDB 的锁 和 MyISAM 的锁有什么区别? 我:MyISAM 只支持表锁,一锁就锁整张表,而 InnoDB 不仅支持表锁,还支持粒度更低的行锁,仅对相关的记录上锁即可,所以对于写入操作来说 InnoDB 的性能更高。 面试官:那不论表锁还是行锁,其实有分为两类的,你知道是哪两类吗? 我:你指的是 shared (S) locks 和 exclusive (X) locks 吗? S锁,称为共享锁,事务在读取记录的时候获取 S 锁,它允许多个事务同时获取 S 锁,互相之间不会冲突。 X锁,称为独占锁,事务在修改记录的时候获取 X 锁,且只允许一个事务获取 X 锁,其它事务需要阻塞等待。 所以 S 锁之间不冲突,X 锁则为独占锁,所以 X 之间会冲突, X 和 S 也会冲突。… Continue reading 一个MySQL锁和面试官大战三十回合,我霸中霸!