一文看懂MySQL的行锁

news2024/11/26 22:47:07

MySQL的全局锁和表锁可以看这篇文章:MySQL的全局锁和表锁
进入正文

行锁

行锁是由各个存储引擎自己实现的,并不是所有的引擎都支持行锁。

MyISAM引擎就不支持行锁,同一时刻一张表只能有一个更新在执行。

现在说InnoDB的行锁,行锁,顾名思义,就是事务A更新一行,同时事务B也要更新一行,那么事务B只好等事务A更新完成再去更新。

两阶段锁

在InnoDB中,行锁是在需要的时候才加上的,并不是事务开始就加上了,当然了,它也不是不需要了就释放锁,锁是在事务提交之后才进行释放的。这就是两阶段锁协议。

知道了这个设定,如果事务中需要锁多个行,可以把最可能造成冲突,最可能造成并发的尽量放在后面。

使用行锁可能产生死锁问题:

死锁产生的条件:互斥条件,请求和保持条件,不可抢占条件,不可剥夺条件。

img

事务A正在等待事务B释放id=2行的锁,事务B正在等待事务A释放id=1行的锁。可见,形成了死锁。

当出现死锁的额时候有两种解决方案:

  • 一种策略是,直接进入等待,知道超时,这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。
  • 第二个策略是,可以发起死锁检测,当死锁发生时,主动回滚死锁发生时的某一条事务,让其他食物得以回滚。将参数innodb_deadlock_detect设置为on,表示开启这个逻辑。

在InnoDB中,innodb_lock_wait_timeout参数的默认超时时间是50s,(出现等待有可能不是死锁,可能是简单的等待锁资源)意思是当出现死锁后,被锁住的线程要超过50s才能退出。然后其他任务才能执行,这对于在线业务来说,肯定是不能接受的。

把参数调小,比如说是1s,那么可能会把没有发生死锁,而是简单等待锁资源的线程给释放了。

所以,正常情况下我们还是要采用第二种策略,即:主动死锁检测,而且 innodb_deadlock_detect 的默认值本身就是 on。主动死锁检测在发生死锁的时候,是能够快速发现并进行处理的,但是它也是有额外负担的。

比如一个事务被锁了, 就要看看它所依赖的线程有没有被别人锁住,如此循环,最后判断是否出现了循环等待,也就是死锁。

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

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

1. 尽量想办法不产生死锁。 出现死锁了就回滚,然后业务重试应该就没有问题了,这是业务无损的。

如果死锁检测关闭了,发生死锁等待之后超时,这是业务有损的。

2. 另一个思路是控制并发度。根据上面的分析,你会发现如果并发能够控制住,比如同一行同时最多只有 10 个线程在更新,那么死锁检测的成本很低,就不会出现这个问题。一个直接的想法就是,在客户端做并发控制。但是,你会很快发现这个方法不太可行,因为客户端很多。我见过一个应用,有 600 个客户端,这样即使每个客户端控制到只有 5 个并发线程,汇总到数据库服务端以后,峰值并发数也可能要达到 3000。因此,这个并发控制要做在数据库服务端。如果你有中间件,可以考虑在中间件实现;如果你的团队有能修改 MySQL 源码的人,也可以做在 MySQL 里面。基本思路就是,对于相同行的更新,在进入引擎之前排队。这样在 InnoDB 内部就不会有大量的死锁检测工作了。可你可以考虑通过将一行改成逻辑上的多行来减少锁冲突。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/50099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]计算机毕业设计springboot家庭医生签约服务管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

你在终端启动的进程,最后都是什么下场?(上)

你在终端启动的进程,最后都是什么下场?(上) 前言 在本篇文章当中,主要给大家介绍我们在终端启动的进程都是怎么结束的,在我们登录终端和退出终端都发生了什么? 基本介绍 首先我们需要了解的…

从Android系统启动→app启动→activity启动和渲染的整个流程

引言 本文讲解从开机到app显示画面的流程,但不分析源码,如果想阅读源码请到参考文章中查阅。 本文把这段流程分为三部分: 从开机到显示应用列表从点击应用图标到Activity创建成功从Activity创建成功到显示画面 从开机到显示应用列表 先看…

Java-CC

漏洞原理 TransformedMap这个类的decorate函数可以将一个普通的Map转换为一个TransformedMap,其第2、3参数分别对应当key改变和value改变时需要做的操作。所以此时如果修改其中的任意key或value,就会触发我们预先定义好的某些操作来对Map进行处理&#…

pytorch初学笔记(十四):损失函数

目录 一、损失函数 1.1 L1损失函数 1.1.1 简介 1.1.2 参数设定 1.1.3 代码实现 1.2 MSE损失函数(平方和) 1.2.1 简介 1.2.2 参数介绍 1.2.3 代码实现 1.3 损失函数的作用 二、在神经网络中使用loss function 2.1 使用交叉熵损失函数 2.2 …

【软件测试】资深测试聊一聊,测试架构师是怎么样的,做一名成功的测试工程师......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 测试架构师 测试架…

利尔达5G模组NE16U-CN通过华为OpenLab基于R16标准的认证测试

近日,利尔达5G R16模组NE16U-CN 率先顺利通过了华为OpenLab的认证测试,成为首批基于展锐V516芯片平台通过华为认证测试的5G模组,实现了基于3GPP R16协议版本的业务验证。 这表明,利尔达NE16U-CN模组已支持3GPP R16所具有的5G LAN、…

Overview of Computer Graphics

ContentsWhat is Computer Graphics?Why study Computer Graphics?ApplicationsFundamental Intellectual ChallengesTechnical ChallengesCourse TopicsRasterization (光栅化)Curves and Meshes (曲线和曲面)Ray Tracing (光线追踪)Animation / Simulation (动画 / 模拟)Re…

ANACONDA的进阶理解和思考

0. 继续深入了解anaconda 0.1 Anaconda 是 Python 的一个开源发行版本 里面集成了很多关于 python 科学计算的第三方库,主要面向科学计算且安装方便,而 python 是一个编译器 如果不使用 anaconda,那么安装库的时候,库的依赖安装起…

力扣LeetCode算法题 第6题-Z 字形变换

要求: 一开始看到题目,第一想到的思路,就被题目要求的思路给带偏了。 内容是Z字型输出内容 就一直想着把字符串输出成上面这种格式 总是想着把字符串放入到二维数组中进行展示。 这样一来思路就受到了限制。 一直使用先写入数组中。 //将…

直播邀请函 | 第12届亚洲知识产权营商论坛:共建创新价值 开拓崭新领域

由香港特别行政区政府、香港贸易发展局及香港设计中心共同举办的亚洲知识产权营商论坛,每年为世界各地知识产权业界专家、商界领袖提供一个理想平台,共同探讨亚洲知识产权市场的最新发展,发掘更多商机。 去年,论坛共邀请70余位国…

使用HBuilder X开发Vue3+node+element-plus(一)

开发Vue3有很多的工具,比如VSCode,它也非常的好用,本文主要使用HBuilder X开发。 环境3个: Windows10 Node安装 1.打开官网,选择一个版本,进行安装 Node.js 2.选择路径,下一步就行了 3. 输…

【深度学习】torch.argmax()函数讲解 | pytorch

文章目录前言一、两个维度的张量使用torch.argmax()函数二、三个维度的张量使用torch.argmax()函数前言 这篇博客也是属于看了好久一直没写,终于写了。 一、两个维度的张量使用torch.argmax()函数 我们直接先举一个例子吧,我们随机生成一个2X3的张量&…

[附源码]SSM计算机毕业设计亿上汽车在线销售管理系统JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

11 Daemonset:忠实可靠的看门狗

文章目录1. 前言2. 为什么要有 DaemonSet(看门狗)?3. 如何使用 YAML 描述 DaemonSe?3.1 参考官网创建DaemonSet YAML3.1.1 DaemonSet YAML 和 Deployment YAML 文件对比3.1.2 DaemonSet YAML 和 Deployment YAML 文件对比图示3.2 用变通的方法来创建 DaemonSet 的 …

【Python模块】图形化编程模块-turtle

Turtle,也称海龟渲染器,是 Python 内置的图形化模块,它使用 tkinter 实现基本图形界面,因此 当前使用的 Python 环境需要支持 tkinter。 Turtle 提供了面向对象和面向过程两种形式的海龟绘图基本组件。使用它可以轻松的实现图形的…

初探Golang语法巩固复习

最近在家,重新拾起Go语言,搭建环境可参考之前博客【初探Golang语言之环境搭建】,本文是基本语法熟悉与练习,方便备查。 判断语句 if && switch if 通过指定一个或多个条件,并通过测试条件是否为true来决定是…

[附源码]计算机毕业设计springboot驾校预约管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

xcode swift 单元测试 test

XCTest是苹果官方的测试框架&#xff0c;是基于OCUnit的传统测试框架&#xff0c;测试编写起来非常简单。 测试案例一 创建一个单元测试 func testExample() throws {let personID:String "0123456789"let count personID.countXCTAssert(count < 10, "I…

aPaaS是什么(aPaaS平台和IPaaS的区别是啥?大白话解释)

依题&#xff1a;aPaaS是什么&#xff1f;aPaaS与iPaaS二者之间的区别在哪&#xff1f;要想了解区别&#xff0c;首先得搞清概念&#xff0c;不然就是在耍流氓&#xff01;下面本人就从概念到区别用大白话给你一次性讲清楚。 一、什么是aPaaS&#xff1f; 应用程序平台即服务&…