show processlist;发现大量阻塞状态的事务,提示Waiting for global read lock
过了一会又不锁了,检查了下发现所有的表都被锁了15分钟,期间没有任何的insert和update执行。因为我们的锁超时是15分钟,所以怀疑有人执行了FLUSH TABLES WITH READ LOCK锁全库的操作。
于是开启慢日志
SET GLOBAL log_slow_queries = ON;
SET GLOBAL long_query_time = 3;
set global slow_query_log_file='/opt/mysql/slow.log'
第二天又出现同样的问题,也是全库锁了15分钟,到数据库主机查看慢日志,发现果然在那个时段有人执行了FLUSH TABLES WITH READ LOCK的操作,然后15分钟后因为超时释放了。这个FLUSH TABLES WITH READ LOCK一旦数据库连接断开就会释放锁,后来定位是他们的备份程序里使用的,就让他们调整了备份时间。我们这边也加了定时发现锁表超时就自动先杀死线程的脚本。
看网上有说mysql备份时使用--master-data参数在SQL文件的头部会写入binlog和position信 息,所以在执行备份前mysql需要执行flush tables。flush tables with read lock 全局锁锁住整个数据库。如果数据库中有一个长查询在运行,那么FTWRL就不能获得,会被阻塞,进而阻塞所有的DML操作。
参考:MySQL备份导致的waiting for global read lock【图文】_aklaus_51CTO博客