【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-02 死锁和死锁检测

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 【4月更文挑战第19天】在高并发环境下,死锁发生在多个线程间循环等待资源时,导致无限期等待。MySQL中,死锁可通过`innodb_lock_wait_timeout`参数设置超时或`innodb_deadlock_detect`开启死锁检测来解决。默认的50s超时可能不适用于在线服务,而频繁检测会消耗大量CPU。应对热点行更新引发的性能问题,可以暂时关闭死锁检测(风险是产生大量超时),控制并发度,或通过分散记录减少锁冲突,例如将数据分拆到多行以降低死锁概率。

死锁和死锁检测

在上一部分的例子里,影院余额这行的行锁在一个事务里不会停留很长时间,但是如果这个影院做活动,可以低价预售一年内所有的电影票,而且这个活动只持续一天。当活动时间开始的时候,MySQL就挂了,cpu消耗接近100%,但是整个数据库每秒执行不到100个事务。

当并发系统里不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。

2024-04-22-20-43-11-image.png

这时候,事务A在等待事务B释放id=2的行锁,而事务B在等待事务A释放id=1的行锁。 事务A和事务B在互相等待对方的资源释放,就是进入了死锁状态。

当出现死锁以后,有两种策略:

  • 一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数innodb_lock_wait_timeout来设置。

  • 另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数innodb_deadlock_detect设置为on,表示开启这个逻辑。

在InnoDB里,innodb_lock_wait_timeout的默认值是50s,这意味着如果采用第一个策略,当出现死锁以后,第一个被锁住的线程要过50s才会超时退出,然后其他线程才有可能继续执行。对于在线服务来说,这个等待时间往往是无法接受的。

但是又不能直接把这个时间设置为很小的值,比如1秒。这样当出现死锁的时候,确实很快可以解开;但是如果不是死锁,只是简单的锁等待,超时时间设置的太短,就会容易误伤。

正常还是采用第二种策略,即主动死锁检测,而且innodb_deadlock_detect的默认值本来就是on。主动死锁检测是能够快速发现死锁并处理的,但是他也会有额外的负担。比如如果所有的事务都要更新同一行的场景,每个新来的被堵住的线程,都会判断会不会由于自己的加入导致死锁,这是一个复杂度O(n)的操作。假设有1000个并发线程要同时更新同一行,死锁的操作检车就是1000*1000=100w的数量级,在这个期间要消耗大量的cpu资源。

那么怎么解决这种由热点行更新导致的性能问题?

  1. 如果确定这个业务一定不会出现死锁,可以临时把死锁检测关掉,会出现大量的超时,对业务有损。

  2. 控制并发度:比如同一行最多只有10个线程在更新,那么死锁检测的成本就会很低。

    • 在客户端做并发控制,这种方法并不可行,因为客户端很多

    • 因此要做在数据库服务端,或是中间件里。如果考虑修改MySQL源码或是自研数据库的话,对于相同行的更新,在进入引擎之前就排队。

    • 还可以考虑将一行改成逻辑上的多行来减少锁冲突。 比如影院账户可以考虑放在多条记录上,比如10个记录,影院的账户总额等于这10个记录的值的总和,每次随机选择一条记录来加金额。这样每次冲突的概率变为1/10,可以减少锁等待个数,也就减少了死锁检测的CPU消耗。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
23小时前
|
缓存 关系型数据库 MySQL
如何优化MySQL数据库查询性能
MySQL是一款常用的关系型数据库,但在实际使用过程中,由于数据量增加和查询操作复杂度增加,会导致查询性能下降。本文将介绍一些优化MySQL数据库查询性能的方法。
|
1天前
|
SQL 存储 关系型数据库
Mysql优化提高笔记整理,来自于一位鹅厂大佬的笔记,阿里P7亲自教你
Mysql优化提高笔记整理,来自于一位鹅厂大佬的笔记,阿里P7亲自教你
|
2天前
|
存储 关系型数据库 MySQL
【MySQL系列笔记】分库分表
分库分表是一种数据库架构设计的方法,用于解决大规模数据存储和处理的问题。 分库分表可以简单理解为原来一个表存储数据现在改为通过多个数据库及多个表去存储,这就相当于原来一台服务器提供服务现在改成多台服务器组成集群共同提供服务。
28 8
|
2天前
|
存储 算法 关系型数据库
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
|
2天前
|
存储 SQL 关系型数据库
MySQL的优化利器⭐️索引条件下推,千万数据下性能提升273%🚀
以小白的视角探究MySQL索引条件下推ICP的优化,其中包括server层与存储引擎层如何交互、索引、回表、ICP等内容
MySQL的优化利器⭐️索引条件下推,千万数据下性能提升273%🚀
|
2天前
|
存储 关系型数据库 MySQL
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
本篇文章来讨论MySQL字段的字符类型选择并深入实践char与varchar类型的区别以及在千万数据下的性能测试
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
|
2天前
|
存储 SQL 关系型数据库
MySQL万字超详细笔记❗❗❗
MySQL万字超详细笔记❗❗❗
77 1
MySQL万字超详细笔记❗❗❗
|
2天前
|
SQL 关系型数据库 MySQL
【MySQL系列笔记】MySQL总结
MySQL 是一种关系型数据库,说到关系,那么就离不开表与表之间的关系,而最能体现这种关系的其实就是我们接下来需要介绍的主角 SQL,SQL 的全称是 Structure Query Language ,结构化的查询语言,它是一种针对表关联关系所设计的一门语言,也就是说,学好 MySQL,SQL 是基础和重中之重。SQL 不只是 MySQL 中特有的一门语言,大多数关系型数据库都支持这门语言。
240 8
|
2天前
|
关系型数据库 MySQL 数据库
docker MySQL删除数据库时的错误(errno: 39)
docker MySQL删除数据库时的错误(errno: 39)
23 0
|
2天前
|
Java 关系型数据库 MySQL
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口(下)
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口
11 0

推荐镜像

更多