MySQL执行时间峰值

我今天突然遇到了MySQL问题。

细节:

  • 操作系统:CentOS版本5.7
  • 服务器types:运行在中等DV 4.0包上的Parallels virtuozzo容器
  • 平均总内存使用量:<500MB
  • 允许的总内存使用量:1GB(部分共享池只用于紧急情况,用户只能保证500MB)
  • 处理器:> 1ghz
  • 主要数据库大小使用最多:275MB和107MB
  • 服务器堆栈:nginx 1.0.10,mysql 5.1.54,php 5.3.8和php-fpm
  • innodb_buffer_pool_size = 100M
  • php-fpm最大的孩子:5
  • Webapps:自定义的基于php的网站,magento和drupal
  • 慢查询超时设置为1秒

我完成了诊断的步骤:

  1. 现在还不能重启容器 – 我今晚晚些时候我们国内的stream量会下降
  2. 启用mysql和php-fpm slowlog。
  3. 在php-fpm slowlog中发现数据库查询的函数时间超过1秒
  4. 在mysql slowlog中发现了一些简单的查询,花费1秒以上完成应该less于1秒。
  5. 最有趣的是 – 执行时间似乎有时会激增。 一个查询将花费几秒钟的时间,然后一次花费8秒来运行相同的查询。 这些结果已经通过mysql命令行运行原始SQL查询来validation。
  6. 顶部没有透露任何有趣的事情
  7. 只有资源相关的东西,我可以看到负载平均比正常高得多
  8. 直到今天,mysql已经很好,自从昨天以来,db一直没有大的变化。
  9. 有时候,事情太糟糕了,在60秒的执行时间之后,我看到了错误的网关错误。
  10. Innodb的平均读取速度为300-1400次/秒。
  11. Mysql正在做3-10查询/秒
  12. 在2小时内查询计数慢,正常运行时间为171(在1秒内缓慢超时)
  13. 试图重新启动mysql,nginx,php-fpm多次

例如:

UPDATE `catalogsearch_query` SET `query_text` = 'EW 90', `num_results` = '7532', `popularity` = '99180', `redirect` = NULL, `synonym_for` = NULL, `store_id` = '1', `display_in_terms` = '1', `is_active` = '1', `is_processed` = '1', `updated_at` = '2012-05-08 21:38:31' WHERE (query_id='31'); 

这个查询花了17秒完成一次,剩下的时间在0.079秒左右。 但是,有时会变化,有时1秒,有时0.004秒。 这是运行相同的查询,每个之间几秒钟一遍又一遍。

大多数表是innodb,有时我注意到locking时间占查询执行时间的90%,但大部分时间locking时间是微不足道的。

任何想法发生了什么?

听起来几乎肯定是一个外围的问题,影响正在发生的事情,在像VPS这样的受限制和竞争的环境中运行Magento相当典型。

如果您的configuration以前运行良好,并且您没有更改任何代码或安装任何扩展程序 – 那么这将是一个外部影响,很可能是stream量增加 – 但是对于VPS,它可能会增加I / O活动。

这听起来就像I / O等待 – 只需安装一个像Munin这样的graphics工具就可以certificate这一点(显示与I / O活动/等待的MySQL缓慢查询相关)。

我会参考几个其他职位相同的徒劳 – 在VPS中运行Magento总是产生类似的行为。

  1. https://serverfault.com/a/368649/113375
  2. https://serverfault.com/a/367861/113375
  3. https://stackoverflow.com/a/8216096

最可能的两个问题是:

1)您的查询被另一个查询阻止 – 请检查您的慢查询日志中是否启动了更新

2)您的虚拟机没有被主机计划。 设置看门狗脚本,将心跳写入日志文件

可能还有其他的原因,但除非你能消除上面的两点,否则没有太多的意义。

在解决问题方面,前者只是查询调优的问题,后者则需要与pipe理主机的人进行交stream。

什么:

 SHOW CREATE TABLE catalogsearch_query\G SHOW INNODB STATUS; SELECT * FROM information_schema.PROCESSLIST WHERE State='Locked' ORDER BY Time; 

看起来像 ?

我怀疑你会被悬挂的“开放表/closures表”问题所打击。 我不会重新启动你的数据库太多,这将需要时间来热身,尤其是当做大量的更新。

为了使它完成,我也很想看到这一点:

 SHOW STATUS LIKE '%cache%'; SHOW STATUS LIKE '%table%'; 

而所有这一切的麻烦,我会打赌你,当你遇到麻烦,做一个“冲桌子”; ,这将需要很长时间。

一些重要的configuration参数将加速处理:

 innodb_log_buffer_size = 16M innodb_file_per_table = 1 innodb_open_files = 16000 innodb_io_capacity = 400 innodb_flush_log_at_trx_commit = 2 innodb_flush_method = O_DIRECT innodb_thread_concurrency=8 innodb_lock_wait_timeout = 90 

(XtraDB)特别是,per_table的设置是非常激烈的,但是只会影响到新的表格,如果你想让它们在自己的innodb中,你需要重新创build问题表格。 与O_DIRECT flush方法和trx_commit = 2(先读这个!)一起,将加速严重的事情,特别是大的更新/插入。

希望这可以帮助。