死锁的发生必须具备以下四个必要条件。
1) 互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待, 直至占有资源的进程用毕释放。
2) 请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3) 不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4) 环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的 P0 正在等待一个 P1 占用的资源;P1正在等待 P2 占用的资源,……,Pn 正在等待已被 P0 占用的资源。
理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。
只要打破四个必要条件之一就能有效预防死锁的发生。

  • 打破互斥条件:改造独占性资源为虚拟资源,大部分资源已无法改造。
  • 打破不可抢占条件:当一进程占有一独占性资源后又申请一独占性资源而无法满足,则退出原占有的资源。
  • 打破占有且申请条件:采用资源预先分配策略,即进程运行前申请全部资源, 满足则运行,不然就等待,这样就不会占有且申请。
  • 打破循环等待条件:实现资源有序分配策略,对所有设备实现分类编号,所有进程只能采用按序号递增的形式申请资源。

避免死锁常见的算法有有序资源分配法、银行家算法。

MySQL查看死锁

  • 使用show processlist命令查找正在运行的进程。
  • 使用kill ID命令杀死该进程。

    死锁排查

    MySQL提供了几个与锁有关的参数和命令,可以辅助我们优化锁操作,减少死锁发生。

    查看死锁日志

    通过show engine innodb status\G命令查看近期死锁日志信息。
    使用方法:1、查看近期死锁日志信息;2、使用explain查看下SQL执行计划

    查看锁状态变量

    通过show status like’innodb_row_lock%命令检查状态变量,分析系统中的行锁的争夺情况

  • Innodb_row_lock_current_waits:当前正在等待锁的数量

  • Innodb_row_lock_time:从系统启动到现在锁定总时间长度
  • Innodb_row_lock_time_avg: 每次等待锁的平均时间
  • Innodb_row_lock_time_max:从系统启动到现在等待最长的一次锁的时间
  • Innodb_row_lock_waits:系统启动后到现在总共等待的次数

如果等待次数高,而且每次等待时间长,需要分析系统中为什么会有如此多的等待,然后着手定制优化。