栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MySQL 45 讲 | 07 行锁功过:怎么减少行锁对性能的影响?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MySQL 45 讲 | 07 行锁功过:怎么减少行锁对性能的影响?

07 | 行锁功过:怎么减少行锁对性能的影响?
  • MySQL的行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁,比如 MyISAM 引擎就不支持行锁。

  • 行锁就是针对数据表中行记录的锁 。

两阶段锁
  • 两阶段锁协议:在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释 放,而是要等到事务结束时才释放。

  • 如果你的事务中需要锁多个行,要把 最可能造成锁冲突、最可能影响并发度的锁尽量往后放 。

死锁和死锁检测
  • 死锁:当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态。

  • 出现死锁以后,有两种策略:

    (1)直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout来设置。

    (2)发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数innodb_deadlock_detect设置为on,表示开启这个逻辑。

  • 在InnoDB中,innodb_lock_wait_timeout的默认值是50s , 但是又不可能直接把这个时间设置成一个很小的值,会出现很多误伤。 所以,正常情况下还是要采用第二种策略,即:主动死锁检测。

  • 主动死锁检测,innodb_deadlock_detect的默认值本身就是on。 能够快速发现并进行处理的,但是它也是有额外负担( 每个新来的被堵住的线程,都要判断会不会由于自己的加入导致了死锁 )。

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

  1. 问题的症结在于,死锁检测要耗费大量的CPU资源。

(1)如果你能确保这个业务一定不会出现死锁,可以临时把死锁检测关掉。但是这种操作本身带有一定的风险。

(2) 控制并发度。在客户端做并发控制不太可行(因为客户端很多,汇总到数据库服务端后,峰值并发数也很高)。因此,并发控制要做在数据库服务端 ,可以考虑在中间件实现;也可以做在MySQL里面修改MySQL源码。基本思路就是,对于相同行的更新,在进入引擎之前“排队”。

  1. 能不能从设计上优化这个问题呢?

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

小结
  • MySQL的行锁
  • 两阶段锁协议
  • 死锁和死锁检测
  • 如何安排正确的事务语句
  • 减少死锁的主要方向
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028171.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号