InnoDB 中的锁问题和死锁

100 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

一、行锁算法

  1. Record Lock 单个行记录上的锁
  • Record Lock 一般会锁住索引记录,若有需要 InnoDB 储存引擎会使用主键来进行锁定。
  1. Gap Lock 间隙锁
  • Gap Lock 会锁定一个范围,但不包含记录本身。
  1. Next-Key Lock Record Lock + Gap Lock
  • Next-Key Lock 既会锁定一个范围,也锁定记录本身。
  • Next-Key Lock 技术称为 Next-Key Locking。该设计是为了解决 Phantom Problem
  • Phantom Problem (幻像问题):是指在同一事务下,连续执行两次同样的 SQL 语句可能导致不同的结果,第二次的 SQL 语句可能返回之前不存在的行。

二、锁问题

  1. 脏读
  • 我们可以先理解脏数据和脏页的概念。
  • 脏数据:是指事务对缓存池进行中的记录进行修改,而且页没有进行提交(commit)。
  • 脏页:是指在缓存池中已经被修改的页,而且也没有刷新到磁盘中。即内存中的页数据与磁盘中的页数据不一致。对于脏页不但不会影响到最终的数据一致性,还可以提高性能。
  • 脏读:是指一个事务读到了另外一个事务中未提交的数据,这当然就违反了数据库的事务之间的隔离性。
  1. 不可重复读
  • 是指在一个事务内多次读取一个数据集合。在一个事务还没有结束事务时,另外一个事务页访问了该数据集合,并进行了 DML 操作。第一个事务第一次读取数据时获取一个数值,在次之间第二个事务也对该数据集和修改和提交,当第一个事务再次读取该数据集合时就会出现与第一次读取的数据不一致的情况。
  • 不可重复读归类为 Phantom Problem,但不可重复读的问题是可以接受的。
  1. 丢失更新
  • 是指一个事务的更新操作会被另外一个事务的更新操作覆盖而导致数据不一致。
  • 但在当前数据库不会发生这种状况,只是可能会出现在计算机系统坏境中。

三、死锁

  • 死锁是指两个或者两个以上的事务在执行的过程中,因争夺锁资源而造成一种互相等待的现象。主要解决方法有:
  • 超时。在两个事务等待时,当一个事务等待时间超过设置的阈值时进行回滚,而另外一个事务就会继续执行。
  • 等待图 waiting-for graph。采用更为主动的锁检测方式(等待图)进行死锁检测。这也是 InnoDB 储存引擎使用的方式。