0
点赞
收藏
分享

微信扫一扫

MySQL 原理与优化:意向锁,IS,IX

MySQL 原理与优化:意向锁,IS,IX_互斥

先来看一种应用场景,当有两个线程 A和B 分别访问一张表。

线程 A :针对表中的一条语句进行update 操作,假设根据记录的id 更新记录,此时开启的事务会对这条记录加行锁。

线程 B:如果需要进行锁表的操作,例如:lock tables [table_name] read/write,也就是对表加上读写锁。在加表锁之前需要检查行记录是否加锁,如果有加锁就需要等待锁释放以后再进行表锁的后续操作。此时检查行锁的操作,就需要从表的第一行向下逐一进行,直到最后一行记录。

大家知道对表进行扫描操作的效率是非常低的,此时就引入了意向锁。

意向锁就是避免DML在执行时,加的行锁和表锁发生冲突而引入的,使得表锁不用加茶妹行数据是否加锁,使用意向锁来减少表锁的检查。

如上图所示,在引入意向锁之后按照这个步骤进行加锁

  1. 线程A 对表中的某条记录加行锁。
  2. 同时对表加上意向锁。
  3. 当线程 B 对表加表锁的时候,发现线程A 加的意向锁,会将表锁与意向锁进行对比。如果两锁互斥:等待意向锁释放执行表锁的操作,如果两锁不互斥:就执行表锁的操作。

按照这个执行步骤,线程B 就不用去对整张表进行全表扫描了。

意向锁分为两类:

意向共享锁:IS,select ... lock in share mode

意向排他锁:IX,insert 、update、delete、select ... for update

从上面的语句可以看出意向共享锁主要对应查询操作,意向排他锁对应更新操作。

意向锁与表锁的互斥情况:

意向共享锁:与表共享锁(read)兼容,与表锁排他锁(write)互斥。

意向排他锁:与表共享锁(read)以及排他锁(write)都互斥。意向锁之间不会互斥。

意向锁对记录进行读操作的时候,表锁可以加读锁,也就是其他的线程可以读表,但是不能写表。当意向锁对记录进行写入操作的时候,表锁线程不能对表的数据进行读和写的操作,需要等到意向排他锁对应的事务提交以后才能,进行后续操作。

下面来看两个例子

第一个例子

开启线程,通过在sql 语句后面加上 lock in share mode,表示对表加上意向共享锁

begin;

select * from course where id =2 lock in share mode;

通过sql 语句查询意向锁的情况

select object_schema, object_name ,index_name, lock_type ,lock_mode, lock_data from performance_schema.data_locks;


MySQL 原理与优化:意向锁,IS,IX_互斥_02

从上图可以看到select 语句在record(行)上加了共享锁(read),在table(表)上加了IS 共享锁。

打开另外一个客户端执行如下语句

lock tables course read;


MySQL 原理与优化:意向锁,IS,IX_意向锁_03


上图可见,此时加锁是成功的说明意向共享锁和表共享锁(read)是兼容的。

接着加上表的互斥锁write

lock tables course write;

发现光标闪动,说明线程阻塞了。因为意向共享锁和表排他锁(write)是互斥的

回到第一个事务,将其commit;

commit;

此时 回到第二个客户端,看到lock tables course write; 语句得以顺利执行。


MySQL 原理与优化:意向锁,IS,IX_意向锁_04


第二个例子

开启一个事务

begin;

update course set name = 'Json' where id =3;

通过sql 语句查询意向锁的情况

select object_schema, object_name ,index_name, lock_type ,lock_mode, lock_data from performance_schema.data_locks;


MySQL 原理与优化:意向锁,IS,IX_互斥_05


从查询结果来看,针对表course ,update 语句在行锁上面加了一个排他锁,在表的级别加上了一个意向排他锁。

此时切换到第二个客户端,执行锁表的操作,执行表共享锁(read)

lock tables course read;

由于表共享锁与意向排他锁有互斥,因此lock 语句光标停留不动,线程阻塞。

接着通过unlock tables;释放掉这个 read lock

unlock tables;

然后尝试加上表互斥锁(write)

lock tables course write;

由于表互斥锁与意向排他锁有互斥,因此lock 语句光标停留不动,线程阻塞。

举报

相关推荐

mysql 表锁/行锁/意向锁

mysql的意向锁

0 条评论