1

锁的算法

Record Lock:单个行记录上的锁

  • 通过主键索引,锁定单行
  • read committed隔离级别下采用。

Geo Lock:间隙锁,锁定一个范围但不包含本身

  • 可以防止多个多个事务将记录插入到同一个范围内(Phantom Problem)
  • 对于唯一键值对的锁定,GeoLock会降级为Record Lock。

Next-Key Lock:Geo Lock+Record Lock,锁定一个范围并锁定记录本身

  • 在同一事务下,连续执行两次sql语句可能导致不同的结果。第二次的sql可能会返回之前不存在的行
  • 例如,假设表里有id为1,2,5三条记录,对于select * from table where id >2 for update语句,Next-Key Lock锁定的不止是5这一行,而是[2,+∞]。
  • repeatable read隔离级别采用

数据问题

Dirty Read(脏读问题)

  • 一个事务中读到了另一个事务中未提交的数据,违反了数据库隔离性,隔离级别read uncommitted

Phantom Problem(幻读问题)

  • 在同一事务下,连续执行两次sql语句可能导致不同的结果。第二次的sql可能会返回之前不存在的行。
  • repeatable read隔离级别下,Innodb采用Next-Key Lock对查询区域进行枷锁解决幻读问题。

不可重复读

  • 一个事务中读到了另一个事务中未提交的数据,违反了数据库一致性
  • 一般情况下,读到的都是已提交的数据,很多厂商默认隔离级别就是read committed。
  • MYSQL官方文档将不可重复读定义为Phantom Problem(幻读),通过Next-Key Lock来解决幻读问题。
  • Next-Key Lock不仅锁住了扫描到的索引,同时锁住了索引的覆盖范围。

丢失更新

  • T1事务提交的更新操作被T2事务的更新覆盖掉。
  • 物理丢失更新不会出现,因为T2事务的操作会被T1阻塞。
  • 逻辑丢失可能会出现:所有操作添加X排他锁,数据库串行化

阻塞

  • T2事务需要等待T1事务释放资源后再进行资源占有。

死锁

  • 两个或以上的事务因争夺资源造成的互相等待现象。
  • 解决方案:

    1. 超时回滚:当超时的事务所占权重较大或事务更新了较多行,undolog较大时回滚所用时间较长。
    2. wait-for graph(等待图) 死锁检测方式:

      • 等待图存储了锁的信息链表和事务等待链表,通过深度优先搜索进行递归排查。
      • 查到后选择undolog较小的事务进行回滚。

锁升级

  • 如果数据库设计者认为锁是一种稀缺资源,则会出现1000个行锁升级为页锁,页锁升级为表锁现象。
  • Innodb没有锁升级。因为每个事务都是对页进行管理,且采用的是位图存储的方式。锁开销较小。

nothingnodust
16 声望2 粉丝

代码界的蔡徐坤