【问题标题】:Mysql resource temporarily unavailablemysql资源暂时不可用
【发布时间】:2012-04-25 06:34:04
【问题描述】:

我在高负载时间看到了其中一些错误:

mysql_connect() [<a
href='function.mysql-connect'>function.mysql-connect</a>]: [2002] Resource
temporarily unavailable (trying to connect via
unix:///var/lib/mysql/mysql.sock)

据我所知,mysql 服务器没有达到其最大连接数限制,但还有其他东西阻止它为查询提供服务。 MySQL 还会遇到哪些其他限制?

我正在运行 RHEL 6.2 64 位和 MySQL 5.5.21

【问题讨论】:

  • 可能是mysql服务器的bug?这也可能是 mysql 服务器如何处理有大量问题的请求的结果,例如根据某些时钟测量,请求几乎是同时的。
  • 您是在重复使用连接还是只是打开新连接?如果没有一些代码,就很难有根据地猜测出了什么问题。
  • 连接在 php 请求中不是持久的。我在某处读到 mysql 文件描述符用完,但我不确定如何检查。
  • 你能查一下mysql的日志吗,也许能提示问题。

标签: mysql


【解决方案1】:

假设您的系统当前是基于 Unix 的(如您的问题陈述中所述)。如果这是正确的,那么您可能会遇到以下问题:

  1. 您已经用完了可供 MySQL 使用的memory

    这是您最可能面临的问题。 MySQL 连接池中的每个连接都需要内存才能运行,如果此资源耗尽,则无法建立进一步的连接。当然,如果您发现这是一个问题,可以在your equivalent to my.cnf 中调整各种操作的内存占用和最大数据包大小。

    Here's an additional thread that can help there,但您也可以考虑使用更简单的分析工具(例如 top)来对正在发生的事情进行大致估计。

  2. 您的 MySQL 用户帐户可用的 file descriptors 已用完。

    另一个常见问题:如果您尝试处理要求文件 IO 超过 1,024 边界(默认情况下)的请求,您将遇到操作简单失败的情况。这是因为大多数系统都对每个用户一次可以使用的打开文件描述符的数量指定了软限制和硬限制,超过此阈值可能会导致问题。

    这通常会在您的日志文件中包含一系列明显的迹象。检查/var/log/messages 和您的类似目录(例如,/var/log/mysql 看看您是否能找到任何有趣的东西。

  3. 您遇到了livelock or deadlock 场景,您的线程无法满足。

    内存和文件描述符耗尽的必然结果是,如果您超出了系统能够处理的计算负载,线程可能会超时。它不会抛出此错误消息,但这是将来要注意的事情。

  4. 您的系统已用完可用于fork 的 PID。

    另一种常见情况:fork 在任何给定时间只有这么多的 PID 可供使用。如果您的系统只是overforked,它将无法处理请求。

    最简单的检查方法是查看是否有任何其他服务可以连接到机器。例如,尝试通过 SSH 连接到盒子并发现您无法使用是一个很大的线索。

  5. 上游代理或连接管理器已耗尽资源并停止服务请求。

    如果您的客户端和 MySQL 之间有任何服务层,则需要检查它是否已崩溃、挂起或以其他方式变得不稳定。以上建议适用。

  6. 你的端口映射器已经用尽了after 65,536 connections

    不太可能,但同样,可能是用尽情况。像上面这样检查琐碎的服务连接,嗯,这里也是最好的停靠港。

简而言之:这是一种资源耗尽的情况,包括服务器只是“停机”。您将不得不进一步分析您的系统以查看您正在阻止的内容。在这种情况下,给我们的所有错误消息都是资源对客户端不可用的事实——我们需要查看有关服务器的更多信息以确定更充分的补救措施。

【讨论】:

  • 谢谢,非常有帮助,但你能指出我在正确的地方进行测试吗?我怀疑我的内存已经用完了(我们每台服务器都有 12GB 内存),但我需要查看其他的。
  • @Noodles 会的。我需要先处理一些事情,但希望在接下来的一个小时左右,我会回到我的答案中提取更多文档。 :)
  • 我的答案已更新。我的时间估计有点偏离,但这应该足以帮助进行故障排除。如果您需要更中肯、更具体的建议,请告诉我。我很乐意通过 SO 聊天让自己有空。
  • 嗯...我浏览了您的建议,看不到任何明显的问题。我开始研究文件描述符限制,但“cat /proc/sys/fs/file-max”显示 1200877 而“lsof -u mysql | wc -l”显示 2862,所以它离限制还很远。 Apache 和 MySQL 之间没有层(在同一个盒子上),使用 Xymon 看起来内存并没有用完。还有其他建议吗?
  • @Noodles 在这种情况下,我建议尝试mysqlslap 并查看日志文件中的内容。这是an additional page of info,可能会有所帮助。如果这不起作用,则需要进行连接级别的故障排除,因为这可能不是您的 MySQL 服务器的问题。
【解决方案2】:

我仍然没有找到它所达到的限制,但我确实设法解决了这个问题。使用 MEMORY 引擎的会话表(在 vbulletin 中)存在问题。该表的索引是 HASH,因此当 vbulletin 每小时清除该表一次时,它会锁定该表的时间刚好足以阻止其他查询并将 mysql 推到其资源的限制。

通过将索引更改为 BTREE,这允许 MySQL 更快地从会话表中删除行,并避免之前达到的任何限制。当我们将主数据库服务器升级到 MySQL 5.5 时,错误才开始出现,所以我猜 MEMORY 表在最新版本中的处理方式有所不同。

有关使用 BTREE 索引而不是 HASH For MEMORY 来提高速度的信息,请参阅 http://www.mysqlperformanceblog.com/2008/02/01/performance-gotcha-of-mysql-memory-tables/

【讨论】:

    【解决方案3】:

    天哪,这可能有很多东西。可能是套接字缓冲区空间已用完。可能是mysql 接受连接的速度不如它们进来的快,并且达到了积压限制(尽管我希望这会给你一个“拒绝连接”错误,但我不确定那是什么你会得到一个 Unix 域套接字)。这可能是@MrGomez 指出的任何事情。

    由于您在同一台服务器上运行 Apache 和 MySQL,这在高负载下是一个问题,很可能是 Apache 正在耗尽系统的某些资源,而您只是没有看到(注意到?)丢弃/日志中的传入连接/请求失败。

    您是否使用连接池?如果没有,我会从那里开始。

    我还会在 Apache 日志和 syslog 中与 mysql_connect 错误同时查找错误,然后看看还会出现什么。我特别建议将 MySQL 转移到它自己独立的专用服务器上。

    【讨论】:

      【解决方案4】:

      就我而言,我正在使用 JSON 数据类型和 PDO(PHP 驱动程序)。 我正在使用fetch 检索一项,但忘记将LIMIT 1 添加到查询中。添加它解决了问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-21
        • 2018-08-04
        • 2021-05-07
        • 2018-02-24
        • 2016-01-25
        • 2018-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多