07 - Lock
07 - 锁
锁是计算机协调多个线程或进程并发访问某一资源的机制...
共享数据的访问...锁冲突是一个数据库并发访问性能的重要因素
分类:
全局锁:锁定所有表
表级锁:锁住整张表
行级锁:锁住行数据
1. 全局锁
整个数据库实例加锁,处于只读状态,后续的 DML 和 DDL 语句都被阻塞...
1.1. 用法
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES; 或者断开加锁 session 的连接,全局锁也会自动释放
1.2. 应用
全局的逻辑备份,获取一致性视图,保证数据的完整性...
只能进行 DQL 语句
mysqldump -u用户名 -p密码 数据库名 > 备份文件路径.sql
1.3. 特点
全局锁是一个比较重的操作
如果在主库上备份,备份期间不能更新,业务停摆
如果在从库备份,备份期间从库不能执行主库同步过来的二进制日志,导致主从延迟
在 InnoDB中可以备份时加上 --single-transaction 参数来完成不加锁的一致性备份操作
2. 表级锁
每次锁住整张表,锁定颗粒度最大,发生所冲突概率最大,并发度最低。
分类:
表锁
元数据锁(meta data lock,MDL)
意向锁
2.1. 表级锁
表共享读锁 read lock
表独占写锁 write lock
语法
加锁 lock tables 表名 read/write
释放锁 unlock tables / 客户端断开连接
不会阻塞读 但是会阻塞写
2.2. 实例
读锁
其他线程可以读取表
t_student
,但不能写入。本线程可以读取表
t_student
,但不能写入。
写锁
其他线程不能读取或写入表
t_student
。本线程可以读取和写入表
t_student
。
知识点
表级锁锁定粒度大,加锁快,但并发度低;行级锁锁定粒度小,并发度高,但加锁开销大
适合对整张表进行批量操作的场景,或者需要避免死锁的复杂事务
在使用 InnoDB 引擎时,尽量避免使用表锁
因为表锁的颗粒度太大,会影响并发性能
而 InnoDB 引擎支持更细粒度的行级锁
2.3. 元数据锁
MDL 是系统自动控制的,无需显示使用,在访问一张表会自动加上...
未来避免DML和DDL冲突...
对一张表增删改查 加MDL读锁 共享...
对表结构变更时候 加MDL写锁 排他
保护表结构:防止在事务执行期间对表结构进行修改(如
ALTER TABLEDROP TABLE
等)。协调 DDL 和 DML 操作:确保 DDL 操作(如修改表结构)和 DML 操作(如查询、插入、更新、删除数据)能够并发执行,同时避免冲突。
维护数据一致性:通过锁定元数据,确保在事务执行期间,表的结构不会被其他事务修改。
What?
元数据锁是 MySQL 用于保护表结构和状态的一种锁机制,确保在事务执行期间,表结构不会被其他并发操作修改
Type
MDL 锁主要有共享锁(S Lock)和排他锁(X Lock)。共享锁允许多个事务同时读取表的元数据,但不允许修改;排他锁只允许一个事务对表的元数据进行写入
Why?
MDL 锁用于保护表结构,防止在事务执行期间对表结构进行修改,从而避免数据不一致和其他潜在冲突
性能瓶颈
在高并发环境下,MDL 锁可能会导致性能瓶颈,特别是当长事务持有锁时。此外,MDL 锁可能会导致锁等待,但通常不会导致死锁
2.4. 意向锁
如果先加了行锁,不能加表锁?
表锁不用检查每行数据是否加锁...
意向共享锁 Shared Lock
与表锁共享锁 read 兼容,与表锁排他锁 互斥
共享锁是一种允许多个事务同时访问同一资源的锁。它的主要特点是允许多个事务并发读取数据,但不允许写入
意向排他锁 Exclusive Lock
与表锁共享锁 read 和 排他锁都互斥...
排他锁是一种只允许一个事务访问资源的锁。它的主要特点是独占资源,不允许其他事务读取或写入数据。
共享锁允许多个事务同时读取表的元数据,但不允许修改
排他锁只允许一个事务对表的元数据进行写入
兼容情况
共享锁与共享锁兼容:多个事务可以同时持有共享锁,读取数据。
共享锁与排他锁不兼容:如果一个事务持有共享锁,另一个事务不能获取排他锁。
排他锁与共享锁不兼容:如果一个事务持有排他锁,其他事务不能获取共享锁或排他锁。
排他锁与排他锁不兼容:同一时间只有一个事务可以持有排他锁。
只有共享锁和共享锁能兼容...
3. 行级锁
每次操作锁住对于行,锁定力度最小,发生锁冲突的概率最低...并发度最高
InnoDB 的数据是基于索引组织的,行锁是通过索引上的索引项加锁来实现的,而不是对记录加锁,对于行级锁主要分三类:
行锁 Record Lock 防止其他事务对此进行 update 和 delete RC RR 隔离级别支持
间隙锁 Gap Lock 锁定间隙,防止在间隙进行 insert 产生幻读... RR隔离级别支持
临键锁 Next-Key Lock 行锁和间隙锁组合,同时锁住数据和 Gap...RR 隔离级别支持
3.1. Type
共享锁
允许一个事务去读一行
阻止其他事务获得相同数据集的排他锁
排他锁
允许排他锁的事务更新,阻止其他的事务获得共享锁和排他锁...
SQL
Type
Comment
INSERT
排他
自动
UPDATE
排他
自动
DELETE
排他
自动
SELECT
不加
SELECT LOCK IN SHARED LOCK
共享
手动
SELECT FOR UPDATE
排他
手动
InnoDB默认在 REPEATABLE READ 隔离级别,不能阻止幻读...
查看加锁情况...
InnoDB
如果在加行锁的过程中没有能够按照索引来执行,那么行锁会升级为表锁...也就是其他的行操作会被阻塞...
3.2. 间隙锁/临键锁
默认情况,在 RR 隔离界别允许,InnoDB用Next-Key锁进行搜索和索引扫描,以防止幻读
索引上等值查询 唯一索引,给不存在的记录加锁,优化为间隙锁
索引上等值查询 普通索引,向右遍历时最后一个值不满足查询需求,临键锁退化为间隙锁
范围查询 唯一索引,访问到不满足条件的第一个值为止
间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。
Last updated