[2025.1.28 MySQL学习] 锁

全局锁

  • 全局锁就是对整个数据库实例加锁,加锁后处于只读状态,DML写语句、DDL语句、已经更新的事务提交语句都会被阻塞,典型使用场景时全库的逻辑备份
  • 加全局锁:flush tables with read lock;
  • 数据备份:mysqldump -uroot -p1234 itcast>itcast.sql
  • 解锁:unlock tables;
  • 存在以下问题:
    • 主库上备份,备份期间不能执行更新,业务需要停摆
    • 从库上备份,备份期间不能执行主库同步的二进制文件,导致主从延迟
  • InnoDB引擎中,可以在备份时加上参数--single-transaction来完成不加锁的一致性数据备份






表级锁

  • 每次操作锁住整张表,发生锁冲突的概率最高,并发度最低
  • 分为以下三类:
    • 表锁
      • 表共享读锁(read lock)
      • 表独占写锁(write lock)
    • 元数据锁
      • MDL加锁是系统自动控制,无需显式使用,在访问一张表时候会自动加上。MDL锁主要作用是维护表元数据的唯一性,在表上有活动事务时候,不可以对元数据进行写入操作
      • 主要作用是避免DML和DDL的冲突,保证读写正确性,如图1
      • 查看元数据锁:select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata.locks;
    • 意向锁
      • 为了避免DML在执行时,加的行锁和表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查,个人理解算一种本质是行锁的一种表锁
      • 意向共享锁(IS):与表锁共享锁read兼容,与表锁排它锁write互斥
      • 意向排它锁(IX):与表锁共享锁read以及排它锁write都互斥,意向锁之间不会互斥

图1

image







行级锁

  • 每次操作锁对应行数据,发生锁冲突概率最低,并发度最高
  • InnoDB的数据是基于索引组织的,行锁通过对索引上的索引项加锁实现,而不是对记录加的锁
  • 主要分为以下三类:
    • 行锁:锁定单个行记录的锁,防止其他事务对此进行update和delete。在在事务的read committed和repeatable read隔离级别下都支持
    • 间隙锁:锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读,在repeatable read隔离级别下支持
      image
    • 临键锁:行锁和间隙锁组合,同时锁住数据和数据前面的gap,在repeatable read隔离级别下支持
  • 默认情况下,InnoDB在repeatable read事务级别隔离运行,InnoDB使用next-key临键锁进行搜索和索引扫描,以防止幻读(默认下RR无法解决幻读,通过加锁进行解决,降低并行化)

行锁(两种类型)

  • 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁
  • 排他锁(X):允许获取排它锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排它锁

image

  • 针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁
  • InnoDB的行锁是针对索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中所有记录加锁,此时就会升级为表锁

间隙锁

  • 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁
  • 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询时,next-key锁退化为间隙锁
  • 索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止
posted @   Luna-Evelyn  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示