美文网首页
6、行锁:怎么减少行锁对性能的影响?

6、行锁:怎么减少行锁对性能的影响?

作者: 内卷星球 | 来源:发表于2020-04-08 10:07 被阅读0次

    两阶段锁

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

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

    死锁

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

    image.png
    • 解决方案:
    1. 通过参数 innodb_lock_wait_timeout 根据实际业务场景来设置超时时间,InnoDB引擎默认值是50s。
    2. 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑(默认是开启状态)。

    在InnoDB中,innodb_lock_wait_timeout的默认值是50s,意味着如果采用第一个策略,当出现死锁以后,第一个被锁住的线程要过50s才会超时退出,然后其他线程才有可能继续执行。对于在线服务来说,这个等待时间往往是无法接受的。

    主动死锁检测在发生死锁的时候,是能够快速发现并进行处理的,但是它也是有额外负担的。(死锁检测要耗费大量的CPU资源
    比如所有事务都要更新同一行的场景呢?
    每个新来的被堵住的线程,都要判断会不会由于自己的加入导致了死锁,这是一个时间复杂度是O(n)的操作。假设有1000个并发线程要同时更新同一行,那么死锁检测操作就是100万这个量级的。虽然最终检测的结果是没有死锁,但是这期间要消耗大量的CPU资源。因此,你就会看到CPU利用率很高,但是每秒却执行不了几个事务。

    • 如何解决热点行更新导致的性能问题?
    1. 如果能确保这个业务一定不会出现死锁,可以临时把死锁检测关闭掉。一般不建议采用
    2. 控制并发度,对应相同行的更新,在进入引擎之前排队。这样在InnoDB内部就不会有大量的死锁检测工作了。
    3. 将热更新的行数据拆分成逻辑上的多行来减少锁冲突,但是业务复杂度可能会大大提高。

    innodb行级锁是通过锁索引记录实现的,如果更新的列没建索引是会锁住整个表的。

    相关文章

      网友评论

          本文标题:6、行锁:怎么减少行锁对性能的影响?

          本文链接:https://www.haomeiwen.com/subject/jnezphtx.html