0

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

任何关于为什么会发生这种锁定的提示将不胜感激!

4

1 回答 1

3

尝试显着减小查询缓存大小。1G可能太大了。

从 16M 或 32M 开始,并相应地调整 query_cache_limit(256K?)——随着读取性能的提高而向上移动,而不会在写入时达到“等待查询缓存锁定”。

“对于查询缓存的大小要谨慎,这会增加维护缓存所需的开销,可能超出启用它的好处。数十兆字节的大小通常是有益的。数百兆字节的大小可能不会。” http://dev.mysql.com/doc/refman/5.6/en/query-cache.html

于 2014-10-18T01:36:27.040 回答