• 【1. MySQL锁机制】


    1.锁的种类

    • 根据加锁的范围,可以分为全局锁、表级锁和行锁三类。
      在这里插入图片描述

    全局锁

    • 全局锁主要应用于做全库逻辑备份。这样在备份数据库期间,不会因为数据或表结构的更新,而出现备份文件的数据与预期的不一样。

    • 缺点:

      • 整个数据库都是只读状态。 会造成业务停滞。
    • 解决办法

      • 如果数据库的引擎支持的事务支持可重复读的隔离级别,那么在备份数据库之前先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个 Read View,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。

    2.表级锁

    表锁

    • 针对数据库的表进行加锁。不会出现死锁,发生锁的冲突几率高,并发低。
    • MySQL表锁有俩个模式:表共享读锁和表独占写锁
    • 表级自增锁,当为表的某一列添加AUTO_INCREAMENT属性后,插入数据可以不指定该字段,系统会自动为它赋值。此时获取自增值是需要AUTO_INC锁锁定的
    • MyISANM不适合做写为主表的引擎,因为它是表锁,当锁住后,其他的线程不能做任何操作,从而大量更新会使得查询很难得到锁,最终导致永久阻塞。
    • InnoDB 牛逼的地方在于实现了颗粒度更细的行级锁。

    意向锁

    如果出现行锁的时候,想加表锁,那就只能进行全表遍历,看是否有加行锁。太浪费时间

    • 意向锁是则不需要进行遍历数据也可以直接判断是否可以给表加锁
      • 意向共享锁(IS锁):当事务给某行记录增加了S锁(共享锁),同时给表加一个IS锁
      • 意向独占锁(IX锁):当事务给某条记录增加X锁时(独占锁),同时给表加一个IX锁。
    • 意向锁是innodb自动加的,不用用户干预。

    意向共享锁和意向独占锁是表级锁,不会和行级的共享锁和独占锁发生冲突,>而且意向锁之间也不会发生冲突,只会和共享表锁(lock tables … read)和独占表锁(lock tables … write)发生冲突。

    3.行级锁

    行锁

    • innodb既支持行锁,也支持表锁
    • 行锁开销大,会出现死锁,发生冲突几率小,并发高
    • MySQL的行锁是通过索引加载的,锁住的永远是索引,而非记录本身,即使没有索引innodb会在后台创建一个聚簇索引,行锁就会锁住聚簇索引,但是如果一个SQL语句没有走任何索引,那么就会为它加上表锁,全表扫描。

    共享锁(读锁也叫S锁)/排他锁(写锁也叫X锁)

    • 共享锁(S锁):当一个事务给一条记录上共享锁后,其他的事务也可以对该事务上共享锁,但是该锁只是可以读,如果有事务想写,那么它就会阻塞,一直等待所有的锁释放。
    • 排他锁(X锁):当一个事务给记录上锁后,可以进行读写,其他的事务不能够上任何锁。

    记录锁

    • 记录锁,锁住的是一条记录。而且记录锁是有 S 锁和 X 锁之分的:

    间隙锁

    MySQL默认隔离级别可重复读,而可重读读只能解决脏读,不可重复读。解决不了幻读,但是不同的一点是MySQL通过俩种机制来解决幻读:一靠MVCC方案解决,二加锁方案解决。然而事务加锁时,记录是不存在的,是无法加行锁,则需要靠间隙锁。
    在这里插入图片描述

    • 例如给 id=8 记录加 gap 锁,锁住(4,8)区间。另一事务想插入 id=6 的记录,会先定位到 id=8 的记录,然后发现存在一个 gap 锁,则阻塞直到 第一个事务将 gap 锁释放掉,才可以在(4,8)区间插入记录
    • gap lock 仅仅是为了防止插入幻影记录,并不会限制其他事务对记录继续加行锁 或者 gap 锁

    临键锁

    • Next-Key Lock 称为临键锁,是 Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。

    插入意向锁

    • 一个事务在插入一条记录的时候,需要判断插入位置是否已被其他事务加了间隙锁(next-key lock 也包含间隙锁)。

    • 如果有的话,插入操作就会发生阻塞,直到拥有间隙锁的那个事务提交为止(释放间隙锁的时刻),在此期间会生成一个插入意向锁,表明有事务想在某个区间插入新记录,但是现在处于等待状态。

    • 插入意向锁名字虽然有意向锁,但是它并不是意向锁,它是一种特殊的间隙锁,属于行级别锁。

    乐观锁

    • 每次拿数据都默认别人不会修改,所以不会上锁,在更新的时候会判断一下在此期间别人有没有去更新这个数据。

    • 实现方式:乐观锁一般会使用版本号机制或CAS算法实现。

    • MVCC (Multiversion Concurrency Control),即多版本并发控制技术。

    • MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁

    总结

    • MVCC其本质就是看做是乐观锁的机制,而排他锁等则是悲观锁的实现。

    悲观锁

    • 每次拿数据时都认为别人会修改,所以每次那数据时都会上锁,别人拿数据时会阻塞直到拿到锁。
  • 相关阅读:
    聊聊redis分布式锁的8大坑
    【无标题】element select下拉框下拉选项位置不对,显示到旁边,不显示到下拉框底部
    克诺尔Knorr-Bremse EDI 对接流程
    vue之sourcemap
    JDK动态代理
    开开心心带你学习MySQL数据库之节尾篇
    为保护iPhone 13,iPad产量被砍50%,全球芯片短缺带来的影响超乎想象
    trace-bpfcc
    计算机视觉|针孔成像,相机内外参及相机标定,矫正的重要性
    编程英语生词笔记本
  • 原文地址:https://blog.csdn.net/weixin_45043334/article/details/127704550