【问题标题】:How to find root cause for "too many connections" error in MySQL/PHP如何在 MySQL/PHP 中找到“连接过多”错误的根本原因
【发布时间】:2010-04-15 09:33:09
【问题描述】:

我正在运行一个 Web 服务,该服务运行每天为数百万次调用提供服务的算法并运行一些后台处理。 时不时地,我在尝试连接到 MySQL 机器时看到“连接太多”错误“持续几秒钟。但这不一定归因于高流量时间或任何我可以发现的问题。

我想找到导致它的瓶颈。除了在特定时间发生这种情况外,服务器在 CPU 和内存方面的负载并没有太大,并且有 2-3 个连接(线程)打开并且一切正常。 (我使用Zabbix进行监控)

关于如何追踪它有什么创意吗?

【问题讨论】:

  • 您能否在非生产机器上重现该问题?你有一个压力测试环境,有合适的硬件箱和一个可以模拟生产负载的驱动系统吗?如果没有,请尽快获得一份。否则,您将不得不尝试在生产环境中对其进行调试,这将涉及执行高风险的操作,例如打开通用查询日志。
  • 更新 - 我已成功运行 SHOW PROCESSLIST,同时出现了太多连接问题。我得到的是:总共 151 个查询的列表(我的连接数设置为 150)。其中 2 个来自我的 PC(显示进程列表) 其余都是时间值为 374-395 的查询命令,除了一个状态为 FULLTEXT 的查询之外,它们的状态为 LOCKED 3 个查询为 UPDATE,其余均为 SELECT。我如何了解导致此锁定的原因?
  • 好吧,很难说出问题的原因是什么,但我很确定这是一个占用系统的查询。尝试查看其中哪些执行时间最长,哪些似乎重复了很多。之后,只需创建正确的索引并优化查询即可,但这里没有人能够在不查看架构和查询的情况下准确地告诉您该怎么做

标签: php mysql performance


【解决方案1】:

发生这种情况时尝试打开 mysql 控制台并发出

SHOW PROCESSLIST;
查看正在执行的查询。 或者,您可以启用记录慢速查询(在 my.cnf 中插入此行:
log-slow-queries=/var/log/mysql-log-slow-queries.log

在 [mysqld] 部分并使用

set-variable=long_query_time=1
定义查询应花费的最短时间才能被视为慢速。 (记得重启mysql以使更改生效)

【讨论】:

    【解决方案2】:

    您使用的是什么 MySQL 表类型? MyISAM 或 InnoDB(或另一个)? MyISAM 将使用表级锁定,因此您可能会遇到这样一个场景:您运行大量选择,然后更新同一个表和大量选择查询。最后的选择查询将不得不等到更新完成(这又必须等到第一个 - 重 - 选择完成)。

    对于 InnoDB,像 innotop 这样的工具可能有助于找出死锁的原因(请参阅 http://www.xaprb.com/blog/2006/07/31/how-to-analyze-innodb-mysql-locks/)。

    顺便说一句,导致锁定发生的查询应该是未处于锁定状态的查询之一。

    【讨论】:

    • 我在 MyISAM 的表,+ 一些内存表。
    • SHOW PROCESSLIST 给了我许多处于锁定状态的查询和一个处于 FULLTEXT 初始化状态的查询。后者具有最低的进程 ID。确定与此进程关联的查询是锁定查询吗?
    • 应该是,处于LOCKED状态的正在等待其他查询完成。
    【解决方案3】:

    SHOW OPEN TABLES 命令将显示 MySQL 中所有表的锁定状态。如果您的一个或多个查询导致连接回锁,则将SHOW PROCESSLIST 和打开的表结合起来应该可以缩小范围,以确定究竟是哪个查询阻止了工作。

    【讨论】:

    • 发生错误时我已经完成了 SHOW OPEN TABLES。我得到 table_name 148 0 我可以假设这张表是锁定的吗?并且所有连接都在对该表的查询中被阻止?
    • '148' 表示您在该特定表上有 148 个活动和/或挂起的锁。如果是 InnoDB 没什么大不了的,因为该引擎可以进行行级锁定,但如果是 MyISAM 则很重要,因为它只能进行表级锁定。如果是 InnoDB,您可以通过 SHOW INNODB STATUS 查看活动查询/锁定是什么。部分输出是查询和错误/锁定列表。
    【解决方案4】:

    老话题。但是,我刚刚遇到了这个问题,这是因为我每天安排了 3 次 mysqldump 脚本。在这些时候,如果我的 Web 应用程序也获得了相当多的使用量,那么所有 Web 应用程序查询只是将它们自己排在彼此之上,而 mysqldump 正在锁定数据库中的所有表。最好的选择是在单独的机器上设置复制从属服务器,并从从属服务器而不是生产服务器获取备份。

    【讨论】:

      【解决方案5】:

      可能与 MySQL 中的 FULLTEXT 搜索错误有关: http://bugs.mysql.com/bug.php?id=37067

      在这种情况下,FULLTEXT 初始化实际上会挂起 MySQL。不幸的是,似乎没有解决方案。

      【讨论】:

        【解决方案6】:

        在不了解您的实现以及一般 PHP 的情况下,您确定您没有任何关于延迟数据库连接的问题吗?例如,即使在请求已处理后仍保持打开的连接?

        在 PHP 中,连接通常会在脚本结束或调用 mysql_close($conn); 时自动关闭,但如果您使用任何类型的本地连接池,则可能会带来问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多