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;

五、总结

  • 概述:锁机制用于解决并发访问中的一致性和有效性问题。
  • 全局锁:锁住整个数据库实例,性能较差,但在数据备份时非常有用。
  • 表级锁:锁住整张表,适合批量操作,但冲突多。包括表锁、元数据锁和意向锁。
  • 行级锁:锁住单行数据,减少冲突,提高并发性。包括行锁、间隙锁和临键锁。
posted @ 2024-10-18 19:26  Abufan  阅读(38)  评论(0)    收藏  举报