写点什么

MySQL 原理与优化:原数据锁的应用

作者:崔皓
  • 2022 年 8 月 12 日
    湖北
  • 本文字数:900 字

    阅读完需:约 3 分钟


MySQL 中原数据锁是系统自动控制添加的,对于用户来说无需显示调用,当我们使用一张表的时候就会加上原数据锁。

原数据锁的作用是为了保护表原数据的一致性,如果在表上有活动事务的时候,不可以对元数据进行写入操作。也就是为了避免 DML 和 DDL 之间的冲突,保证读写的正确性。

说白了就是,在对数据表进行读写操作的时候,不能进行修改表结构的操作



如上图所示,在执行 select 操作的时候,MySQL 会自动加上 shared_read 锁,在 insert,update, delete 以及 select for update 操作的时候会加上 shared_write 锁,这两类锁是兼容的。

在执行 alter table 操作的时候,会加上 exclusive 锁,这个锁与 shared_read 和 shared_write 锁 是互斥的,换句话说在做查询和更新表数据的时候,是不能够修改表结构的。

来看个例子

首先开启事务,使用 select 语句会针对表加上 shared_read 的共享锁

begin;

select * from course;

此时查看原数据锁的信息

select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;



通过上图我们可以发现,course 表加上了 shared_read 锁。

接着,开启另外一个事务,记住刚才的事务不要 commit

begin;

update course set name = 'Jason' where id =2;



如上图所示,此时的 update 语句可以执行成功,并没有被阻塞。说明 select 和 update 是不冲突的,他们的锁是兼容的。

再次查看原数据锁

select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;



从上面的截图可以看出,此时原数据锁的表中记录了两条记录分别是针对 course 表的 shared_read 和 shared_write 锁,也刚好对应我们执行的 select 和 update 操作。

最后,我们再启动第三个客户端,并且启动 第三个事务,执行 alter 语句,在 course 表中加入一个字段 hello 如下 。

begin;

alter table course add column hello int;



由于之前的事务没有提交所以修改表的操作会被阻塞,因为 shared_read 以及 shared_write 这两个锁 与 exclusive 之间是互斥的,所以会阻塞

此时,回到最开始的两个客户端,对两个事务进行 commit 操作,再返回到第三个事务执行的 alter 语句出,发现语句顺利执行。



发布于: 刚刚阅读数: 3
用户头像

崔皓

关注

还未添加个人签名 2019.01.02 加入

还未添加个人简介

评论

发布
暂无评论
MySQL 原理与优化:原数据锁的应用_崔皓_InfoQ写作社区