> 文章列表 > MySQL全局锁、表级锁、行级锁介绍演示(详细)

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

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