博客
关于我
MySQL有哪些锁
阅读量:789 次
发布时间:2023-02-12

本文共 2187 字,大约阅读时间需要 7 分钟。

MySQL 的锁机制是数据库管理中至关重要的一部分,它不仅保证了数据的一致性,还显著提升了数据库的并发性能。根据锁的粒度和用途,MySQL 提供了多种锁类型,每种锁类型都有其独特的作用范围、适用存储引擎以及适用的场景。以下是MySQL 锁的详细分类和应用场景分析。

1. 全局锁(Global Lock)

全局锁会锁住整个数据库,阻止所有写入(DML)操作,通常用于全库一致性备份。全局锁的作用范围是整个数据库,适用于所有存储引擎,但在高并发环境中并不适用。

获取全局锁

通过执行以下命令可以获取全局锁:

FLUSH TABLES WITH READ LOCK;

此时,只允许读操作,阻止写入。全局锁适用于 MyISAM 和 InnoDB,但不适合高并发环境。

全局锁的缺点

  • 所有写操作都会被阻塞,影响业务连续性。
  • 客户端异常断开会导致锁释放,可能影响备份操作。

2. 表级锁(Table Lock)

表级锁作用于整个表,适用于 MyISAM 和 InnoDB,但 InnoDB 默认使用行锁。

表级锁的主要类型

  • 共享锁(READ 锁,S 锁)

    • 允许多个事务同时读取数据,但不能写入。
    • 适用于报表查询和只读操作。
    LOCK TABLES users READ;
  • 排他锁(WRITE 锁,X 锁)

    • 只允许当前事务读取和修改数据,其他事务不能访问。
    • 适用于批量更新和数据迁移。
    LOCK TABLES users WRITE;
  • 表级锁的优缺点

    • 优势:适合大批量数据操作,锁开销小。
    • 缺点:并发性能差,所有事务必须等锁释放后才能继续。

    3. 行级锁(Row Lock)

    行级锁作用于具体的行,是 InnoDB 的默认锁机制,特别适用于高并发环境。

    行级锁的主要类型

  • 共享锁(S 锁,LOCK IN SHARE MODE)

    • 允许多个事务读取同一行,但不能写入。
    SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;
  • 排他锁(X 锁,FOR UPDATE)

    • 只允许当前事务读取和修改数据,其他事务不能访问该行。
    SELECT * FROM users WHERE id = 1 FOR UPDATE;
  • 行级锁的特点

    • 优势:适合高并发事务,不影响其他行的数据操作。
    • 缺点:需要索引支持,否则会升级为表锁;可能发生死锁,事务管理不当时会相互等待锁释放。

    4. 意向锁(Intent Lock)

    意向锁是一种表级锁,用于优化行锁的管理,避免表锁与行锁的冲突。

    意向锁的主要类型

  • 意向共享锁(IS 锁):事务想要获取行级共享锁,先加 IS 锁。
  • 意向排他锁(IX 锁):事务想要获取行级排他锁,先加 IX 锁。
  • 意向锁的示例

    SELECT * FROM users WHERE id = 1 FOR UPDATE;

    意向锁能够提升行锁管理效率,防止表锁和行锁的冲突。

    5. 间隙锁(Gap Lock)

    间隙锁锁住一个范围,防止数据插入,避免幻读。

    间隙锁的作用

    间隙锁锁住 20 ≤ age ≤ 30 之间的范围,防止新数据插入。

    间隙锁的示例

    SELECT * FROM users WHERE age BETWEEN 20 AND 30 FOR UPDATE;

    间隙锁能够防止幻读,但会影响插入操作,可能导致死锁。

    6. Next-Key 锁

    Next-Key Lock = 行锁 + 间隙锁,用于 REPEATABLE READ 级别,防止幻读。

    Next-Key 锁的示例

    如果索引有 (5,10,15):

    • id=10 加行锁。
    • id=5~10 加间隙锁,防止 id=7 被插入。

    Next-Key 锁能够避免幻读问题,但在 READ COMMITTED 级别不会生效,影响并发性能。

    7. MDL(元数据锁,Metadata Lock)

    MDL 锁保护表结构,防止 DDL(ALTER、DROP)与 DML(INSERT、SELECT)冲突。

    MDL 锁的作用

    MDL 锁防止数据不一致,DDL 操作必须等待 DML 释放锁。

    MDL 锁的示例

    SELECT * FROM users;  -- 自动加 MDL 读锁ALTER TABLE users ADD COLUMN age INT;  -- MDL 写锁,阻塞

    MDL 锁能够防止数据不一致,但可能导致 DDL 阻塞,影响系统可用性。

    8. 死锁问题与解决方案

    死锁产生的原因

    • 多个事务持有锁,并相互等待对方释放锁。
    • 不同事务以不同顺序加锁,导致循环等待。

    死锁解决方案

  • 加锁顺序统一:所有事务按照相同的顺序加锁。
  • 短事务优先:尽量减少事务持锁时间。
  • 降低锁范围:使用行锁替代表锁。
  • 死锁检测:InnoDB 默认会自动检测死锁,并回滚一个事务。
  • 9. 总结

    锁类型 作用范围 适用场景 优点 缺点
    全局锁 整库 备份 一致性高 并发性能差
    表锁 整表 批量操作 低开销 影响并发
    行锁 具体行 高并发事务 高并发 可能死锁
    间隙锁 行间隙 防止幻读 保证一致性 降低并发
    Next-Key 行+间隙 RR 事务 防止幻读 性能较低
    MDL 表结构 DDL 操作 防止冲突 可能阻塞

    MySQL 锁的选择需要根据业务场景和并发需求灵活调整,以保证数据一致性和高性能。

    转载地址:http://mndfk.baihongyu.com/

    你可能感兴趣的文章
    Mysql学习总结(6)——MySql之ALTER命令用法详细解读
    查看>>
    Mysql学习总结(70)——MySQL 优化实施方案
    查看>>
    Mysql学习总结(71)——MySQL 重复记录查询与删除总结
    查看>>
    Mysql学习总结(73)——MySQL 查询A表存在B表不存在的数据SQL总结
    查看>>
    Mysql学习总结(77)——温故Mysql数据库开发核心原则与规范
    查看>>
    Mysql学习总结(78)——MySQL各版本差异整理
    查看>>
    Mysql学习总结(79)——MySQL常用函数总结
    查看>>
    Mysql学习总结(7)——MySql索引原理与使用大全
    查看>>
    Mysql学习总结(80)——统计数据库的总记录数和库中各个表的数据量
    查看>>
    Mysql学习总结(81)——为什么MySQL不推荐使用uuid或者雪花id作为主键?
    查看>>
    Mysql学习总结(82)——MySQL逻辑删除与数据库唯一性约束如何解决?
    查看>>
    Mysql学习总结(83)——常用的几种分布式锁:ZK分布式锁、Redis分布式锁、数据库分布式锁、基于JDK的分布式锁方案对比总结
    查看>>
    Mysql学习总结(84)—— Mysql的主从复制延迟问题总结
    查看>>
    Mysql学习总结(85)——开发人员最应该明白的数据库设计原则
    查看>>
    MySQL学习笔记十七:复制特性
    查看>>
    mysql安装卡在最后一步解决方案(附带万能安装方案)
    查看>>
    mysql安装和启动命令小结
    查看>>
    MySQL安装配置教程(非常详细),从零基础入门到精通,看完这一篇就够了
    查看>>
    mysql安装配置简介
    查看>>
    MySQL定义和变量赋值
    查看>>