查询被锁住&执行慢

Posted kelvinfan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了查询被锁住&执行慢相关的知识,希望对你有一定的参考价值。

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这个结果返回

以上是关于查询被锁住&执行慢的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver怎么用sql查看具体那个表被锁住了

oracle表在啥情况下会被锁住

mysql查看被锁住的表

mysql查看被锁住的表

oracle表被锁了怎么处理?

oracle 表锁住了啥原因