Kaze
Kaze
Published on 2023-10-20 / 15 Visits
0
0

19为什么我只查一行的语句,也执行这么慢?

文章地址

show processlist 命令可以查看语句的执行状态,当语句长时间无响应时可以使用此命令排查原因

Waiting for table metadata lock

这个状态表示的是,现在有一个线程正在表上请求或者持有 MDL 写锁,把 select 语句堵住了。

通过查询 sys.schema_table_lock_waits 这张表,我们就可以直接找出造成阻塞的 process id,把这个连接用 kill 命令断开即可。

select blocking_pid from sys.schema_table_lock_waits;

如果要使用这条语句,MySQL 启动时需要设置 performance_schema=on,相比于设置为 off 会有 10% 左右的性能损失

Waiting for table flush

对表做 flush 操作的用法,一般有以下两个:

flush tables t with read lock;

flush tables with read lock;

如果指定表 t 的话,代表的是只关闭表 t;如果没有指定具体的表名,则表示关闭 MySQL 里所有打开的表。

正常flush语句执行很快,除非被其他语句堵住了

出现 Waiting for table flush 状态的可能情况是:有一个 flush tables 命令被别的语句堵住了,然后它又堵住了我们的 select 语句。

等行锁

select k from t where id=1 lock in share mode;

读锁(S 锁,共享锁)

select k from t where id=1 for update;

写锁(X 锁,排他锁)

select 语句如果加锁,是当前读;

通过 sys.innodb_lock_waits 查行锁:

select * from sys.innodb_lock_waits where locked_table='test.t'\G


Comment