减少行锁对性能的影响
1. 什么是行锁
行锁是针对数据表中的行记录进行加锁。
2. 两阶段锁
InnoDB中会在需要的时候加上行锁,不是使用完立即释放,而是等待事务结束才释放,这就是两阶段锁。
3. 死锁
并发系统中,多个线程有循环资源依赖,导致进入无限等待状态,就是死锁。
3.1 死锁的处理策略
- 超时释放。设置参数 innodb_lock_wait_timeout
- 死锁检测,发现死锁后,主动回滚死锁链条中的一个事务。将innodb_deadlock_detect 设置为on
4. 如何解决热点行更新导致的性能问题?
- 如果知道业务不会产生死锁的话,就把死锁检测关掉。
- 控制并发度。控制并发更新热点行的线程数量。
- 从设计上有话,讲一行热点数据改成逻辑上的多行。比如将统计总数的记录按照某些维度拆分到不同的行,统计的时候通过sum统计,更新的时候,只更新其中的某一行,降低锁冲突概率。
5. 如何删除表中的前10000行数据
备选方案如下:
- delete from T limit 10000
- 在一个连接中循环执行 delete from T limit 500
- 在20个连接中同时执行 delete from T limit 500
最优的是方案2.
- 方案1会对数据逐行加锁,事务结束后才会释放行锁,导致加锁时间长,影响其他事务。
- 方案2 涉及加锁的数据行比较少,持有锁的时间比较短。
- 方案3 在20个连接中同时执行,会产生20个事务,这20个事务之间互相竞争锁,人为增加了冲突。