首页 > 其他 > 详细

查询被锁住&执行慢

时间:2020-05-24 12:01:25      阅读:60      评论:0      收藏:0      [点我收藏+]
select * from t where id=1;

查询长时间不返回。

等MDL锁

技术分享图片

技术分享图片

  • 有一个线程正在表t上请求或者持有MDL写锁,把select语句堵住了

处理方式:找到谁持有MDL写锁,然后把它kill掉

查找方式:

  1. mysql启动时设置 performance_schema=on
  2. select blocking_pid from sys.schema_table_lock_waits;

等flush

技术分享图片

  1. session A,每行都调用一次sleep(1),默认要执行10万秒,期间表t一直是被session A“打开”着
  2. session B的flush tables t命令再要去关闭表t,就需要等session A的查询结束
  3. session C要再次查询的话,就会被flush 命令堵住了

技术分享图片

  • 有一个flush tables命令被别的语句堵住了,然后它又堵住了我们的select语句

等行锁

技术分享图片

技术分享图片

  • session A启动了事务,占有写锁,还不提交,是导致session B被堵住

查询谁占着这个写锁:
mysql5.7

select * from t sys.innodb_lock_waits where locked_table=`‘test‘.‘t‘`\G
  • 连接被断开的时候,会自动回滚这个连接里面正在执行的线程

查询慢

  1. 查询1
select * from t where id=1;

slow log:

技术分享图片

只查一行,却耗时800毫秒。


  1. 查询2
select * from t where id=1;

slow log:

技术分享图片

lock in share mode,为什么加锁相反更快?


技术分享图片

session A先用start transaction with consistent snapshot命令启动了一个事务,之后session B才开始执行update 语句。

session B执行完100万次update语句后,id=1这一行处于什么状态呢?

技术分享图片

session B更新完100万次,生成了100万个回滚日志(undo log)

  • 带lock in share mode的SQL语句,是当前读,因此会直接读到1000001这个结果,所以速度很快
  • 而select * from t where id=1这个语句,是一致性读,因此需要从1000001开始,依次执行undo log,执行了100万次以后,才将1这个结果返回

查询被锁住&执行慢

原文:https://www.cnblogs.com/KelvinFan/p/12946900.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!