MySQL行锁的最佳实践(下)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: MySQL行锁的最佳实践

死锁和死锁检测

当并发系统不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源,就会导致这几线程都无限等待=》死锁。


image.png


  • 事务1在等待事务2释放id=2的行锁
  • 事务2在等待事务1释放id=1的行锁
  • 事务1和事务2在互相等待对方的资源释放,导致死锁

死锁后的策略

超时等待


该超时时间可通过参数innodb_lock_wait_timeout设置。


InnoDB中,innodb_lock_wait_timeout默认值50s,若采用策略1,当死锁后,第一个被锁住的线程要50s才超时退出,然后其他线程才可能继续。对在线服务,这等待时间无法接受!

也不可能直接把这时间设成一个小值。这样当死锁时,确实很快解开,但若不是因为死锁,而只是正常的锁等待呢?所以,超时时间设太短,会误伤友军。


主动死锁检测

发现死锁后,主动回滚死锁链中的某一事务,让其他事务继续执行。

将参数innodb_deadlock_detect设置为on,开启该逻辑。


正常情况采用该策略,而且innodb_deadlock_detect默认值就是on。

主动死锁检测在发生死锁时,能够快速发现并处理,但有额外负担:

每当一个事务被锁,就看看它所依赖的线程是否被别人锁住。如此循环,最后判断是否出现循环等待,即死锁。


  • 若是说到的所有事务都更新同一行数据?

每个新来的被堵住的线程,都要判断会不会由于自己的加入导致了死锁,时间复杂度O(n)。若有1000个并发线程要同时更新同一行,则死锁检测操作就是100万量级。虽然最终检测结果是没有死锁,但这期间要消耗大量CPU。因此,你就会看到CPU占用率很高,但是每秒却执行不了几个事务。


优化热点行更新

死锁检测关掉


问题在于,死锁检测耗费大量CPU资源。若你能确保该业务一定不会出现死锁,可以临时把死锁检测关掉。但这操作有一定风险,因为业务设计时一般不会把死锁当做一个严重错误:

  • 毕竟出现死锁,就回滚,然后通过业务重试一般就没问题,业务无损
  • 而关掉死锁检测意味着可能会出现大量超时,业务有损


控制并发度


如果并发能够控制住,比如同一行同时最多10个线程更新,那么死锁检测成本低了,就不会出现这问题。

一个直接的想法,在客户端做并发控制。但很快发现这不太可行,因为客户端很多的!!!

因此并发控制要做在数据库服务端。若有中间件,可考虑在中间件实现。若团队有能修改MySQL源码的人,也可做在MySQL。


基本思路


对于同行更新,在进入引擎之前排队。这样在InnoDB内部就不会有大量死锁检测工作。

若团队没有DB专家,不能实现这样方案,能否做设计优化?


分段锁


可以考虑将一行改成逻辑上的多行,以减少锁冲突。


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


这方案看上去无损,但这类方案需根据业务逻辑做详细设计。若账户余额可能减少,比如退票操作,则此时就需要考虑当一部分行记录变成0时,代码要有特殊处理。


调整语句顺序并不能完全避免死锁,以上方案都只是减少死锁对数据库影响。减少死锁的主要方向也就是控制访问相同资源的并发事务量。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
存储 关系型数据库 MySQL
深入理解MySQL索引:从原理到最佳实践
深入理解MySQL索引:从原理到最佳实践
207 0
|
7月前
|
存储 分布式计算 关系型数据库
AnayticDB MySQL降本30%的数据湖最佳实践
上海兰姆达数据科技有限公司,基于ADB MySQL 湖仓版降本30%的数据湖最佳实践
|
5天前
|
关系型数据库 MySQL 中间件
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-02 死锁和死锁检测
【4月更文挑战第19天】在高并发环境下,死锁发生在多个线程间循环等待资源时,导致无限期等待。MySQL中,死锁可通过`innodb_lock_wait_timeout`参数设置超时或`innodb_deadlock_detect`开启死锁检测来解决。默认的50s超时可能不适用于在线服务,而频繁检测会消耗大量CPU。应对热点行更新引发的性能问题,可以暂时关闭死锁检测(风险是产生大量超时),控制并发度,或通过分散记录减少锁冲突,例如将数据分拆到多行以降低死锁概率。
19 1
|
2月前
|
存储 关系型数据库 MySQL
百度搜索:蓝易云【MySQL的行锁、表锁触发教程】
需要注意的是,行锁和表锁的使用会对数据库的性能产生影响。行锁可以提高并发性,但可能导致死锁问题,而表锁可以简单粗暴地避免死锁,但会降低并发性。因此,在使用锁时需要根据实际情况来选择合适的锁级别。如果需要更精细的并发控制,可以考虑使用行锁,如果对并发性要求不高,可以考虑使用表锁。
26 1
|
2月前
|
监控 关系型数据库 MySQL
MySQL Binlog实战:在生产环境中的应用与最佳实践【实战应用】
MySQL Binlog实战:在生产环境中的应用与最佳实践【实战应用】
36 0
|
3月前
|
关系型数据库 MySQL 索引
Mysql锁之——行锁
Mysql锁之——行锁
|
4月前
|
SQL 运维 关系型数据库
阿里云DTS踩坑经验分享系列|如何使用DTS进行MySQL->ClickHouse同步
在使用阿里云DTS 进行MySQL->ClickHouse同步时,从准备工作,到创建任务,再到后期运维处理,新手可能会感到茫然和不知所措。为了帮助新手顺利过渡,本文将介绍使用阿里云DTS在进行MySQL到ClickHouse迁移时的最佳实践以及常见踩坑问题, 我们希望通过这篇文章,让您能无忧使用阿里云DTS进行数据迁移,享受ClickHouse带来的高效数据分析体验。
98317 12
阿里云DTS踩坑经验分享系列|如何使用DTS进行MySQL->ClickHouse同步
|
9月前
|
存储 关系型数据库 MySQL
探讨MySQL什么情况下触发表锁,行锁
MySQL是一种流行的关系型数据库管理系统,它支持多种存储引擎,例如MyISAM和InnoDB。在并发访问数据库的环境下,为了保证数据的完整性和一致性,MySQL会使用锁机制来控制对数据的访问。MySQL中的锁分为表级锁和行级锁,它们在不同的情况下会被触发。
721 0
|
4月前
|
SQL 存储 关系型数据库
MySQL表锁、行锁、排它锁和共享锁
MySQL表锁、行锁、排它锁和共享锁
49 0
MySQL表锁、行锁、排它锁和共享锁
|
6月前
|
关系型数据库 MySQL Java
Java 最常见的面试题:说一下 mysql 的行锁和表锁?
Java 最常见的面试题:说一下 mysql 的行锁和表锁?