mysql insert引起的表锁问题

记录mysql一次批量插入遇到的锁问题
  • 问题: 同事遇到对一个问题,由于线上需要刷新轨迹点常停留点的数据需求,具体常停留点定义的逻辑判断在此不叙述了,回到正题,这里通过spark离线将日志数据计算进hive,再按天为一个任务,执行多任务将hive数据刷入数据库。多个任务执行的时候,可能某个任务出现了问题停止了,这时删除这个任务一天的数据,然而其他任务还在跑插入.mysql会抛出:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction。

  • 测试: 先将测试表的建表语句贴出:
    CREATE TABLE test_yuhai ( id int(20) NOT NULL AUTO_INCREMENT, imei varchar(32) NOT NULL, alarm_tag int(11) NOT NULL DEFAULT '0', test_fied date DEFAULT NULL, PRIMARY KEY (id,imei), KEY ix_imei_alarm_tag (imei,alarm_tag) USING BTREE),作者数据库事务隔离级别是读已提交的。查看事务:select@@tx_isolation;如图:
    image
    首先将自动提交事务关闭。查看是否开启自动提交事务:SHOW VARIABLES LIKE ‘autocommit’;默认是ON开启的。image
    如果是OFF可以通过set autocommit=0关闭自动提交。假设一个A任务失败了,B任务还在插入,与此同时开启了C任务去删除A刷进来的那部分数据。

  • B任务在跑,事务未提交:begin;INSERT INTO test_yuhai(imei, alarm_tag, test_fied) VALUES ('11559', 0, '2019-10-18');image

  • C任务删除任务同时跑

  1. 删除未命中索引:begin; delete from test_yuhai WHERE test_fied='2019-10-14'; commit
    image
  2. 删除命中索引:begin; delete from test_yuhai WHERE id=1234;commit
    image
  • 查询锁表情况:show OPEN TABLES where In_use > 0;
    image

  • 结论:由上图可以看到如果一个事务插入并且尚未提交,另外一个事务在删除的话未命中索引会出现表锁的情况。等待超时也就会抛出这个锁等待超时的错。我还测试了insert对update、select、insert并不会有产生锁表情况(文中insert与update、select、insert类似关系都属于前后事务)

  • 延伸:如果insert会对delete有锁表的话,那么update会对其他操作有锁表的影响吗?各位看官可以自行实践,而且实践可以加深印象。这里作者还是根据本地测试直接给出结论:update对delete、update都是只会产生行锁.
    delete对update、delete产生表锁。

  • 总结:两个先后事务A、B.

  1. 如果A在insert操作对时候,会对B事务中的delete操作发生锁表情况.
  2. 如果A在delete操作的时候,会对B事务中的update、delete操作发生锁表的情况
  3. 如果A在update操作的时候,会对B事务中的delete、update操作发生锁表操作

(特别说明如果B后事务操作是delete则A前事务、B事务必须都要命中索引才会是行锁,否则都将产生表锁)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值