美文网首页
死锁的分析与解决

死锁的分析与解决

作者: 旦暮何枯 | 来源:发表于2019-04-04 17:16 被阅读0次

    死锁

    两个或者两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象。

    死锁产生的必要条件

    互斥

    • 并发执行的事务为了进行必要的隔离保证执行正确,在事务结束前,需要对修改的数据库记录持锁,保证多个事务对相同数据库记录串行修改。

    串行修改:a 事务尚未提交,b 事务不能修改同个数据记录

    • 对于大型并发系统无法避免

    请求与保持

    • 已经持有一个锁资源,等待另外一个锁资源
    • 死锁仅发生在请求两个或两个以上的锁对象
    • 由于应用需要,难以消除

    不剥夺

    • 已经获得锁资源的事务,在未执行前,不能被强制剥夺,只能使用完时,由事务自己释放。
    • 一般用于已经出现死锁时,通过破坏该条件达到解除死锁的目的。
    • 数据库系统通常通过一定的死锁检测机制发现死锁,强制回滚代价相对较小的事务,达到解除死锁的目的。

    环路等待

    • 发生死锁时,必然存在一个事务---锁的环形链
    • 按照同一顺序获取锁,可以破坏该条件
    • 通过分析死锁事务之间的锁竞争关系,调整 SQL 的顺序,达到消除死锁的目的。

    MySQL 中的锁

    排他锁

    与其他任何锁都是冲突的。

    共享锁

    多个事务可以共享一把锁。

    加锁方式

    外部加锁

    由应用程序执行特定语句,显式的加锁;

    • 可以通过分析 sql 语句,比较容易看清锁的依赖关系
    • 共享锁 select * from table lock in share mode
    • 排他锁 select * from table for update

    内部加锁

    为了实现 ACID 特性,由数据库内部自动添加

    • 加锁规则繁琐,与 SQL 执行计划、事务隔离级别、表索引结果有关,不容易排查死锁情况

    哪些 SQL 需要持有锁

    • 快照读

      • 所有 select 语句都属于快照读
      • Innodb 实现了多版本控制(MVCC),支持不加锁的快照度 「保证 select 语句的性能」
      • 能够保证同一个 select 结果集一致
      • 不能保证同一个事务内部,select 语句和其他语句的数据一致性,如有业务需要,需外部显式加锁
    • 当前读

      • select * from table lock in share mode
      • select * from table for update
      • Update from table set ...
      • Insert into ...
      • Delete from table ...

      显式加锁的读,以及更新插入删除操作语句,都是可触发 MySQL 内部加锁的

    捕获死锁的 sql 语句

    sql 语句:

    show engine innodb status
    

    相关文章

      网友评论

          本文标题:死锁的分析与解决

          本文链接:https://www.haomeiwen.com/subject/cyyqiqtx.html