【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
目录
相关文章
|
2天前
|
SQL 关系型数据库 MySQL
【MySQL系列笔记】MySQL总结
MySQL 是一种关系型数据库,说到关系,那么就离不开表与表之间的关系,而最能体现这种关系的其实就是我们接下来需要介绍的主角 SQL,SQL 的全称是 Structure Query Language ,结构化的查询语言,它是一种针对表关联关系所设计的一门语言,也就是说,学好 MySQL,SQL 是基础和重中之重。SQL 不只是 MySQL 中特有的一门语言,大多数关系型数据库都支持这门语言。
25 8
|
2天前
|
SQL 关系型数据库 MySQL
【MySQL系列笔记】常用SQL
常用SQL分为三种类型,分别为DDL,DML和DQL;这三种类型的SQL语句分别用于管理数据库结构、操作数据、以及查询数据,是数据库操作中最常用的语句类型。 在后面学习的多表联查中,SQL是分析业务后业务后能否实现的基础,以及后面如何书写动态SQL,以及完成级联查询的关键。
18 6
|
2天前
|
存储 关系型数据库 MySQL
【MySQL系列笔记】InnoDB引擎-数据存储结构
InnoDB 存储引擎是MySQL的默认存储引擎,是事务安全的MySQL存储引擎。该存储引擎是第一个完整ACID事务的MySQL存储引擎,其特点是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,同时被设计用来最有效地利用以及使用内存和 CPU。因此很有必要学习下InnoDB存储引擎,它的很多架构设计思路都可以应用到我们的应用系统设计中。
21 4
|
2天前
|
SQL 存储 关系型数据库
【MySQL系列笔记】SQL优化
SQL优化是通过调整数据库查询、索引、表结构和配置参数等方式,提高SQL查询性能和效率的过程。它旨在减少查询执行时间、减少系统资源消耗,从而提升数据库系统整体性能。优化方法包括索引优化、查询重写、表分区、适当选择和调整数据库引擎等。
17 3
|
4天前
|
弹性计算 关系型数据库 MySQL
检测MySQL 服务是否存活
【4月更文挑战第29天】
5 0
|
4天前
|
弹性计算 关系型数据库 MySQL
检测MySQL 数据库连接数量
【4月更文挑战第29天】
5 0
|
5天前
|
弹性计算 关系型数据库 MySQL
检测 MySQL 服务是否存活
【4月更文挑战第28天】
7 0
|
5天前
|
弹性计算 关系型数据库 MySQL
检测 MySQL 数据库连接数量
【4月更文挑战第28天】
8 0
|
9天前
|
缓存 关系型数据库 MySQL
MySQL数据库优化技巧:提升性能的关键策略
索引是提高查询效率的关键。根据查询频率和条件,创建合适的索引能够加快查询速度。但要注意,过多的索引可能会增加写操作的开销,因此需要权衡。
|
10天前
|
存储 数据可视化 关系型数据库
MySQL字段的时间类型该如何选择?千万数据下性能提升10%~30%🚀
本文探讨MySQL中时间类型的选择,阐述datetime、timestamp、整形时间戳等类型特点以及它们在千万级数据量下的查询性能
MySQL字段的时间类型该如何选择?千万数据下性能提升10%~30%🚀