Flush tables:Closes all open tables, forces all tables in use to be closed, and flushes the query cache. FLUSH TABLES also removes all query results from the query cache, like the RESET QUERY CACHE statement
SQL语句在执行前,都会打开相应的表对象,如select * from t1语句,会找到t1表的frm文件,并打开表内存对象。
为了控制表对象使用的内存空间和其他资源,MySQL会隐式(后台表对象管理线程)或显式(flush tables等)来关闭已打开但并没有使用的表对象。
然而,正在使用的表对象是不能关闭的(如SQL请求仍在运行),此时,Flush Tables操作会被正在运行的SQL请求阻塞
测试:
1,FLUSH TABLES
会话1:select sleep(30) from t limit 1; -- 正在执行
会话2:flush tables; -- 等待会话1
会话3:select * from t limit 1;-- 等待会话1,会话2结束
会话n: 执行其他表的任意操作,不阻塞
可以看到flush tables 会阻塞,直到之前正在执行的会话结束,但是不影响别的会话
2,FLUSH TABLES WITH READ LOCK;
会话1:select sleep(30) from t limit 1; -- 正在执行
会话2:FLUSH TABLES WITH READ LOCK -- 等待会话1
会话3:select * from t limit 1;-- 等待会话1,会话2结束
会话n: 执行其他表的任意操作,读不阻塞,所有写阻塞,直到执行UNLOCK TABLES;
从上可以看到,FLUSH TABLES WITH READ LOCK执行完之后,读不影响,所有写阻塞