MySQL 锁全集(共享锁/排它锁、记录锁/间隙锁/临键锁)

简介:锁是计算机协调多个进程或线程并发访问某一资源变得有序的机制。

一、锁分类

  1. 行级锁/表级锁/页面锁

    A. 行级锁:是指给索引上的索引项加锁,偏向InnoDB存储引擎;

    B. 表级锁:是指给全表加锁,这个是由于没有使用索引导致的,偏向MyISAM存储引擎;

    C. 页面锁:开销和加锁时间界于表锁和行锁之间;

  2. 共享锁/排它锁

    A. 共享锁(S锁):也称读锁,指可以同时读数据,即允许持锁事务读取一行,事务A持有S锁,事务B请求S锁时,会立即被赋予,若请求X锁,需等待释放S锁才可以拿;

    B. 排它锁(X锁):也称写锁,指只允许一个事务拿到锁,即允许持锁事务更新或删除一行,事务A持有X锁,事务B请求S、X锁时,需等待释放X锁才可以拿;

  3. 意向共享锁/意向排它锁

    A. 意向锁(Intention Locks):表明一个事务稍后要获取表中某一行的共享锁或排它锁;

    B. 意向共享锁(IS):事务打算给数据行加共享锁时,那么事务在给一个数据行加S锁前必须先取得该表的IS锁;

    C. 意向排它锁(IX):事务打算给数据行加排它锁时,那么事务在给一个数据行加X锁前必须先取得该表的IX锁;

    D. 意向锁是由存储引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享锁或排它锁之前,InnoDB会先获取该数据行所在的数据表对应的意向锁;

   4. 自增锁:指事务插入自增列(ID)的时候需要的锁,一个事务正在插入记录,其他事务插入记录需要等待释放自增锁;

   5. 悲观锁/乐观锁。

 

二、行级锁/表级锁

  1. 行级锁

    A. 特点

      MySQL的行级锁是通过索引加载,如果sql没有走索引,则会全表扫描,那么对应加表级锁;

      行锁开销大,加锁慢,会出现死锁,但发生锁冲突几率低,并发高;

    B. 分类:共享锁和排它锁;

    C. 行锁升级为表锁:如果没有使用索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果就跟加表锁一样;

  2. 表级锁

    A. 特点 

      MYISAM引擎只支持表锁,当sql执行时自动加上,InnoDB也支持表锁,是在没有使用索引的时候,就会自动加表锁;

      表锁开销小,加锁快,不会出现死锁,但发生锁冲突几率高,并发低;

    B. 分类:意向锁和自增锁。

 

三、共享锁/排它锁

  1. 共享锁(Shared Locks)

    A. 特点:允许读读可以并行,但是不能做到写读、读写和写写并行;

    B. 加锁方式:lock in share mode,如:select * from user where id = 1 lock in share mode;

  2. 排它锁(Exclusive Locks)

    A. 加锁方式:for update,如:select * from user where id = 1 for update;

    B. 分类:记录锁、间隙锁和临键锁;

    C. 对于insert、update、delete语句,InnoDB会自动给数据集加排它锁,而对于普通select语句,InnoDB不会加任何锁。

 

四、记录锁/间隙锁/临键锁

  1. 记录锁(Record Locks)

    A. 仅仅锁住索引记录的一行,也叫行锁;

    b. 锁住的永远是索引记录而非记录本身。

  2. 间隙锁(Gap Locks)

    A. 定义:是没有匹配记录,锁住索引记录中的间隙,或者第一条索引记录之前的范围,又或者最后一条索引记录之后的范围,是锁住一个索引区间(左开右闭);

        间隙锁会封锁该条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据,这是为了防止出现幻读现象。

    B. 特点:间隙锁只在事务隔离级别RR下才有,一方面是防止产生幻读的问题,另一方面是为了满足恢复和复制的需要;

    C. 产生条件:使用普通索引锁定、使用多列唯一索引、使用唯一索引锁定多行记录;

      唯一索引只有锁住多条记录或者一条不存在的记录的时候,才会产生间隙锁,指定给某条存在的记录加锁的时候,只会加记录锁,不会产生间隙锁;

      普通索引不管是锁住单条,还是多条记录,都会产生间隙锁。

    D. 查看锁:show variables like 'innodb_locks_unsafe_for_binlog',默认值为OFF,即启用间隙锁。

   3. 临键锁(Next-key Locks)

    A. 定义:是匹配到了记录,指锁住索引记录和索引间隙,是innodb引擎默认的加锁方式;

    B. 是记录锁和间隙锁的组合;

    C. 使用在不同的场景会演变成不同的锁类型(记录锁还是间隙锁)。

 

五、插入意向锁(Insert Intention Locks)

  1. 是一种间隙锁,而非意向锁,在insert操作时产生,属于行锁

  2. 他不会阻止任何锁,对于插入的记录会持有一个记录锁。

 

六、锁相关

  1. 查看当前运行的所有事务:select * from information_schema.innodb_trx;

    A. 删除相应进程:kill trx_mysql_thread_id;

  2. 查看正在锁的事务:select * from information_schema.innodb_locks;

  3. 查看等待锁的事务:select * from information_schema.innodb_lock_waits;

 

八、死锁

  可参考:【mysql】死锁-产生原因和解决方法

 

可参考:MySQL锁总结

    Mysql锁详解(行锁、表锁、意向锁、Gap锁、插入意向锁)

    mysql数据库相关原理图

posted @   如幻行云  阅读(596)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示