死锁和死锁检测

死锁和死锁检测

死锁的概念

死锁是指两个或者两个以上的事务在执行过程中,因争夺资源而造成的一种相互等待的现象

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

这时候,事务 A 在等待事务 B 释放 id=2 的行锁,而事务 B 在等待事务 A 释放 id=1 的行锁。 事务 A 和事务 B 在互相等待对方的资源释放,就是进入了死锁状态。当出现死锁以后,有两种策略:

死锁解决策略

超时 innodb_lock_wait_timeout

默认为50秒

在innodb中,innodb_lock_wait_timeout的默认值是50s,意味着第一个策略出现死锁之后,第一个被锁住的线程要经过50s才会超时退出,然后其他线程才能执行,对于在线服务来说,这个等待时间是无法接受的。

但是,这个值泵改成太小的,这样出现死锁的时候,确定很快就可以揭开,但是不是死锁,而是简单的锁等待?所以,超时时间设置的太短的化,会出现很多误伤

死锁检测 innodb_deadlock_detect

默认值是on,主动死锁检测在发生死锁的时候,是能够快速发现并处理的,但是也有额外的负担

触发条件

当操作的行有锁的时候会进行死锁检测

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

过程

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

避免死锁

确保业务不会出现死锁,可以临时把死锁机制关闭

控制并发,比如同一行只有10个线程在更新,

利用中间件,异步解决mysql操作问题

将一行数据分成多行进行汇总操作

你可能感兴趣的:(MYSQL骑马的路)