MySQL 表锁解决
查看哪些表被锁,字段 In_use 表示有多少线程在使用这张表,字段 name_locked 表示表格是否被锁,0 代表锁定状态
mysql> show OPEN TABLES where In_use > 0;
+-------------+-----------------------+--------+-------------+
| Database | Table | In_use | Name_locked |
+-------------+-----------------------+--------+-------------+
| dsp_catalog | data_apply_statistics | 9 | 0 |
| dsp_catalog | data_apply_report | 3 | 0 |
+-------------+-----------------------+--------+-------------+
定位到这两张表,存在问题
data_apply_statistic、data_apply_report
查找当前信息
SHOW FULL PROCESSLIST; --full参数可以显示完整SQL信息
1、 这里首先定位 state 状态是 Waiting for table flush
2、找到 info 列 SQL 包含 data_apply_statistic、data_apply_report表的线程
kill + id
kill 4822226;
批量查出来
select
CONCAT ('kill ', id, ';'),
host,
db,
info
from
information_schema.processlist
where user = 'root'
and state = 'Sending data'
or state = 'Waiting for table flush'
and `TIME` > 1;
等待数秒,查看确认
mysql> show OPEN TABLES where In_use > 0;
好了,问题解决
此外还需要注意的 Waiting for table flush 和 MDL:meta data lock 也不可轻视,需要特别注意
- 出现 Waiting for table flush的原因
https://dev.mysql.com/doc/refman/5.6/en/general-thread-states.html
flush tables 语句需要或者 alter table,rename table,repair table,analyze table,optimize table 等DDL语句 需要关闭table,然后重新打开table,
而这些table可能会存在大的事务再执行,或者被锁住了,从而无法关闭 table,所以就出现了状态:Waiting for table flush
也就是说:需要执行 flush tables 的线程,因为某些原因无法关闭表,无法完成 flush tables,所以就 waiting for table flush - 解决方式
出现 Waiting for table flush 时,我们一般需要找到那些表被lock住或那些慢查询导致 flush table 一直在等待而无法关闭该表。然后Kill掉对应的线程即可,但是如何精准定位是一个挑战,尤其是生产环境,你使用 show processlist 会看到大量的线程。让你眼花缭乱的,怎么一下子定位问题呢?
对于慢查询引起的其它线程处于Waiting for table flush状态的情形:
可以查看 show processlist 中 time 值很大的线程。然后甄别确认后 Kill 掉。有种规律就是这个线程的 time 列值必定比被阻塞的线程要高。这个就能过滤很多记录。
03)注意
避免 mysqldump 的 --singel-transaction 和 --master-data 选项一起使用,除非主从搭建的时候,最安全的方式是只使用 --single-transaction 选项