数据更新导致锁表

 一、数据表结构

1
2
3
4
5
6
7
8
9
10
CREATE  TABLE  `jx_attach` (
   `attach_id`  int (11)  NOT  NULL  AUTO_INCREMENT,
   `feed_id`  int (11)  DEFAULT  NULL  ,
   `attach_name`  varchar (255)  NOT  NULL ,
   `cycore_file_id`  varchar (255)  DEFAULT  NULL 
   `attach_size`  bigint (20)  NOT  NULL  DEFAULT  '0' ,
   `complete`  smallint (6)  NOT  NULL  DEFAULT  '0'  ,
   PRIMARY  KEY  (`attach_id`),
   KEY  `jx_trend_attach_FK` (`feed_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=394160  DEFAULT  CHARSET=utf8;

二、现象

  当多个连接同时对一个表的数据进行更新操作,那么速度将会越来越慢,持续一段时间后将出现数据表被锁,从而影响到其它的查询及更新。  

存储过程循环30次更新操作

1
2
3
4
5
6
7
8
/*30次更新操作*/
BEGIN
   DECLARE  v1  INT  DEFAULT  30;
   WHILE v1 > 0 DO
     update  jx_attach  set  complete=1,attach_size=63100  where  cycore_file_id= '56677142da502cd8907eb58f' ;
     SET  v1 = v1 - 1;
   END  WHILE;
END

执行结果(速度非常慢)

时间: 29.876s

Procedure executed successfully
受影响的行: 0

 

200个数据更新操作,三个数据库连接同时执行

1
2
3
4
5
6
7
update  jx_attach  set  complete=1,attach_size=63100  where  cycore_file_id= '56677142da502cd8907eb58f' ;
  update  jx_attach  set  complete=1,attach_size=63100  where  cycore_file_id= '56677142da502cd8907eb58f' ;
  update  jx_attach  set  complete=1,attach_size=63100  where  cycore_file_id= '56677142da502cd8907eb58f' ;
  update  jx_attach  set  complete=1,attach_size=63100  where  cycore_file_id= '56677142da502cd8907eb58f' ;
  update  jx_attach  set  complete=1,attach_size=63100  where  cycore_file_id= '56677142da502cd8907eb58f' ;
  update  jx_attach  set  complete=1,attach_size=63100  where  cycore_file_id= '56677142da502cd8907eb58f' ;
...等等

执行结果(持续一段时间后速度越来越慢,出现等待锁) 

复制代码
 
 

# Time: 151208 22:41:24
# User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2
# Query_time: 1.848644 Lock_time: 0.780778 Rows_sent: 0 Rows_examined: 393382
SET timestamp=1449643284;
update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';

.........
........

# User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2 # Query_time: 2.868598 Lock_time: 1.558542 Rows_sent: 0 Rows_examined: 393382 SET timestamp=1449643805; update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f'; [root@localhost log]# tail -f slow_query.log # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 19 # Query_time: 1.356797 Lock_time: 0.000169 Rows_sent: 1 Rows_examined: 393383 SET timestamp=1449643805; SELECT * FROM jx_attach ja,jx_feed jf where ja.feed_id=jf.feed_id and ja.cycore_file_id='56677146da502cd8907eb5b7'; # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2 # Query_time: 2.868598 Lock_time: 1.558542 Rows_sent: 0 Rows_examined: 393382 SET timestamp=1449643805; update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
复制代码

 

 三、原因分析

MySQL的innodb存储引擎支持行级锁,innodb的行锁是通过给索引项加锁实现的,这就意味着只有通过索引条件检索数据时,innodb才使用行锁,否则使用表锁。根据当前的数据更新语句(update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';),该条件字段cycore_file_id并没有添加索引,所以导致数据表被锁。

 

四、解决办法

为cycore_file_id添加索引

 

五、最终效果(30次更新操作)

时间: 0.094s

Procedure executed successfully
受影响的行: 0

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 中,插入数据也有可能导致锁表的情况发生,特别是在高并发的场景下。以下是一些可能导致锁表的情况及相应的解决方法: 1. 级锁:当插入数据时,如果使用了级锁(如写锁),其他事务无法同时对同一张进行写操作,可能导致锁表。解决方法是尽量减少事务的持有锁的时间,将事务范围缩小到最小必要范围内。 2. 长事务:如果有一个事务在插入大量数据时持有锁资源,其他事务需要等待该事务完成才能继续操作,可能导致锁表。解决方法是将长时间运行的事务拆分为多个较短的事务,减少锁冲突的可能性。 3. 索引问题:插入数据时如果存在较多的索引,会增加索引更新的开销,可能导致锁表。解决方法是合理设计索引,避免过多的冗余索引,并根据实际情况选择合适的索引类型。 4. 死锁:在并发环境下,多个事务相互等待对方释放锁资源,形成死锁现象,导致锁表。解决方法是合理设计事务操作的顺序,尽量避免交叉依赖的操作,或者通过设置事务超时时间、死锁检测和自动回滚机制来解决死锁问题。 5. 数据库配置:如果数据库的连接池设置不合理,导致连接数过多或者超时时间过长,可能导致锁表。解决方法是合理设置数据库连接池参数,限制最大连接数和连接超时时间,避免资源竞争和长时间占用锁资源。 总的来说,要避免由插入数据导致锁表问题,需要合理设计事务范围、索引和数据库配置,并尽量减少事务持有锁的时间。同时,监控和调整数据库性能也是预防锁表问题的关键。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值