记一次mysql阻塞问题
表锁
show processlist 命令,看看当前语句处于什么状态。
Waiting for table metadata lock:这类问题的处理方式,就是找到谁持有 MDL 写锁,然后把它 kill 掉。
通过查询 sys.schema_table_lock_waits 这张表,我们就可以直接找出造成阻塞的 process id,把这个连接用 kill 命令断开即可。
mysql> select blocking_pid from sys.schema_table_lock_waits;
行锁
mysql> select * from t sys.innodb_lock_waits where locked_table='`test`.`t`'\G
如展示4 号线程是造成堵塞的罪魁祸首。而干掉这个罪魁祸首的方式,就是 KILL QUERY 4 或 KILL 4。
“KILL QUERY 4”。这个命令表示停止 4 号线程当前正在执行的语句,而这个方法其实是没有用的。因为占有行锁的是 update 语句,这个语句已经是之前执行完成了的,现在执行 KILL QUERY,无法让这个事务去掉 id=1 上的行锁。
KILL 4 才有效,也就是说直接断开这个连接。这里隐含的一个逻辑就是,连接被断开的时候,会自动回滚这个连接里面正在执行的线程,也就释放了 id=1 上的行锁。