MySQL全局锁、表级锁、行级锁介绍&演示(详细)

目录

介绍

分类

1、全局锁

1.1介绍

1.2场景

1.3语法

1.4演示

2、表级锁

2.1介绍

2.2分类

2.3语法

2.4演示

3、行级锁

3.1介绍

3.2分类

3.3场景


介绍

        锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)等争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。

分类

        MySQL中的锁按照粒度可以分为以下三类:

        1、全局锁:锁定数据库中所有表;

        2、表级锁:每次操作锁住整张表;

        3、行级锁:每次操作锁住对应的行数据;

1、全局锁

1.1介绍

        全局锁就是对整个数据库实例加锁,加锁后整个数据库实例处于只读状态,提交的写入、更新、删除操作语句都会被阻塞。

        最典型的使用场景就是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

1.2场景

        假如数据库中有三张表,分别是商品库存表、订单表、订单记录表,如果对数据库直接进行备份,当商品库存表备份完成继续执行后续备份时,有客户下单会使三张表数据都进行改变,导致备份的商品库存表是该客户下单前的数据,订单表和订单记录表时该客户下单后的数据,此时备份完成的数据就不完整,不一致。

1.3语法

        实现加全局锁进行逻辑备份主要分为以下步骤:

        1、flush tables with read lock; 加全局锁;

        2、mysqldump -u账户 -p密码 数据库名 > 备份sql文件路径 进行备份;

        3、unlock tables; 释放全局锁;

1.4演示

连接数据库:我使用的本地数据库,如测试远程数据库可使用 mysql -h IP地址 -u 账号 -p 密码 连接;

加全局锁:所有数据库表全部锁住;

测试读写语句:此时数据库处于只读状态,更新、写入、删除语句都被不生效;

备份:因为该命令不是sql命令,所以需要退出mysql直接在命令窗口执行即可;

释放锁:

2、表级锁

2.1介绍

        表级锁,每次操作锁住整张表,锁粒度最大,发生锁冲突的概率最高,并发最低,

2.2分类

        对于表级锁,主要分为以下三类:

        1.表锁;对于表锁可以分为两类:

                1.1表共享读锁:加锁后只能读数据,不能更新、写入、删除数据,并且其他客户端访问也只能读数据,不能更新、写入、删除数据;

                1.2表独占写锁:加锁后可以读、更新、写入、删除数据,但其他客户端访问不能读、更新、写入、删除数据;

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

        说明:元数据其实就是表的结构,元数据锁就是用来保证表结构的一致性,比如当某张表上有未提交的事务时,系统会自动加锁,该期间不能改变表的结构。

        在MySQL5.5中引入了元数据锁,当对一张表进行增删改查的时候,自动加MDL读锁,当对表的结构进行变更操作的时候,自动加MDL写锁。

        3.意向锁:为了避免DML语句执行时,加的行锁与表锁冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否有行锁,使用意向锁来减少表锁的检查。意向锁可分为两类:

                3.1意向共享锁(IS):与表锁共享读锁兼容,与表锁独占写锁互斥;

                3.2意向排他锁(IX):与表锁共享读锁和表锁独占写锁都互斥;意向锁之间不会互斥;

        说明:线程A开启事务,执行更新语句更新第五行数据,于是第五行数据会加上行锁,此时线程B进来准备对该表加表锁,线程B加表锁前会检查该表每行数据是否有行锁及类型,于是就会从第一行挨个检查,这个时候检查的效率就会极低。当引入了意向锁之后就会变成这样的情况,线程A开启事务,执行更新语句更新第五行数据,于是第五行数据会加上行锁同时对该表加上意向锁,此时线程B进来准备对该表加表锁,此时检查的是该表是否有意向锁而不是每行检查行锁,发现意向锁之后线程B被阻塞,知道线程A提交事务结束线程B继续执行任务。

2.3语法

表锁        

        加锁:lock tables 表名... read/write;

        释放锁:unlock tables/客户端断开连接;

2.4演示

表共享读锁:客户端1进行加锁,加锁后客户端1只能读数据,不能操作数据,客户端2只能读数据,操作数据会被阻塞,直到客户端1释放锁,客户端2的操作数据语句才会继续执行;

 表独占写锁:客户端1加锁后,可以进行读写数据操作,客户端2的读写操作都会被阻塞,直到客户端1将锁释放才会继续执行;

元数据库锁:在客户端1开始事务,执行查询语句且不提交事务,然后在客户端2中修改表结构会被阻塞,直到客户端1提交事务后,客户端2的修改表结构语句才会继续执行。

意向共享锁:select语句需手动加上 lock in share mode 才会加上行锁和意向共享锁;

意向排他锁:update、delete、insert语句执行时会自动加行锁和意向排他锁;

3、行级锁

3.1介绍

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

3.2分类

        InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。行级锁主要分为以下三类:

        1.行锁:锁定单个行记录的锁,防止其他事务对此进行update和delete,在RC、RR隔离级别下都支持;行锁分为以下两类:

                1.1共享锁(S):允许一个事务去读一行,阻止其他事务获取相同数据的排他锁(共享锁与共享锁兼容,共享锁与排他锁互斥);

                1.2排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获取相同数据的共享锁和排它锁(排他锁与共享锁互斥,排他锁与排他锁互斥);

        2.间隙锁:锁定索引记录间隙,不包含记录,确保索引记录间隙不变,防止其他事务在这个间隙进行insert,在RR隔离级别下支持;

        3.临键锁:行锁和间隙锁的组合,同时锁住数据和数据前面的所有间隙,在RR隔离级别下支持;

3.3场景

行锁

InnoDB的行锁是针对索引加的锁,当不通过索引条件操作数据时,那么InnoDB会将表中所有记录加锁,此时就会升级为表锁;

SQL 行锁类型 说明
INSERT... 排他锁 自动加锁
UPDATE... 排他锁 自动加锁
DELETE... 排他锁 自动加锁
SELECT... 不加任何锁
SELECT... LOCK IN SHAR MODE 共享锁 需手动在SELECT后加LOCK IN SHAR MODE
SELECT... FOR UPDATE 排他锁 需手动在SELECT后加FOR UPDATE

猜你喜欢

转载自blog.csdn.net/weixin_45151960/article/details/130149226