暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mysql锁机制

xbaobao 2020-08-03
257

首先我们需要知道的一个大前提是:mysql的锁是由具体的存储引擎实现的,所以像mysql的MyISAM引擎和InnoDB引擎的锁实现机制是有区别的。


1.表级锁

表级锁每次锁定的是一张表

1)优点:实现逻辑简单,开销小;获取锁和释放锁的速度快;由于表级锁一次会将整个表锁定,所以能很好的避免死锁问题。

2)缺点:由于锁粒度最大,因此出现争用被锁定资源的概率也会最高,致使并发度十分低下。

3)表级锁类型:表共享锁、表排他锁、表意向共享锁、表意向排他锁

表意向共享锁(IS):事务在给一个数据行加行共享锁前(lock inshare mode),必须先取得该表的意向共享锁。

表意向排他锁(IX):事务在给一个数据行加行排他锁前(forupdate),必须先取得该表的意向排他锁IX锁。

表锁的兼容性:


表共享锁(S)

表排他锁(X)

表意向共享锁(IS)

表意向排他锁(IX)

表共享锁(S)

兼容

冲突

兼容

冲突

表排他锁(X)

冲突

冲突

冲突

冲突

表意向共享(IS)

兼容

冲突

兼容

兼容

表意向排他(IX)

冲突

冲突

兼容

兼容

 

 2.行级锁

行级锁每次锁定的是一行数据

1)优点:锁粒度小,争用率低,并发高。

2)缺点:实现复杂,开销大;加锁慢、容易出现死锁。 

3)行级锁类型

记录锁(Record Locks):只锁定索引项本身。

间隙锁(Gap Locks):锁定索引项中的间隔,或者第一条索引项之前的范围,又或者最后一条索引项之后的范围。

临键锁(Next-key Locks):是记录锁与间隙锁的组合,它的封锁范围,既包含索引项,又包含索引项区间。

注意:行锁锁定的是索引项不是返回的结果集中的记录。如下表中有两条记录,事务一结果集为空但任然锁住了id为9的数据,导致事务二锁等待。

表中数据:

事务一查询:

事务二查询:


3.MyISAM引擎中的锁

MyISAM引擎只支持表所,且只支持表共享锁、表排他锁,对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对 MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作。在执行查询语句前,会自动给涉及的所有表加读锁,在执行更新操作(update、delete、insert等)前,会自动给涉及的表加写锁。这个过程并不需要用户干预,因此不需要直接用locktable命令给MyISAM表显式加锁。


4.InnoDB引擎中的锁

InnoDB引擎除支持表级锁中表共享锁、表排他锁之外,增加了对行级锁的支持,而在锁定机制的实现过程中为了让行级锁定和表级锁定共存,InnoDB又增加了两个表级锁,即表意向共享锁、表意向排他锁。 


InnoDB行锁是通过给索引项加锁来实现的(如果走的是聚集索引则只给聚集索引加锁,如果走的是辅助索引则会给辅助索引和聚集索引都加上锁)。所以,只有通过索引条件检索数据,InnoDB才使用行级锁(不同的事务隔离级别会选择不同的行锁,如记录锁,临键锁等,否则,InnoDB将使用表锁。


即便在条件中使用了索引字段,但具体是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。

文章转载自xbaobao,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论