专栏首页洁癖是一只狗Mysql数据--死锁解密

Mysql数据--死锁解密

Mysql行锁是在引擎中实现的,并不是所有的存储引擎都支持行锁,比如myisam就不支持行锁,而innodb支持行锁,myisam在并发度高的系统中就会影响系统的性能,因为他仅仅支持表锁,这也就是他被innodb替换的原因之一

行锁顾名思义,就是当一个事物A更新一行的数据的,事物B也要更新同一行,因此事物B必须等待事物A执行完成之后才会执行,

有些情况行锁会引起不必要的问题,首先我们了解一下二阶段锁说起

正如下面例子,事物B是什么时候才回去执行呢

其实这个问题取决于事物A是在什么时候执行完成,当事物A执行完成之后,事物B不一定立马会执行。直到事物A是在提交事物之后,才会释放行锁,知道了这个原理,发现并不是不需要的时候就去释放行锁,而是等待事物提交之后才会真正的释放锁,这就是二阶段锁

那么这能给我们业务系统中起到什么作用呢,在事物中含有多个行锁的时候,尽量要把引起所冲突,最可能引起并发的锁向后拖,举个例子 在某电影院中,一个人A需要购买电影票,主要涉及下面几种业务操作

  1. 扣除我们账户的金额
  2. 在电影院中增加电影票的金额
  3. 记录一条都买记录

与此同时,另外一个人B也需要购买电影票,这个时候,就必须等待A操作完毕之后,B的业务逻辑才能进行,这种情况要是在高并发中,可能就会有很高的延迟性,根据二阶段锁定义,我们是必须等待A这个人购买完之后,才能进行另一个人B的操作,但是我们认真的分析了一下,其中有锁冲突的就仅仅是对电影院中账户增加金额,才会导致锁冲突,那么就可以移动操作的业务逻辑顺序,比如我们执行的顺序是1,3,2.这样我们就尽可能的把锁冲突的时间较少到了做少,这样就会间接的提高了并发度。 但是上面的优化并没有真正的解决问题,如果当电影院进行活动,用户量非常的高,我们发现cpu达到了100%,但是并没有多少事物被执行。如何解决的呢,到这里我们必须了解几个概念

死锁和死锁检测

并发系统中多个不同线程循环依赖资源,在多个线程就会等待其他线程释放资源,互相等待,这就是死锁,举个例子

看到上面的例子,我们发现事物A执行id=2的时候,在等待事物B释放id=2的锁,而事物B在执行id=1的时候,在等到事物A释放id=1的锁。互相循环等待,如何解决这种问题呢,有两种策略

  • 设置超时时间,事物超过了时间就会自动释放,可以用nnodb_lock_wait_timeout设置
  • 死锁检测,检测到有死锁,释放其中一条,让其他事物先进行,可以用innodb_deadlock_detect设置为on,表示开启这个逻辑

如果我们设置超时时间,默认是50s,在并发系统中,我们必须等待超过50s才会释放锁,这对于正常的业务是不能接受的,那么我们如果把超时间设置成更短呢,比如1s,这种也是不行的,我们正常的业务系统中,有可能发生正常的锁等待,这就可能导致误杀,也是不能接受的。

如果我们使用死锁检测呢,一个事物操作数据的时候,就会检测是否有依赖的资源,导致死锁,那么他能快速的进行处理,但是也是有额外的开销的

在一个高并发的系统中,有1000个线程并发执行同一行数据,就会导致100万级别的计算检测,这样也会导致系统高延迟,cpu急剧上升,也执行不了多少事物。

那么我们如何解决这种热点行导致的问题的,当然也是有的

比如我们可以肯定要操作的行数据是不会发生锁冲突的,我们就可以关闭死锁检测,这种我们的系统会大量超时,对业务是有损的,业务对于死锁看做并不是一种很验证的错误,发生的时候,使用死锁检测可以进行回滚,对业务是无损,因此如何选择你自己看着办。

另一种思路就是提高并发控制,对一行数据仅仅有10个线程操作,那么死锁检测就不会有很大的成本,最直接的想法就是设置客户端的并发线程最多是5个,但还是如果有的系统由很多个客户端,那也有不小的并发线程,因此我们只能在服务端进行控制

因此我们可以利用中间件进行控制,当然如果你们的团队有能力修改存储引擎,让线程排队处理,也是可以的,但是正常情况很少有这样的人才,反正我们的团队是没有的,只有问题出现了,互相推锅的人才,防不胜防,

我们也可以换种思路,比如把一行数据改成多个,让不能的线程处理不同行,比如,电影院的账户记录,可以拆成多行,只要正常添加金额就可以了,但是要注意可能退票的场景,导致金额为0的时候,这个时候需要特殊处理进行了

今天我们主要说了行锁,二阶段锁,以及死锁,死锁检测,如何处理热点行的处理,提供了几种方案,以及二阶段锁,事物中有多条行锁,尽量把有所冲突的行向后拖,但是这种也不能解决问题,才会引入死锁和死锁检测,主要在减少死锁上方向上,就是对并发资源的控制.

本文分享自微信公众号 - 洁癖是一只狗(rookie-dog),作者:洁癖汪

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 并发编程问题为什么都很诡异

    并发编程对于很多人说都是比较难的,总是出现一些莫名其妙的bug,让我们很是苦恼,那么他到底是难在哪里呢,今天就带大家看看引起并发bug的根源

    小土豆Yuki
  • 如何解决可见性,有序性,原子性

    上一次我们说到了可见性,原子性,有序性,今天我们看看如何解决这个问题,今天我们先看看可见性和有序性,因此我们先要知道java内存模型

    小土豆Yuki
  • Mysql中sql执行如此慢

    我们经常发现,往往执行一条简单的查询语句,但是很长时间都没有返回,今天我们看看是什么原因导致的

    小土豆Yuki
  • 基于ReentrantLock发生死锁的解决方案

    java404
  • 一个多线程死锁案例,如何避免及解决死锁问题?

    多线程死锁在java程序员笔试的时候时有遇见,死锁概念在之前的文章有介绍,大家应该也都明白它的概念,不清楚的去翻看历史文章吧。 下面是一个多线程死锁的例子 输出...

    Java技术栈
  • 面试常问 乐观锁 & 悲观锁 、自旋锁 & 互斥锁 ?诸君听我一言

    乐观锁和悲观锁并不是一种真实存在的锁,而是一种设计思想,乐观锁和悲观锁对于理解后端多线程和数据库来说至关重要,那么本篇文章就来详细探讨一下这两种锁的概念以及实现...

    看、未来
  • 入门 | 如何从零基础转行数据分析

    转行,这个话题我觉得许多朋友都非常感兴趣。毕竟工作伴随着我们的一生,也是我们的主要收入来源,任谁都希望能拥有一份高薪又有前景的工作!

    CDA数据分析师
  • 【微服务】159:Elasticsearch的使用

    昨天我们给索引库设定了几个字段,以上述例子中的title字段为例,给其添加一条数据“小爱手机”,这样后面可以通过索引库来快速定位这条数据了。

    刘小爱
  • HTML5 download属性无效的问题

    如果url指向第三方资源,download会失效,表现和不使用download时一致——浏览器能打开的文件,浏览器会直接打开,不能打开的文件,会直接下载。浏览器...

    javascript.shop
  • Log4j2 — Log4j2导入、LogEvent、配置文件编写及路径

    1. Log4j2的导入                 首先到http://logging.apache.org/log4j/2.x/download.htm...

    YGingko

扫码关注云+社区

领取腾讯云代金券