查询被锁住&执行慢
Posted kelvinfan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了查询被锁住&执行慢相关的知识,希望对你有一定的参考价值。
select * from t where id=1;
查询长时间不返回。
等MDL锁
- 有一个线程正在表t上请求或者持有MDL写锁,把select语句堵住了
处理方式:找到谁持有MDL写锁,然后把它kill掉
查找方式:
- mysql启动时设置 performance_schema=on
select blocking_pid from sys.schema_table_lock_waits;
等flush
- session A,每行都调用一次sleep(1),默认要执行10万秒,期间表t一直是被session A“打开”着
- session B的flush tables t命令再要去关闭表t,就需要等session A的查询结束
- 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
select * from t where id=1;
slow log:
只查一行,却耗时800毫秒。
- 查询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这个结果返回
以上是关于查询被锁住&执行慢的主要内容,如果未能解决你的问题,请参考以下文章