MST

星途 面试题库

面试题:MySQL死锁的产生原因及检测与解决机制

在MySQL数据库运行过程中,死锁是一个常见但棘手的问题。请深入分析死锁产生的原因,描述MySQL内部是如何检测死锁的,以及一旦检测到死锁,MySQL采取什么机制来解决死锁问题,同时说明开发人员在代码层面可以采取哪些预防措施。
37.2万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

死锁产生原因

  1. 资源竞争:多个事务同时竞争有限的资源,例如多个事务试图同时获取同一行数据的锁,且获取锁的顺序不一致。
  2. 事务操作顺序:不同事务对资源的访问顺序不同,形成循环等待的情况。例如事务A获取了资源X的锁,事务B获取了资源Y的锁,然后事务A试图获取资源Y的锁,事务B试图获取资源X的锁,从而导致死锁。

MySQL内部死锁检测

  1. 等待图(Wait-for Graph):MySQL通过维护一个等待图来检测死锁。在等待图中,节点代表事务,边表示事务之间的等待关系。当一个事务请求锁时,如果该锁已经被其他事务持有,MySQL会在等待图中添加一条从当前事务到持有锁事务的边。
  2. 周期性检测:MySQL会定期检查等待图是否存在环。如果存在环,就意味着发生了死锁。

MySQL解决死锁机制

  1. 选择牺牲者:一旦检测到死锁,MySQL会选择一个事务作为牺牲者(Victim),通常选择回滚代价最小的事务。回滚代价可以通过事务已执行的操作数、已获取的锁数等因素来衡量。
  2. 回滚牺牲者事务:MySQL将牺牲者事务回滚,释放该事务持有的所有锁,使得其他事务能够继续执行。

开发人员预防措施

  1. 优化事务逻辑:尽量减少事务的执行时间和资源占用,将大事务拆分成小事务,降低死锁发生的概率。
  2. 按相同顺序访问资源:确保多个事务以相同的顺序访问资源,避免形成循环等待。例如,所有事务都先获取资源A的锁,再获取资源B的锁。
  3. 降低锁的粒度:尽量使用行级锁而非表级锁,减少锁冲突的范围。
  4. 合理设置事务隔离级别:根据业务需求选择合适的事务隔离级别,不同隔离级别对锁的使用和死锁的发生概率有影响。例如,READ COMMITTED隔离级别相对REPEATABLE READ隔离级别,锁的使用可能更宽松,死锁概率可能降低。
  5. 设置合理的锁等待超时时间:通过设置innodb_lock_wait_timeout参数,控制事务等待锁的最长时间,避免无限期等待。如果等待时间超过该值,事务会自动回滚,防止死锁长时间占用资源。