3

我们有一个应用程序,它由几个现成的 PHP 应用程序(ExpressionEngine 和 XCart)以及我们自己的自定义代码组成。

我没有进行实际分析,所以我不知道它是如何确定的,但听到太多 MySQL 连接未关闭并不感到惊讶(我并不感到惊讶,因为我在我们的开发人员中看到了严重的内存泄漏服务器,在一两天的过程中,从初始启动时的 100MB 开始,内存的整个 gig 都被消耗掉了,而且只有很少一部分被缓存)。

那么,我们如何才能准确地确定哪些 PHP 代码是罪魁祸首呢?我以前有使用 XDebug 的经验,并建议当我们获​​得相当稳定的单独的暂存环境时,我们在 dev 上改进 XDebug 并使用它来进行一些分析。这是合理的,和/或其他人有更具体和/或额外的建议吗?

4

6 回答 6

4

您可以使用

 SHOW PROCESSLIST  

SQL 命令查看正在运行的进程。这将告诉您每个进程正在使用的用户名、主机、数据库等。这应该让您知道发生了什么,尤其是在您访问多个数据库的情况下。

更多信息:https ://dev.mysql.com/doc/refman/8.0/en/show-processlist.html

于 2009-10-29T13:45:38.633 回答
2

这不应该是由 php 代码引起的,因为 mysql 连接应该是自动关闭的。

cf:http ://www.php.net/manual/function.mysql-connect.php:

到服务器的链接将在脚本执行结束后立即关闭,除非它通过显式调用 mysql_close() 提前关闭。

一些建议:

  • 您的开发人员在技术上是否可以直接访问您的生产 mysql 服务器?如果是,那么他们可能只是让他们的 Mysql 管理器保持打开状态 :)
  • 你有一些日常批处理吗?如果是,也许内存中有一些僵尸进程
于 2009-10-29T13:26:53.793 回答
1

I used to run a script that polled SHOW STATUS for thread count and I noticed that using mysql_pconnect always encouraged high numbers of threads. I found that very disconcerting because then I couldn't tell when my connection rate was actually dropping. So I made sure to centralize all the places where mysql_connect() was called and eliminate mysql_pconnect().

The next thing I did was look at the connection timeouts and adjust them to more like 30 seconds because. So I adjusted my my.cnf with

connect-timeout=30

so I could actually see the number of connections drop off. To determine the number of connections you need open is dependent on how many apache workers you're running times the number of database connections they each will open.

The other thing I started doing was adding a note to my queries in order to spot them in SHOW PROCESSLIST or mytop, I would add a note column to my results like:

$q = "SELECT '".__FILE__.'.'.__LINE__."' as _info, * FROM table ...";

This would show me the file issuing the query when I looked at mytop, and it didn't foil the MySQL query cache like using

/* __FILE__.'.'.__LINE__ */ 

at the start of my query would.

于 2009-10-30T06:34:01.940 回答
1

当页面结束时,PHP 会自动关闭任何 mysql 连接。PHP Web 应用程序有太多未关闭的 mysql 连接的唯一原因是 1)您正在使用连接池,或者 2)mysql 服务器或连接器中存在错误。

但如果您真的想查看您的代码以找到它的连接位置,请参阅http://xdebug.org/docs/profiler

于 2009-10-29T13:28:05.820 回答
1

正如其他人所说,PHP 终止通过mysql_connectmsqli/PDO 等效项创建的 MySQL 连接。

但是,您可以使用mysql_pconnect. 它将寻找打开的现有连接并使用它们;如果找不到,它将打开一个新的。如果您一次有很多请求,则可能会导致大量连接打开并保持打开状态。

您可以降低最大连接数,或降低持久连接的超时时间。有关更多详细信息,请参阅手册页底部的注释。

于 2009-10-29T13:45:38.653 回答
0

我想我可以做的另外几件事,关于一般内存问题,而不是专门针对 MySQL,特别是在我们自己的自定义代码的上下文中,将通过调用其中一个或另一个来包装我们的代码以下 PHP 内置函数:

memory_get_usage

memory_get_peak_usage

特别是因为我目前正在处理一些自定义代码的日志记录,所以我可以在使用它时记录内存使用情况

于 2009-10-29T14:17:39.910 回答