Mysql 之 阻塞与死锁详解

本文基于MySQL 5.7.11的默认引擎InnoDB 1.2.x ,从复现问题(模拟阻塞与死锁)、产生原因、解决办法、编码建议等角度全面解析阻塞和死锁;

第四节也会提及使用命令和INFORMATION_SCHEMA下的表来查看事务&锁的情况。

目录

1.  阻塞

     1.1 阻塞配置

     1.2 模拟阻塞

      1.3 阻塞超时带来的问题

      1.4 划重点

  2 . 死锁

      2.1  基本概念

      2.2  等待图(Wait - for Graph)

     2.3  AB-BA死锁示例

     2.4  X锁&S锁互斥 死锁示例

3.  编码建议

4.  查看运行中的事务&锁

5. 总结


1.  阻塞

     首先明确一点,阻塞与死锁是不同的。但它俩发生的场景往往相同:通常都在最糟糕的时候发生,比如产线业务最繁忙、高并发的场景下 🤭。

     阻塞是 InnoDB 引擎的正常行为,它为了确保事务可以正常并发,保证数据一致性等;

     但会影响性能,尤其在高并发情况下。两者差异如下图

特性 阻塞 死锁
定义 事务等待资源释放,才能继续执行 两个或多个事务互相等待对方持有的资源,形成循环等待。
发生条件 事务请求锁时,资源已被其他事务锁定。 事务之间相互等待对方的锁,并且没有办法继续执行。
处理方式 事务会在锁释放后继续执行,或者等待超时抛出异常 MySQL 自动检测并回滚一个事务,以解决死锁问题。
性能影响 会导致事务等待,延迟响应,可能影响整体系统性能。 死锁回滚需要额外的时间和资源,可能影响事务的响应时间。
发生概率 常见,特别是在高并发情况下。 较少发生,但一旦发生,通常需要手动优化事务的执行顺序。
影响范围 一般影响单个事务的执行,但不会导致系统崩溃。 死锁可能导致多个事务的失败,影响系统稳定性。

     1.1 阻塞配置

        InnoDB中有俩参数来控制阻塞的时间和策略。

  •  innodb_lock_wait_timeout 用来控制等待时间,默认是50秒,可动态设置Session | Global级;Global在重启后将丢失;Global修改时在这期间存活的Session也是不生效的;也可通过配置文件静态修改。
  •  innodb_rollback_on_timeout 控制等待超时的事务是否回滚,默认是OFF 不回滚;该参数为只读,不支持动态设置;需要在 MySQL 的配置文件(通常是my.cnfmy.ini)中进行修改,然后重启服务才生效。

        备注:有些文章甚至GPT 有关innodb_rollback_on_timeout 都说支持动态设置。其实官网对这俩参数的配置和作用说的很清楚,附上

innodb_lock_wait_timeout

innodb_rollback_on_timeout

        用以下命令动态设置Session级等待时间,设置global级只需换成 set @@global.X = Y

-- 查看等待时间
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';
-- 设置等待时间
SET @@session.innodb_lock_wait_timeout = 10;
设置前,默认50秒
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值