前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mysql数据--死锁解密

Mysql数据--死锁解密

作者头像
小土豆Yuki
发布2020-08-06 23:53:15
1.4K0
发布2020-08-06 23:53:15
举报
文章被收录于专栏:洁癖是一只狗洁癖是一只狗

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的时候,这个时候需要特殊处理进行了

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洁癖是一只狗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档