【问题标题】:SELECT + INSERT + Query Cache = MySQL lock upSELECT + INSERT + 查询缓存 = MySQL 锁定
【发布时间】: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


【解决方案1】:

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

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

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

【讨论】:

  • 这不是一个有用的答案。问题不在于查询缓存的效率,而是与使用缓存相关的特定死锁问题。你应该花更多的时间来理解问题,而不是使用你的复制和粘贴技能,希望它能有所帮助。
  • @dezlov 死锁“等待查询缓存锁”通常来自查询缓存上的写争用,因为它太大并且 mysql 花费更多时间使该缓存无效,因此减小了大小将缓存设置为性能最低的值是要走的路。
  • 我想告诉你关于 Mysql 的 2 个要点 a) 锁:检查 this 以了解 select insert 和 update 是否会导致锁。 b) 查询缓存:如果查询缓存太大,会因为缓存开销和锁而导致性能下降。因此,查询缓存越大,在缓存管理之前用于锁定、刷新和开销的系统时间就越多,这会抵消查询缓存的任何好处并降低数据库吞吐量。如果您遇到随机锁定,请尝试禁用查询缓存,看看是否能解决问题。
猜你喜欢
  • 2011-07-18
  • 2014-04-11
  • 2012-02-26
  • 1970-01-01
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 2011-03-13
相关资源
最近更新 更多