mysql锁表分析

由于近期MYSQL在改表移库时,发生了锁表现象.如今对该现象进行分析,并提出一些建议。mysql

1、改表sql

Mysql 5.6 虽然引入了Online DDL,可是并非修改表结构的时候,必定不会致使锁表,在一些场景下仍是会锁表的,好比
1)某个慢SQL或者比较大的结果集的SQL在运行,执行ALTER TABLE时将会致使锁表发生;
2)存在一个事务在操做表的时候,执行ALTER TABLE也会致使修改等待;并发

 

按以下步骤执行测试:测试

1)开启A事务,更新数据,且不提交大数据

执行结果以下:优化

2)开启B事务,更新数据,且不提交3d

这两条语句互相不影响,将这两个事务回滚掉,继续下一轮测试。blog


3)开启C事务,更新数据,且不提交索引

执行结果以下:事务

  1. 修改表结构

  1. 开启D事务,更新数据

执行时会发现表被锁住了.

  1. 将C事务提交或者回滚,这里我选择了回滚

7)C事务释放锁后,D事务更改为功,可是耗时很长。

结论与建议:

在执行alter table 操做时,事务会由并行变为串行,同时只能有一个事务更新表数据。尽可能选择流量小的时候执行alter 语句。而且要注意避开跑批等耗时较长的更新操做。在执行时最好先看一下有没有未提交的事务。

 

  • 更新单条语句
    MYSQL的锁是加在索引上的,若是update 语句中的where 未使用到索引,即会锁表。

按以下步骤执行测试:

Dsfp_order_jnl表 busi_serial字段不存在索引。

1)开启A事务,更新数据,且不提交

执行结果以下

 

2)开启B事务,更新数据,且不提交

B事务更新时锁超时。

结论与建议:

update语句必须使用索引,哪怕是更新很快的操做,否则在并发高时同样会致使问题。

 

 

  • 数据集合使用索引
    mysql对于数据集合使用索引时,存在内部优化策略,当你选择的数据范围较大时,会放弃使用索引,而扫描全表,若是是select for update,update,delete等操做就会锁定全表,影响业务。

范围数据有没有使用索引咱们可使用explain查询。

  1. 较小数据范围

Possible_keys表示查询可能使用哪些索引,key表示mysql决定采用哪一个索引对查询进行优化。Type range表示这是一个范围扫描。

  1. 扩大数据范围

此时虽然可使用索引,可是mysql最终选择了全表扫描。 type 为all,key为null.

对于查询咱们能够强制mysql放弃内部优化,使用咱们指定的索引。

  1. 使用强制索引

Update 语句与select 语句可使用相同的处理方式。

  1. 更新不使用强制索引

 

  1. 更细使用强制索引

Delete 语句不支持force index语法,咱们可使用limit 语句替代,limit语句会优先使用索引查找数据

  1. Delete不使用limit

  1. Delete使用limit

结论与建议:

在对批量数据进行操做时,先到生产环境或者1b1环境,对要执行的SQL进行一次explain看是否使用了索引。 select for update,update 可使用force_index。Delete 可使用limit。

相关文章
相关标签/搜索