【发布时间】:2013-08-12 10:03:44
【问题描述】:
MySQL 服务器似乎不断锁定并停止响应某些类型的查询,并最终(在几分钟未响应后)放弃错误“MySQL 服务器已消失”,然后再次挂起下一组查询,一次又一次。服务器设置为从属服务器,从主服务器复制到dbA,主要是 INSERT 语句,每秒大约 5-10 行。一个基于 PHP 的应用程序正在服务器上运行,它每 5-10 秒读取一次新复制的数据,对其进行处理并存储(在重复键更新时插入)结果到一个单独的数据库 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 正在流式传输(无缓冲)新复制的数据以进行处理。查询 #3 最终产生错误“MySQL 服务器已消失”,大概是因为它是第一个超时的。
它看起来像是某种死锁,但我不明白为什么。在一个数据库中同时进行 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 DUPLICATE KEY UPDATE。
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
任何关于为什么会发生这种锁定的提示将不胜感激!
【问题讨论】:
-
DBA 部分发布了同样的问题,但一周后没有回复。也许这里更适合。
-
我遇到了同样的问题(稍微不那么严重),到目前为止我发现的唯一“解决方案”是禁用查询缓存......
-
@Vatev 感谢分享!同时我也禁用了查询缓存,因为它是目前唯一的解决方法。我仍然对为什么会发生这种情况感到困惑......
标签: mysql deadlock database-replication mysql-5.5 database-caching