用MySQL已经有一段时间了,对事务的隔离级别比较了解,但是对InnoDB如何实现这些隔离级别(锁),了解得还是比较少。在现实中如果有死锁的产生,或者有由锁造成的SQL性能影响,会变得比较棘手。所以参考官方文档,写下此文,一来贴整理一下知识的脉络,填补知识盲区,二来培养一下知识分享的习惯,利己利人。
下文中不同事务用T加数字表示。如 T1,表示事务1。
MySQL的锁有主要有以下几种:
• Shared and Exclusive Locks 共享与排他锁
• Intention Locks 意向锁
• Record Locks 记录锁
• Gap Locks 间隙锁
• Next-Key Locks 临键锁
• Insert Intention Locks 插入意向锁
• AUTO-INC Locks 自增锁
- Shared and Exclusive Locks 共享与排他锁
共享锁与排他锁的组合,当在插入或修改的数据时,需要获得排他锁,读取数据时,需要获得共享锁。不同线程可以同时获得共享锁,即可以同时进行读操作。但如有线程获得排他锁,其他想要获得排他锁,或共享锁的线程需要在队列中等待。(后面将撰文详细描述共享排他锁的几种实现,先Mark一下, 之后贴出链接)
几种情况:
- T1获得了某行记录的共享锁进行读取记录,其他需要读取该记录的Tn,亦可获得共享锁进行读取。
- T1获得了某行记录的共享锁进行读取记录,T2需要获得排他锁修改该记录。T2需要等待T1释放共享锁之后,才能获得排他锁进行修改。
- T1获得了某行记录的排他锁进行修改记录,T2需要获得共享锁修改该记录。T2需要等待T1释放排他锁之后,才能获共享锁进行读取。
- Intention Locks 意向锁
意向锁是InnoDB用来实现各种粒度的锁之间共存的方案。它作用在表级别,表示事务
下一步将继续获取记录级别的排他锁,或共享锁。这样当其他操作需要取得表锁的时候,可以直接根据表上的意向锁来判断是否需要等待。
有两种意向锁:
- Intention Shared Lock共享意向锁
表示事务要获取记录级共享锁的意图。要获取共享锁时,先需要获取共享意向锁。
- Intention Exclusive Lock排他意向锁
表示事务要获取记录级排他锁的意图。要获取排他锁时,先需要获取排他意向锁。
表级别共享锁,排他锁,与共享意向锁和排他意向锁的兼容性情况:
由上图可见,意向锁和意向锁之间不会有冲突,因为作用在表级别,所以只有与表级别的共享或排他锁才会发生冲突。从而达到了记录锁与表锁能快速相互感知相互影响的目的。