一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情
上篇讲到根据锁定资源粒度的表级锁,今天继续
1.意向锁
意向锁是MySQL引擎默认的加锁(表级别),在获取行锁时(共享锁或排它锁)要先获取其表的意向锁,举个例子假设当前有事务一,给test_index表的某条记录加上行锁写锁,那么MySQL引擎会默认给这个表加上ix表级意向锁,那么其他事务想要获取其表的写锁就得获取其表级写锁意向锁,如果获取不到那么事务阻塞。下面举个例子。
新开事务一,对表加行锁写锁执行SQL:select * from test_index where id =1;且事务不提交,
新开事务二,对表加表级别读锁,执行:select * from test_index for update;执行结果如下:
根据上图现象可以发现事务二阻塞,原因就是因为事务一加了行锁写锁且MySQL引擎默认加上了ix表级写锁意向锁,所以事务二想要获取test_index表级别的写锁是需要先获取其意向锁,但是此时意向锁被事务一占领,此时事务二阻塞, 加意向锁的原因就是加快加锁的速度,如果没有意向锁,那么事务二此时想要对表test_index加表锁写锁需要对每条记录都去遍历判断当前记录是否加锁,效率较低,但是有表级意向锁之后只需要判断意向锁即可,无需在遍历全表。
2.autu自增锁
auto自增主键,想必大家肯定都用过,自增锁其实比较好理解,对于自增需要保证数据的id增长是连续且单调递增的,所以自增锁是表级别的锁。
3.元数据锁
元数据锁是MySQL5.5之后引入的简称MDL(meta data lock),元数据锁目的就是为了保证表数据的正确性、完整性,比如我开启一个事务去查询表test_index且不提交事务,此时开启事务二去删除表的某个字段,那么此时事务二就会出现阻塞的现象,这是因为在执行select、update、insert、delete语句时MySQL会默认给事务加上,MDL读锁,在对表结构作出修改时会默认加上MDL写锁,由于读、写锁之间是互斥的所以会造成事务二的阻塞直到事务等待时间达到锁超时时间。具体例子如下:
事务一执行:select * from test_index;:
事务二执行:alter table test_index drop test_add;