欢迎光临
我们一直在努力

MySQL 中有哪些锁类型?

MySQL 中有哪些锁类型

InnoDB锁可以按粒度、兼容性、实现、意向锁几个维度划分,面试重点:行锁、表锁、意向锁、间隙锁、临键锁、MDL元数据锁。

一、按锁粒度划分

1. 表级锁:锁住整张表

  • 表共享读锁(S锁)
    lock table xxx read,多个事务可以同时加读锁;有读锁时,其他事务不能写。
  • 表排他写锁(X锁)
    lock table xxx write,只有一个事务持有,其他事务读写都阻塞。
  • MyISAM默认使用表锁;InnoDB一般不会手动用表锁,粒度大,并发差。

    2. 行级锁(InnoDB特有,只锁行记录)

    只锁被操作的数据行,并发高。

    • 行共享读锁 S(共享锁):select … lock in share mode
      多个事务可以同时加S锁;如果有S锁,其他事务不能加X锁做修改。
    • 行排他写锁 X(排他锁):update / delete / select … for update
      当前事务独占,其他事务不能加S、X锁,读写阻塞。

    行锁只有走索引才会生效;如果没用到索引,InnoDB会退化成表锁。

    意向锁(意向共享IS、意向排他IX)

    意向锁是表级锁,InnoDB自动加,不需要手动操作。

    • 意向共享 IS:事务准备给表中某些行加S锁,先给表加IS
    • 意向排他 IX:事务准备给表中某些行加X锁,先给表加IX

    作用:快速判断表锁和行锁之间是否冲突,避免遍历每一行锁做判断。

    意向锁之间互相兼容;意向锁和普通S/X表锁互斥。

    二、RR可重复读隔离级别特有:解决幻读

    1. 间隙锁 Gap Lock

    锁住索引记录之间的间隙,不锁记录本身,防止其他事务在间隙插入新数据。
    只存在于RR隔离级别;RC隔离级别没有间隙锁。

    2. 临键锁 Next‑Key Lock

    行锁 + 间隙锁的组合,InnoDB RR默认加的锁。
    左开右闭区间,锁住当前记录,同时锁住前面的间隙,防止插入,以此解决幻读。
    当查询命中唯一索引等值匹配,临键锁会退化为普通行锁。

    三、MDL 元数据锁(Metadata Lock)

    表结构锁,5.6之后引入,访问表自动获取。

    • MDL读锁:增删改查DML,加MDL读锁,多个事务共享。
    • MDL写锁:alter table 修改表结构DDL,加MDL写锁,排他。

    经典坑:长事务持有MDL读锁,此时执行alter table会被阻塞,后续所有DML全部堵塞,库雪崩。

    锁兼容矩阵

    锁类型SXISIX
    S 兼容 互斥 兼容 互斥
    X 互斥 互斥 互斥 互斥
    IS 兼容 互斥 兼容 兼容
    IX 互斥 互斥 兼容 兼容

    补充区分:乐观锁 & 悲观锁

  • 悲观锁:认为一定会发生冲突,操作直接上锁。InnoDB的S、X、临键锁都属于悲观锁。
  • 乐观锁:不加数据库锁,业务实现,依靠版本号version或者时间戳,更新时判断版本。
  • update table set val=?,version=version+1 where id=? and version=old_version

    面试高频小结

  • RC隔离级别:只有行锁,没有间隙锁、临键锁,幻读靠业务控制;
  • RR隔离级别:默认临键锁,等值命中唯一索引退化成行锁;
  • 行锁失效条件:索引失效,升级为表锁;
  • MDL锁坑点:长事务阻塞DDL,引发大量等待;
  • 意向锁是InnoDB内部表锁,不需要手动干预。
  • 总结:
    粒度上分表锁、行锁、意向锁;RR下有间隙锁、临键锁;还有MDL元数据锁;思想上分悲观锁、乐观锁。RC没有间隙锁,RR靠临键锁解决幻读。

    赞(0)
    未经允许不得转载:171主机测评 » MySQL 中有哪些锁类型?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址