5 Matching Annotations
  1. Apr 2025
    1. 死锁检测以及相应开销

      由于事务之间可能产生死锁,因此要么设置最大等待超时时间,要么设置死锁检测。

      死锁检测

      1. 维护等待图(Wait-for Graph)

      InnoDB 内部维护一个有向图,图中的节点表示事务(Transaction),边表示锁的等待关系。

      例如:事务A持有行X的锁,事务B请求行X的锁并被阻塞,则图中有一条边从B指向A(B→A,表示B在等待A释放锁)。

      当某个事务请求锁时,如果锁已被其他事务持有,InnoDB 会更新等待图,添加一条新的边。

      2. 检测环(Cycle)

      每次有事务请求锁失败(进入等待状态)时,InnoDB 会触发死锁检测。

      深度优先搜索(DFS):InnoDB 通过DFS遍历等待图,检查是否存在环。如果发现环,则判定为死锁。

      优化:为了减少性能开销,InnoDB 不会每次都全图遍历,而是从新加入的边出发,仅检查可能形成环的路径。

      3. 选择牺牲者(Victim)

      如果检测到死锁,InnoDB 会选择一个事务作为牺牲者(通常选择回滚成本更低的事务,例如修改数据量较小的事务),强制回滚该事务,并释放其持有的锁。

      回滚后,等待图中对应的边被移除,其他被阻塞的事务可以继续执行。

      死锁的开销

      问题

      因此由于事务的不断加入,图会变得越来越大,进行环检测是O(n)的操作,若n很大则cpu大量消耗。

      解决

      可以通过中间件对操作相同key的事务限流,这样事务虽然也在等待,但是没有增加死锁检测的负担。

    1. MySQL有哪些锁?

      1. 全局锁

      元数据锁

      2. 表级锁

      • 元数据锁
      • 插入意向锁
      • 自增锁

      3. 行级锁

      • 间隙锁
      • 行锁
  2. Dec 2022
  3. Aug 2022
    1. 事务B是当前读,必须要读最新版本,而且必须加锁,因此就被锁住了,必须等到事务C’释放这个锁,才能继续它的当前读。