1. 问题
使用mysqldump备份数据时,有时会看到 show processlist 出现大量的 Waiting for table flush,mysqldump被卡住。而且可能会导致查询也被卡住。
一个案例是执行备份:mysqldump -uroot -p --single-transaction --master-data=2 --set-gtid-purged=OFF testdb > /tmp/testdb.sql
然后show processlist:
当时立即把 mysqldump 的线程ctrl+c杀掉了。过一会儿 Waiting for table flush 状态全部消失。这次是运气好,没有出现应用大面积的SQL被阻塞。mysql自己恢复了正常。之前遇到过一次,最后只能重启了mysqld才解决。
所以 Waiting for table flush 也不可轻视,需要特别注意!!! 和 MDL:meta data lock 一样需要特别注意。
2. 出现 Waiting for table flush的原因
https://dev.mysql.com/doc/refman/5.6/en/general-thread-states.html
The thread is executing FLUSH TABLES
and is waiting for all threads to close their tables, or the thread got a notification that the underlying structure for a table has changed and it needs to reopen the table to get the new structure. However, to reopen the table, it must wait until all other threads have closed the table in question.
This notification takes place if another thread has used FLUSH TABLES
or one of the following statements on the table in question: FLUSH TABLES
, tbl_name
ALTER TABLE
, RENAME TABLE
, REPAIR TABLE
, ANALYZE TABLE
, or OPTIMIZE TABLE
.
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.
3. 如何避免 mysqldump 导致的 Waiting for tables flush
--master-data[=#]
This causes the binary log position and filename to be appended to the output. If equal to 1, will print it as a CHANGE MASTER
command; if equal to 2, that command will be prefixed with a comment symbol. This option will turn --lock-all-tables on, unless
--single-transaction is specified too (in which case a global read lock is only taken a short time at the beginning of the dump;
don't forget to read about --single-transaction below). In all cases, any action on logs will happen at the exact moment of the dump.
Option automatically turns --lock-tables off.
mysqldump 的 --singel-transaction 和 --master-data选项一起用时:
1)需要执行 flush tables !!!!
2)需要执行 flush tables with read lock !!!
而这里的 flush tables 很可能被大事务、慢查询 或者锁给卡住了,从而导致了 Waiting for table flush !!!!
一般 --single-transacation和 --master-data 一起用时为了搭建主从复制。不然也一般不会使用 --master-data 选项。其实可以使用xtrabackup备份来做主从复制,不存在该问题。
所以为了避免 mysqldump 导致 Waiting for table flush 问题,需要避免 将 --single-transacation 和 --master-data 选项一起使用!最安全的方式是只使用 --single-transaction选项。
4. Waiting for table flush导致的问题
flush tables 无法完成会出现 waiting for table flush状态,此时这个被 flush的表,即使是执行 select 语句也会被阻塞!!! 当然其他表还是可以正常的 select的。
5. Waiting for table flush 处理方法
出现Waiting for table flush时,我们一般需要找到那些表被lock住或那些慢查询导致flush table一直在等待而无法关闭该表。然后Kill掉对应的线程即可,但是如何精准定位是一个挑战,尤其是生产环境,你使用show processlist会看到大量的线程。让你眼花缭乱的,怎么一下子定位问题呢?
对于慢查询引起的其它线程处于Waiting for table flush状态的情形:
可以查看show processlist中Time值很大的线程。然后甄别确认后Kill掉。有种规律就是这个线程的Time列值必定比被阻塞的线程要高。这个就能过滤很多记录。
对于lock table read引起的其它线程处于Waiting for table flush状态的情形:
这种会话可能处于Sleep状态,而且它也不会出现在show engine innodb status \G命令的输出信息中。 即使show open tables where in_use >=1;能找到是那张表被lock住了,但是无法定位到具体的线程(连接),其实这个是一个头痛的问题。但是inntop这款利器就可以定位到,如下所示,线程17锁住了表test,在innotop里面就能定位到是线程17。所谓工欲善其事必先利其器!
参考:https://www.cnblogs.com/kerrycode/p/7388968.html
转自
Waiting for table flush 的原因及处理方法 - digdeep - 博客园
https://www.cnblogs.com/digdeep/p/12455757.html