Mysql技术内幕 Innodb阅读笔记第三篇

Posted by Xuan Peng on July 23, 2019

  • 锁机制用来管理对共享资源的并发访问,同时提供数据的完整性和一致性(表锁、页锁、行锁)

  • lock的适用对象是事务,用来锁定的是数据库中的表页行。并且一般lock的对象仅在事务commit或者rollback知乎进行释放。同时lock具有死锁检测机制。保护的是数据库的内容

  • latch适用对象是线程,是一种锁定时间非常短的锁,分为mutex和rwlock(互斥量和读写锁)。目的是用来保证并发线程操作临界资源的正确性。没有死锁检测机制。保护的是内存数据结构

  • 1563738383448

  • 两种标准的行级锁

    1. S lock 共享锁:允许事务读一行数据
    2. X lock:允许事务删除或者更行一行数据
  • 两个事务同时获得某一行的S lock,是可行的,称为锁兼容(lock compatible)

  • 读写锁并不只是针对行,行表都成

  • 1563738635387

  • 多粒度锁机制:允许事务在行级、表级上的锁同时存在。

  • 意向锁:将锁定的对象分为多个层次,意味着事务希望在更细的粒度加锁

  • 将上锁的对象看成一颗树,那么对最细粒度的叶子上锁之前,首先需要对粗粒度的对象上锁 1563739177926

    如果对粗粒度上锁导致等待,说明当前对象被其他锁锁定。举例来说,在对记录r加X锁之前,已经有事务对表1进行了S表锁。现在当前事务要对表1加上IX以为记录r上X锁。这时需要等待前一个事务释放锁

  • InnoDB的意向锁都是表级锁。支持的两种意向锁:

    1. 意向共享锁(IS lock):事务想要获得一张表某几行的共享锁
    2. 意向排他锁(IX lock):事务想要获得一张表中某几行的排他锁
  • 1563739560890

  • 意向锁就像是一个intermediary lock,在存在行级锁和表级锁的情况下,事务 T 想要对表 A 加 X 锁,就需要先检测是否有其它事务对表 A 或者表 A 中的任意一行加了锁,那么就需要对表 A 的每一行都检测一次,这是非常耗时的。所以意向锁大大提高了并发效率

  • 一致性非锁定读(consistent unlocking read): 1563739990809

    事务读取某一行,碰到排他锁,这时去读快照里的数据,并且不需要锁定读(没有事务要去修改快照数据)。快照数据是之前版本的数据,通过undo段来实现的。这是一种多版本并发控制MVCC

  • 自增长锁: 1563740742982

    1563740755003

  • 外键:InnoDB会自动对外键列添加索引,可以避免表锁。
    • 对于外键值的插入或者更新,会先尝试给父表加S锁。
  • 锁的算法:InnoDB有三种行锁的算法

    1. Record Lock:单个行记录上的锁
    2. Gap Lock:间隙锁,锁定一个范围,但不包含记录本上
    3. Next-Key Lock: 1+2,锁住范围+记录本身。
    • Record lock总是会去锁住索引记录。如果没有索引,则锁主键(主键本身就是一个索引)
  • 锁升级:将低粒度锁聚集,自动升级为高粒度的锁(如很多行锁聚集,则自动升级成页锁或者表锁)