美文网首页
记一次线上死锁

记一次线上死锁

作者: 史小猿 | 来源:发表于2018-12-21 16:59 被阅读13次

    项目做了什么

    这个项目是为了处理一些任务,实现是启动定时任务去处理这些数据,因为项目上线后是集群的,所以为了避免多个节点处理到相同的数据,我们使用select ... where state =0 for update limit 500 来锁住数据,然后update state =2值。这样其他节点就不会重复处理数据了

    同事定时任务的代码大概是这样的,我这里用伪代码表示

    @Transaction //注意使用for update一定要在事务里边
    processData(){
    bikeIds = findForUpdate();//select * from test_rawdata where state=0 for update limit 500;
    //取出数据,然后先状态改成2
    updateData(bikeIds);//update test_rawdata set state = 2 where bikeId in(bikeIds);
    
    }
    

    除了这个地方操作db外,其他地方也有insert delete,所以for update的where条件里必须要有索引,因为如果where 里的字段没有索引的话,for update就不是行锁了,就升级成表锁了。
    那当处理定时任务时,insert和delete都将会被阻塞,这样并发性太弱了。

    CREATE TABLE `test_rawdata` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `bikeId` varchar(15) NOT NULL COMMENT '车id',
      `lat` decimal(11,8) NOT NULL DEFAULT '0.00000000' COMMENT '纬度',
      `lng` decimal(11,8) NOT NULL DEFAULT '0.00000000' COMMENT '经度',
      `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建更新时间,默认当前时间',
      `state` int(8) NOT NULL DEFAULT '0' COMMENT '0表示未处理 1处理中',
      `accuracy` smallint(6) NOT NULL DEFAULT '0' COMMENT '位置精确度',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uniq_bikeid` (`bikeId`),
      KEY `idx_time` (`update_time`) USING BTREE,
      KEY `idx_state` (`state`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8897633 DEFAULT CHARSET=utf8 COMMENT='车辆原始位置';
    
    db记录

    trx1

    set autocommit = 0;
    begin;
    select * from test_rawdata where state=0 for update;
    select sleep(8);
    update test_rawdata set state = 2 where bikeId = "7fd9gSBkZ1";
    commit;
    

    trx

    set autocommit = 0;
    begin;
    delete from test_rawdata where bikeId = '7fd9gSBkZ1'; //在trx sleep时间点执行
    commit;
    
    

    发生死锁
    死锁日志


    参考链接
    innodb的锁 https://zhuanlan.zhihu.com/p/31875702
    索引和锁 https://zhuanlan.zhihu.com/p/40396971
    https://www.jianshu.com/p/1dc4250c6f6f

    相关文章

      网友评论

          本文标题:记一次线上死锁

          本文链接:https://www.haomeiwen.com/subject/cprykqtx.html