博客
关于我
MySQL笔记:InnoDB的锁机制
阅读量:788 次
发布时间:2023-02-13

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

为什么需要 MySQL 锁?

在并发场景下,锁是一种保证线程安全的方式。对于 MySQL 数据库,尤其是在并发环境下,当多个事务同时操作同一数据时,可能会出现脏读、不可重复读、幻读等事务并发问题。为了解决这些问题,MySQL 采用了不同的锁机制来确保数据的一致性和有效性。

MySQL 的默认事务隔离级别是可重复读(RR),在这个隔离级别下,读操作依靠快照读(基于 MVCC 实现)和当前读(加锁实现)来避免并发问题,而写操作则通过加锁的方式来避免冲突。因此,MySQL 需要锁来防止事务并发问题,保证数据的安全性和一致性。


InnoDB 锁机制

InnoDB 是 MySQL 的默认存储引擎,支持行级锁和表级锁。以下是 InnoDB 的锁机制详细解析。

查看事务加锁情况

要查看事务加锁情况,可以通过以下方式操作:

  • 关闭自动提交:

    SET @@autocommit = 0;

    查看当前状态:

    SELECT @@autocommit;
  • 每次操作前使用 begin;start transaction; 开启事务,执行后使用 commit; 手动提交事务。

  • 使用以下命令查看加锁情况:

    SELECT * FROM performance_schema.data_locks;

    关注字段:

    • OBJECT_NAME:被锁的表名。
    • INDEX_NAME:对应的锁索引名。
    • LOCK_TYPE:锁类型(表级锁或行级锁)。
    • LOCK_MODE:锁模式(如 S 锁或 X 锁)。
    • LOCK_STATUS:锁状态(GRANTED 或 WAITING)。
    • LOCK_DATA:锁的相关数据(如索引值)。

  • 行级锁

    InnoDB 的行级锁分为共享锁(S 锁)和排他锁(X 锁)。根据锁模式进一步划分为记录锁、间隙锁和临键锁。

    共享锁与排他锁

    • 共享锁(S 锁):用于读取记录,允许其他事务获取共享锁,但不允许其他事务获取排他锁。常通过 SELECT ... lock in share mode; 实现。例如:

      SELECT * FROM products WHERE id = 1 lock in share mode;
    • 排他锁(X 锁):用于修改记录,阻止其他事务的读或写操作。常通过 SELECT ... for update;UPDATEDELETE 等语句实现。例如:

      SELECT * FROM products WHERE id = 1 for update;UPDATE products SET stock = 99 WHERE id = 1;

    记录锁、间隙锁和临键锁

    在可重复读(RR)隔离级别下,为了防止幻读,InnoDB 使用记录锁、间隙锁和临键锁。

  • 记录锁:锁住一条记录,常用于主键等值查询且记录存在的情况。

    例如:

    SELECT * FROM products WHERE id = 1 for update;

    查看锁情况:

    SELECT * FROM performance_schema.data_locks;
  • 间隙锁:锁住一个区间,常用于主键等值查询且记录不存在的情况。

    例如:

    SELECT * FROM products WHERE id = 3 for update;

    查看锁情况:

    SELECT * FROM performance_schema.data_locks;
  • 临键锁:由记录锁和间隙锁组成,锁住一个左开右闭区间,常用于普通索引等值查询且记录存在的情况。

    例如:

    SELECT * FROM products WHERE price = 799.99 for update;

    查看锁情况:

    SELECT * FROM performance_schema.data_locks;
  • 锁兼容关系

    • 共享锁与共享锁兼容。
    • 共享锁与排他锁不兼容。
    • 排他锁与排他锁兼容。

  • 表级锁

    InnoDB 也支持表级锁,常用于全表操作:

  • 共享型表锁(S 表锁):允许其他事务读取表中的数据,但不允许修改。

    LOCK TABLES products READ;
  • 排他型表锁(X 表锁):阻止其他事务对表进行读或写操作。

    LOCK TABLES products WRITE;
  • 意向锁:用于加快判断表中记录是否被锁。

    • 共享型意向锁(IS 锁):用于加共享锁。
    • 排他型意向锁(IX 锁):用于加排他锁。
    SHOW VARIABLES LIKE 'innodb_%lock_mode%';

  • 自增锁

    自增锁用于主键自增功能,确保并发插入时的数据一致性。

    CREATE TABLE products (    id INT AUTO_INCREMENT PRIMARY KEY);

    总结

    通过以上锁机制,InnoDB 保证了事务的安全性和数据的一致性。在实际应用中,应根据业务需求合理选择锁类型,避免全表扫描等性能问题。

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

    你可能感兴趣的文章
    MySQL底层概述—8.JOIN排序索引优化
    查看>>
    MySQL底层概述—9.ACID与事务
    查看>>
    Mysql建立中英文全文索引(mysql5.7以上)
    查看>>
    MySQL开源工具推荐,有了它我卸了珍藏多年Nactive!
    查看>>
    Mysql当前列的值等于上一行的值累加前一列的值
    查看>>
    MySQL当查询的时候有多个结果,但需要返回一条的情况用GROUP_CONCAT拼接
    查看>>
    MySQL必知必会(组合Where子句,Not和In操作符)
    查看>>
    MySQL必知必会总结笔记
    查看>>
    MySQL快速入门
    查看>>
    MySQL快速入门——库的操作
    查看>>
    mysql快速复制一张表的内容,并添加新内容到另一张表中
    查看>>
    mysql快速查询表的结构和注释,字段等信息
    查看>>
    mysql怎么删除临时表里的数据_MySQL中关于临时表的一些基本使用方法
    查看>>
    mysql性能优化
    查看>>
    MySQL性能优化必备25条
    查看>>
    Mysql性能优化(1):SQL的执行过程
    查看>>
    Mysql性能优化(2):数据库索引
    查看>>
    Mysql性能优化(3):分析执行计划
    查看>>
    Mysql性能优化(4):优化的注意事项
    查看>>
    Mysql性能优化(6):读写分离
    查看>>