
了解并掌握MySQL的加锁语句,对于数据库管理员和开发人员来说至关重要
本文将详细介绍MySQL中的加锁语句,包括全局锁、表级锁和行级锁的使用方法和场景
一、全局锁 全局锁是对整个数据库实例加锁,加锁后整个实例处于只读状态,后续的DML(数据操纵语言)写语句、DDL(数据定义语言)语句以及更新操作的事务提交语句都将被阻塞
全局锁主要用于全量备份时,保证表与表之间的数据一致性
语法: sql FLUSH TABLES WITH READ LOCK; 使用全局读锁锁定所有数据库的所有表后,会阻塞其他所有DML以及DDL操作,从而避免备份过程中的数据不一致
备份完成后,使用`UNLOCK TABLES`来解锁
但需要注意的是,`FLUSH TABLES`属于比较重的操作,对于InnoDB引擎的表,可以使用`--single-transaction`参数来完成不加锁的一致性备份
bash mysqldump --single-transaction -uroot -p test >1.sql 二、表级锁 表级锁是对整个表加锁,粒度较粗,并发能力相对较低,因此在InnoDB引擎中很少使用
表级锁分为表锁、元数据锁(MDL)、意向共享锁(IS锁)和意向排他锁(IX锁)
1. 表锁 表锁分为共享锁和排他锁
-共享锁(S锁):允许其他会话读取表,但不允许修改
-排他锁(X锁):完全独占表,不允许其他会话读取或修改
语法: sql LOCK TABLES 表名 READ/WRITE; UNLOCK TABLES; 示例: sql -- 加共享读锁 LOCK TABLES t5 READ; -- 此时可以执行SELECT,但不能执行INSERT/UPDATE/DELETE -- 加排他写锁 LOCK TABLES t5 WRITE; -- 可以执行任何操作 UNLOCK TABLES; 2. 元数据锁(MDL) 元数据锁主要是为了避免DML与DDL冲突
DML的元数据锁之间不互斥,但DDL的元数据锁与DML的元数据锁互斥
加元数据锁的情况: -`LOCK TABLES READ/WRITE`:类型为`SHARED_READ_ONLY`和`SHARED_NO_READ_WRITE`
-`ALTER TABLE`:类型为`EXCLUSIVE`,与其他MDL都互斥
-`SELECT`、`SELECT ... LOCK IN SHARE MODE`:类型为`SHARED_READ`
-`INSERT`、`UPDATE`、`DELETE`、`SELECT ... FOR UPDATE`:类型为`SHARED_WRITE`
查看元数据锁(适用于MySQL 8.0以上版本): sql SELECT object_type, object_schema, object_name, lock_type, lock_duration FROM performance_schema.metadata_locks; 3. 意向共享锁(IS锁)与意向排他锁(IX锁) 意向锁主要是避免DML与表锁冲突
DML主要目的是加行锁,为了让表锁不用检查每行数据是否加锁,加意向锁(表级)来减少表锁的判断
意向锁之间不会互斥
加意向锁的情况: -`SELECT ... LOCK IN SHARE MODE`:会加IS锁
-`INSERT`、`UPDATE`、`DELETE`、`SELECT ... FOR UPDATE`:会加IX锁
示例: sql -- 给表加上IX(意向排他锁) SELECTFROM table FOR UPDATE; 查看意向表锁(适用于MySQL 8.0以上版本): sql SELECT object_schema, object_name, index_name, lock_type, lock_mode, lock_data FROM performance_schema.data_locks; 三、行级锁 行级锁是MySQL中最重要的锁之一,粒度细,并发能力强
InnoDB存储引擎支持行级锁
行级锁主要分为记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-Key Lock)
1. 记录锁(Record Lock) 记录锁只在一条记录上加锁
示例: sql -- 加排他记录锁 BEGIN; SELECT - FROM t5 WHERE id = 5 FOR UPDATE; -- 自动先获取表的IX锁,再获取行的X锁 2. 间隙锁(Gap Lock) 间隙锁锁定某一个范围,不包含记录本身,主要用于防止幻读
示例: sql -- 加间隙锁 BEGIN; SELECT - FROM t5 WHERE id > 3 AND id <7 FOR UPDATE; -- 会话2中insert操作会被阻塞 INSERT INTO t5 VALUES(2,2,2); --阻塞 UPDATE t5 SET d = d +1 WHERE id =5; --阻塞 3. 临键锁(Next-Key Lock) 临键锁是记录锁和间隙锁的组合,包含记录本身,左开右闭
InnoDB的默认锁机制
示例: sql -- 加临键锁 BEGIN; SELECT - FROM t5 WHERE id <= 20 FOR UPDATE; --锁定范围:(-∞,0】,(0,5】,(5,10】,(10,20】 UPDATE t5 SET d = d +1 WHERE id =0; --阻塞 UPDATE t5 SET d = d +1 WHERE id =20; --阻塞 UPDATE t5 SET d = d +1 WHERE id =25; -- 正常执行 INSERT INTO t5 VALUES(2,2,2); --阻塞 加锁原则与优化: -原则1:加锁的基本单位是next-key lock,前开后闭区间
-原则2:查找过程中访问到的对象才会加锁
-优化1:索引上的等值查询,给唯一索引加锁时,next-key lock退化为行锁
-优化2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件时,next-key lock退化为间隙锁
-范围查询时的优化:在正序查询时,如果查询条件满足优化1,依旧会退化成行锁;但在倒序查询时,不会采用优化1
在范围查询时,如果有不涉及的行,那么最后一个next-ke
MySQL优化技巧:如何有效关闭间隙锁以提升性能
MySQL加锁语句实用指南
MySQL分页查询TOP数据技巧
MySQL库存数据空格换行处理技巧
MySQL值约束设置全攻略
MySQL数据库:如何轻松修改外键约束,提升数据完整性管理
MySQL实验4详解与答案揭秘
MySQL优化技巧:如何有效关闭间隙锁以提升性能
MySQL分页查询TOP数据技巧
MySQL库存数据空格换行处理技巧
MySQL值约束设置全攻略
MySQL数据库:如何轻松修改外键约束,提升数据完整性管理
MySQL实验4详解与答案揭秘
MySQL安装:如何设置并发连接数
Java获取MySQL插入ID技巧解析
多程序并发读取MySQL数据库技巧
MySQL开发初级教程:入门必备指南
MySQL删除操作失败?排查与解决方案大揭秘
MySQL本质探秘:数据库核心机制解析