MySQL 发生锁表
异常描述
- DBA 反馈监控异常日志,23点某 dml - update 语句锁表 10 m
异常分析
- 根据 DBA 提供的SQL
- 检索表中数据,发现检索结果为空
- 多条SQL执行时间接近,最多相差 1s
- 定位场景:锁表的场景,多个数据连接对同一个数据进行操作
- 场景复原:因为表中没有此条数据,所以默认指向了表中数据count数的下一条,所有SQL查询结果都指向了此条不存在的数据,相当于同一时间内多个数据库连接对同一条数据进行操作
- 问题定位:为何会有不属于该表的数据却在该表中做 update 操作
- 未实现某一个功能时,一个特定的功能,只针对某一特定的场景,但是没有加过滤条件,导致所有数据都会进行此操作
- 另外一个原因在于功能实现采用组合模式,每一个叶子节点的都是顺次执行的,无论是什么业务场景,及时不符合,也会进入该叶子节点进行逻辑处理,浪费时间及空间
异常总结
- 锁表的原因1:
- 当多个连接(数据库连接)同时对一个表的数据进行更新操作,那么速度将会越来越慢,持续一段时间后将出现数据表被锁的现象,从而影响到其它的查询及更新
- MySQL的innodb存储引擎支持行级锁,innodb的行锁是通过给索引项加锁实现的,这就意味着只有通过索引条件检索数据时,innodb才使用行锁,否则使用表锁
- 用索引字段做为条件进行修改时, 是否表锁的取决于这个索引字段能否确定记录唯一,当索引值对应记录不唯一,会进行锁表,相反则行锁
- 同一个表,如果进行删除操作时,尽量让删除条件唯一,否则会相互影响造成锁表
- 如果在事务中执行了一条不满足条件的update语句,则执行全表扫描,把行级锁上升为表级锁2