MySQL 服务器似乎不断锁定并停止响应某些类型的查询,最终(在几分钟没有响应后)放弃错误“ MySQL 服务器已消失”,然后再次挂起下一组查询,再次然后再次。服务器设置为从属服务器,从主服务器复制到dbA
,主要是 INSERT 语句,每秒大约 5-10 行。一个基于 PHP 的应用程序正在服务器上运行,它每 5-10 秒读取一次新复制的数据,对其进行处理并将结果存储在一个单独的数据库中(INSERT ON DUPLICATE KEY UPDATE)dbB
. 所有表都使用 MyISAM 引擎。Web 应用程序为用户显示后处理的数据。在基本术语中,所涉及的处理步骤是将每秒分辨率的时间序列数据压缩为每分钟、每小时和每天的分辨率。
当 MySQL 锁定时,我执行 SHOW PROCESSLIST 命令并看到以下查询:
N User Time Status SQL query
1 system user XX update INSERT INTO `dbA`.`tableA` (...) VALUES (...)
2 ???? XX Waiting for query cache lock INSERT INTO `dbB`.`tableB` (...) VALUES (...) ON DUPLICATE KEY UPDATE ...
3 ???? XX Writing to net SELECT ... FROM `dbA`.`tableA` WHERE ... ORDER BY ...
“时间”列将保持同步,直到达到某种查询等待超时,然后我们得到错误“ MySQL 服务器已消失”。在 5-10 秒内,将再次处理新数据,同样的锁定将发生。查询 #1 是复制过程。查询#2 是后处理数据的更新。查询 #3 正在流式传输(无缓冲)新复制的数据以进行处理。最终产生错误“ MySQL server has gone away ”的是查询#3,大概是因为它是第一个超时的。
它看起来像某种死锁,但我不明白为什么。在一个数据库中同时进行 SELECT 和 INSERT 似乎会导致死锁,并在另一个数据库中通过 INSERT ON DUPLICATE KEY UPDATE 更新查询缓存。如果我关闭复制或查询缓存,则不会发生锁定。平台:Debian 7、MySQL 5.5.31、PHP 5.4.4 - 所有标准包。值得注意的是,几乎相同的应用程序目前在Debian 6、MySQL 5.1.66、PHP 5.3.3上运行良好,唯一的区别在于后处理数据是使用单独的 INSERT 和 UPDATE 查询而不是 INSERT ON 存储的重复密钥更新。
MySQL 配置(在 Debian 6 和 7 机器上):
key_buffer_size = 2G
max_allowed_packet = 16M
thread_cache_size = 64
max_connections = 200
query_cache_limit = 2M
query_cache_size = 1G
任何关于为什么会发生这种锁定的提示将不胜感激!