MySQL行锁的最佳实践(下)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 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时,代码要有特殊处理。


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


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
关系型数据库 MySQL
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-01
【4月更文挑战第18天】MySQL的InnoDB引擎支持行锁,而MyISAM只支持表锁。行锁在事务开始时添加,事务结束时释放,遵循两阶段锁协议。为减少锁冲突影响并发,应将可能导致最大冲突的锁操作放在事务最后。例如,在电影票交易中,应将更新影院账户余额的操作安排在事务末尾,以缩短锁住关键行的时间,提高系统并发性能。
208 4
|
关系型数据库 MySQL 数据库
《MySQL 简易速速上手小册》第2章:数据库设计最佳实践(2024 最新版)
《MySQL 简易速速上手小册》第2章:数据库设计最佳实践(2024 最新版)
201 2
|
关系型数据库 MySQL 数据库
数据安全之路:深入了解MySQL的行锁与表锁机制
数据安全之路:深入了解MySQL的行锁与表锁机制
643 1
|
7月前
|
SQL 存储 关系型数据库
滴滴面试:明明 mysql 加的是 行锁,怎么就变 表锁 了?
滴滴面试:明明 mysql 加的是 行锁,怎么就变 表锁 了?
|
关系型数据库 MySQL 数据库
MySQL数据库:基础概念、应用与最佳实践
一、引言随着互联网技术的快速发展,数据库管理系统在现代信息系统中扮演着核心角色。在众多数据库管理系统中,MySQL以其开源、稳定、可靠以及跨平台的特性受到了广泛的关注和应用。本文将详细介绍MySQL数据库的基本概念、特性、应用领域以及最佳实践,帮助读者更好地理解和应用MySQL数据库。二、MySQL
949 5
|
关系型数据库 MySQL 数据库连接
绝对干货!从MySQL5.7平滑升级到MySQL8.0的最佳实践分享
绝对干货!从MySQL5.7平滑升级到MySQL8.0的最佳实践分享
2431 0
|
SQL 存储 关系型数据库
精通MySQL:从基础到高级应用与最佳实践
第一章:MySQL基础入门 1.1 MySQL概述 介绍MySQL的历史、发展、优势以及应用领域
|
网络协议 关系型数据库 MySQL
【最佳实践】MySQL数据库迁移到PXC集群
借本次数据库迁移实践,再次总结一下MySQL数据库迁移到PXC的最佳操作路径。
264 0
|
关系型数据库 MySQL 中间件
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-02 死锁和死锁检测
【4月更文挑战第19天】在高并发环境下,死锁发生在多个线程间循环等待资源时,导致无限期等待。MySQL中,死锁可通过`innodb_lock_wait_timeout`参数设置超时或`innodb_deadlock_detect`开启死锁检测来解决。默认的50s超时可能不适用于在线服务,而频繁检测会消耗大量CPU。应对热点行更新引发的性能问题,可以暂时关闭死锁检测(风险是产生大量超时),控制并发度,或通过分散记录减少锁冲突,例如将数据分拆到多行以降低死锁概率。
408 1
|
关系型数据库 MySQL 数据库
精通MySQL:数据库管理、性能优化与最佳实践
h3> 一、引言 MySQL是一个功能强大的开源关系型数据库管理系统,广泛应用于各种Web应用、企业级应用和数据分析等领域
1516 0

推荐镜像

更多