MySQL中的锁
MySQL中的锁
一、概述
在数据库高并发场景下,锁机制是保证数据一致性和有效性的重要手段。MySQL中的锁根据操作粒度和使用场景可分为多种类型,以确保在不同应用中实现良好的性能和一致性。
二、分类
- 全局锁 (Global Lock) :锁住整个数据库实例,通常在备份或维护时使用。
- 表级锁 (Table Lock) :对整张表进行加锁,常用于 MyISAM 引擎,或对元数据进行保护。
- 行级锁 (Row Lock) :锁住特定的数据行,Innodb引擎支持这种锁,提高并发性。
三、共享锁和排他锁
-
共享锁 (S锁):允许多个事务同时获取共享锁,适用于读取操作。
-
排他锁 (X锁):只能被一个事务持有,适用于写操作,避免其他事务访问。
-
锁冲突情况:
- S与S:不冲突
- X与X:冲突
- S与X:冲突
-
使用示例:
SELECT * FROM orders LOCK IN SHARE MODE; -- 加S锁,用于读取
SELECT * FROM orders FOR UPDATE; -- 加X锁,用于更新操作
-
MyISAM 和 InnoDB 引擎:
- MyISAM:仅支持表级锁。
- InnoDB:支持行级锁和表级锁,但更常用行锁以提高并发性。
-
表锁的示例:
LOCK TABLES orders READ; -- 读锁(S锁)
LOCK TABLES orders WRITE; -- 写锁(X锁)
注意:一般情况下,不建议手动使用表锁,而是利用行锁来减少冲突。
- DDL操作与元数据锁 (MDL):
DDL语句如 ALTER TABLE 需要加元数据锁(MDL),锁住整个表以防止其他读写操作。
四、锁的粒度
MySQL中的锁按照操作粒度可以分为:
- 全局锁
- 表级锁
- 行级锁
1. 全局锁
- 描述:锁住整个数据库实例,使所有表处于只读状态。
- 应用场景:主要用于数据备份,避免备份时数据发生变更。
- 示例:
FLUSH TABLES WITH READ LOCK; -- 加全局读锁
2. 表级锁
- 锁住整张表,适用于MyISAM引擎。InnoDB也会在某些特殊场景使用表锁。
- 表锁、元数据锁、意向锁是表级锁的主要类型。
2.1 表锁
- 描述:每次操作会锁住整张表,适用于简单操作和表结构变更。
- 特点:粒度大,冲突多,适合批量操作和维护。
2.2 元数据锁 (MDL)
- 描述:用于DDL操作,防止表结构变更时的数据不一致。
- 示例:
ALTER TABLE employees ADD COLUMN age INT;
2.3 意向锁 (Intent Lock)
- 描述:表级别的意向声明,用于表明事务打算在某些行上加锁。
- 类型:
- IS (Intent Shared):事务打算加S锁。
- IX (Intent Exclusive):事务打算加X锁。
3. 行级锁
- 描述:锁住数据表中的特定行,常用于InnoDB引擎。
- 特点:粒度最小,提高并发性,冲突少。
3.1 行锁 (Record Lock)
- 描述:针对行记录的锁,主要用于精确定位的行数据。
- 示例:
SELECT * FROM employees WHERE id = 1 FOR UPDATE;
3.2 间隙锁 (Gap Lock)
- 描述:锁住某一范围内不存在的记录,避免幻读。
- 示例:
SELECT * FROM employees WHERE id > 100 FOR UPDATE;
3.3 临键锁 (Next-Key Lock)
- 描述:结合行锁和间隙锁,锁住一个行及其附近的间隙,避免并发插入。
- 示例:
SELECT * FROM employees WHERE id BETWEEN 100 AND 200 FOR UPDATE;
五、总结
- 概述:锁机制用于解决并发访问中的一致性和有效性问题。
- 全局锁:锁住整个数据库实例,性能较差,但在数据备份时非常有用。
- 表级锁:锁住整张表,适合批量操作,但冲突多。包括表锁、元数据锁和意向锁。
- 行级锁:锁住单行数据,减少冲突,提高并发性。包括行锁、间隙锁和临键锁。
浙公网安备 33010602011771号