MySQL 锁——全局锁、表级锁(表锁 元数据锁MDL 意向锁)、行锁

**锁是计算机协调多个进程或线程并发访问某一资源的机制。**在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供多用户共享的资源。如何保持数据并发的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
分类:

分类介绍
全局锁锁定数据库中的所用表
表级锁每次操作锁住整张表
行级锁每次操作锁住对应的行数据

一、全局锁

全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读的状态,后续的DML写的语句,DDL语句,已经更新的事务提交语句都将被阻塞。
其典型的使用场景是做全库的备份,对所用表进行锁定,从而获取一致性的视图,保证数据的完整性。

#加锁
flush tables with read lock;#做备份
mysqldump -uroot -p密码 数据库名>备份到的文件;mysqldump -uroot -p1234 itcast>itcast.sql
#解锁
unlock tables;

    
    

#演示
#加锁
在这里插入图片描述其中一个客户端加了全局锁,所以另一个客户端只读,更新会被阻塞。
#备份
在这里插入图片描述
#解锁
在这里插入图片描述

在这里一共用到了2个客户端,一个负责加锁解锁,另一个负责备份

数据库中加全局锁,是一个比较重的操作,存在以下问题:
1、如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆
2、如果在从库上备份,那么在备份期间不能执行主库同步过来的二进制日志(binlog),会导致主从延迟。

在InnoDB引擎中,我们可以在备份时加上参数--single-transaction 来完成不加锁的一致性数据备份。
在这里插入图片描述

二、表级锁

表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。
分类:
1、表锁
2、元数据锁(meta data lock,MDL)
3、意向锁

1、表锁

1)表共享读锁(read lock)#只能读
在这里插入图片描述可以看到,当加了读锁之后客户端都可以读,但是都不可以改。

2)表独占写锁(write lock)
在这里插入图片描述当加了写锁之后,加锁的那个客户端既可以读也可以写,但是其他客户端都不能进行读写。

语法

#加锁
lock tables 表名... read/write
#释放锁
unlock tables /客户端连接关闭

    
    

    **

    总结:读锁不会阻塞其他客户端的读,但是会阻塞写。写锁既会阻塞其他客户的读,又会阻塞其他客户端的写。

    **

    2、元数据锁(meta data lock,MDL)

    MDL加锁的过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上。MDL锁的主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作。
    为了避免DML和DDL冲突,保证数据读写的正确性。

    在MySQL5.5中引入MDL,当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作的时候,加MDL写锁(排他)。

    演示:
    case1:当对一张表增删改查
    在这里插入图片描述
    case2:当修改表结构时
    在这里插入图片描述查看元数据锁:select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;

    3、意向锁

    为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。(提高性能)

    描述
    引入意向锁之前:假设线程A对开启一个事务,并对某行进行更新,此时系统会为这行添加表锁。同时线程B要对这个表添加表锁,系统要依次检查表中是否有行锁。效率很低。
    引入意向锁之后:假设线程A对开启一个事务,并对某行进行更新,此时系统会为这行添加表锁,与此同时也会为这个表加一个意向锁。同时线程B要对这个表添加表锁,系统只需检查这个意向锁与表锁是否兼容即可。大大提高了效率。

    1)意向共享锁(IS):由语句select…lock in share mode添加 。与表锁的共享锁兼容,排他锁互斥。
    在这里插入图片描述

    2)意向排他锁(IX):由insert、update、delete、select…for update添加。

    tipsinsert、update、delete这三个操作系统自动为其添加排他锁

    与表锁共享锁和排他锁都互斥。
    意向锁之间不会互斥

    在这里插入图片描述
    查看意向锁:select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;

    在这里插入图片描述

    补充

    三、行锁

    行级锁,每次操作锁住对应的行数据。锁的粒度最细,发生锁冲突的概率最低,并发度最高。应用与InnoDB引擎中。

    InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对行数据(记录)加锁。

    行级锁主要分为以下三类

    1、行锁(Record Lock)

    锁住单个记录的锁,防止其他事务对此进行delete和update操作,在RC、RR隔离级别下都支持

    在这里插入图片描述

    InnoDB实现了以下两种行锁

    共享锁(S)

    允许一个事务去读取一行,阻止其他事务获得相同数据集的排他锁

    防止不可重复读,因为当事务对数据加上共享锁后,其他事务就只能对该数据进行读操作,不能进行修改操作,因此也就避免了不可重复读的问题(不可重复读:前后两次读取的结果不一样)

    排他锁(X)

    允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁

    在这里插入图片描述

    sql语句行锁类型说明
    insert、update、delete排他锁自动加锁
    select不加任何锁
    select … lock in share mode共享锁需要在select之后加上lock in share mode
    select … for update排他锁需要在select之后加上for update

    默认情况下,InnoDB在默认的隔离级别REPEATABLE-READ(可重复的),InnoDB使用next - key锁进行搜索和索引扫描,以防止幻读
    1、针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将自动转换成行锁
    2、InnoDB的行锁是针对索引加的锁,若不通过索引条件来检索数据,那么InnoDB将对表中所有记录加锁,此时行锁升级成表锁

    2、间隙锁(Gap Lock)

    锁住索引记录间隙(不包含该记录),确保索引间隙不变,防止其他事务在这个间隙间insert,从而产生幻读。RR隔离级别下都支持
    在这里插入图片描述

    间隙锁的目的:防止其他事务在间隙中插入数据,以免造成幻读

    间隙锁可以共存,一个事务使用间隙锁不会阻止另一个事务在同一个间隙上使用间隙锁

    临键锁(Next-Key Lock)

    行锁和间隙锁的组合,同时锁住记录并锁住记录前面的间隙。RR隔离级别下都支持

    在这里插入图片描述

    1、在唯一索引上的等值查询,给不存在的记录加锁时,则优化成间隙锁
    2、在普通索引上的等值查询,向右遍历时最后一个值不满足查询要求时,临键锁将退化成间隙锁

    以上图为例:
    前提条件:age是一个普通索引;查询条件为 where age = 18
    那么18 和 29 记录及前后的间隙加上间隙锁,防止其他事务插入数据

    非唯一索引,索引列值相同时按照主键排序

    3、唯一索引上的范围查询——会访问到不满足条件的第一个值为止

    示例

    如下表
    在这里插入图片描述

    当执行

    select * from stu where age>=19 lock in share mode;
    

    时索引使用情况
    在这里插入图片描述

    会锁住19这条记录、19和25这两条记录之间的间隙及25往后所有记录和间隙

    • 1
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值