0

我会尽量简短,但仍然完整。提前感谢那些花费宝贵时间向我指出可能的解决方案的人。


Ubuntu 环境下的 PHP/Mysql 应用程序。

原始问题:

Keep getting error 'to_many_connections'.

当我检查时:

show processlist;

有很多睡眠过程。所以我认为这些是 to_many_connections 错误的原因,因为它们会阻止任何新的传入连接。

更改 mysql 设置:

Raise max_connections from 250 to 400;
lower wait_timeout from 60 to 15;

连接似乎有效,但现在我的 apache 占用了内存。只需更改这 2 个设置,它就从 11G 增加到了 25G 以上。我无法想象 150 个额外的 mysql_connections 占用 14G 的额外内存?我也不希望 wait_timeout 设置较低会增加 apache 的内存使用量。它应该在内存中保持更少的连接,因此使用更少的内存?我预计进程使用率会上升,但内存不会。当然不是那些巨额。

尝试重新设置 mysql 设置:

keep max_connections at 400
raise wait_timeout to 30 sec

内存使用量下降了大约 5 分钟,但之后又上升了。

其他注意事项:

我注意到某个表有很多锁定的进程。(mysql: show processlist;) update: table 是一个 MyISSAM 表。

我还更改了一些不太理想的数据库实现,有些页面使用 2 个连接到数据库,因为我们正在经历代码重构阶段。从 mysql_query 功能切换到 PDO 功能

更新:

新的 pdo 功能将持久连接专门设置为 false(即使它默认为 false),旧的 mysql 功能也不使用持久连接。

    public function __construct($dbname, $username, $password) {
        parent::__construct('mysql:hostname=localhost;dbname=' . $dbname . ';', $username, $password, array(
            PDO::ATTR_PERSISTENT => false,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8;"
        ));
    }

我很清楚与数据库建立多个连接远非最佳实践,但我们当前的应用程序缺少很多设计模式,一切仍然是程序性的,没有 mvc,没有 OOP。我有义务这样做,因为我的雇主想要结果,并且此刻,无意对我们的应用程序进行完全重写,以使用很久以前就应该实施的设计/编码标准。 无论如何,如果这段代码是真正的原因,我会感到惊讶,因为它已经运行了一个多星期,而且由于讨价还价期(1 个月的巨额讨价还价/交易),我们在那一周进行了大量访问在我们的商店)。

对此事的任何见解将不胜感激。截至目前,我不知道下一步可能会解决这个问题。

update2 因发现问题而关闭,但与原始帖子无关。

4

1 回答 1

1

我对你有这些大而复杂的问题感到同情!我会补充一些东西,看看你是否尝试过

  • re: apache memory - 我最近一直在做的 apache 测试,实际上指向降低 MaxClients 的数量,在 ab 或 siege 测试下,我实际上在我的测试环境中获得了更好的性能 ~12 而不是 256。虽然这非常多到目前为止在开发环境而不是生产环境中

  • 关于锁定的 mysql 进程,您使用的是什么表类型?MyIsam 比我相信的 InnoDB 更容易出现锁定问题。Myisam 是表锁定,其中 innodb 是行 iirc

  • 我注意到你写了

    新的 pdo 功能已将持久连接设置为 false

旧代码是使用持久连接吗?我从来没有太多的运气或使用它们

  • 你缓存多少?您是否启用了 mysql 查询缓存,在 web 服务器和 mysql 之间使用 memcache 或 nosql 系统怎么样?

我知道很多人会说 memcache 等不是慢速/崩溃应用程序的解决方案,但如果它给你更多的喘息空间,为什么不呢?还有一点哲学什么时候缓存不是缓存?例如,我使用 redis.io,它存储在内存中但也保存到磁盘,每当管理系统更新 mysql 时,它也会更新这个“缓存”,它是持久的,因为数据在停机时间中存活 - 最小的预热问题 - 并且总是最新的所以没有滞后。从智力上讲,它可能有点像警察回避这样的事情,但是在我们的情况下,redis 比我们设法让 mysql 完成同样的任务快 6 倍(开箱即用)......

更新 我看到你正在使用 myisam,所以任何锁定问题都可能归结于此,iirc 更新将在持续时间内锁定整个表,这可能导致查询堆积、滚雪球和每次都失败

回复:缓存层缓存可以回避/推迟问题,因为您连接到数据库的次数会更少,我有一些页面根本无法连接!我可以从字面上做一个 mysqld 停止,即使它们在技术上是动态的,它们仍然可以工作

在相关说明中,您是在页面顶部定期连接数据库还是仅在需要时才连接数据库?

更新 额外的评论让我想起了一个类似的问题,我曾经有一次,来自第三方提供商的 xml 提要(在页面请求上运行 - 由于政治原因无法预缓存!)运行缓慢,就像网站的其他区域一样会变得很忙,缓慢的 XML 提要会导致阻塞 apache 进程并降低服务器速度,这意味着有些人不会等待他们的页面完成,但数据库仍会尝试向中止的请求提供信息以及新的,所以它起初看起来像一个数据库问题

于 2013-01-09T09:49:46.393 回答