PHP如何控制MySQL连接数过高

PHP how to control the MySQL connection number is too high

在线项目运行上了一段时间,通知监控可以看到,每天晚上一个MySQL连接数特别高,项目开发使用PHP,我不不知道怎么控制连接数,毕竟不喜欢能在代码层面实现连接池的内存驻留类型语言

默认情况下,151 是 MySQL 5.5 中允许的最大同时客户端连接数。如果达到 max_connections 的限制,当您尝试连接到 MySQL 服务器时,您将收到“连接过多”错误 – 这意味着所有可用连接都被其他客户端使用。

MySQL 允许在 max_connections 限制之上增加一个连接,该限制是为具有 SUPER 权限的数据库用户保留的,以便诊断连接问题。通常管理员用户具有此 SUPER 权限。您应该避免向应用用户授予 SUPER 权限。

MySQL 每个客户端连接使用一个线程,许多活动线程是性能杀手。通常,并行执行查询的大量并发连接会导致速度显着下降并增加死锁的机会。在 MySQL 5.5 之前,尽管 MySQL 从那时起变得越来越好,但它的扩展性并不好——但是如果你有数百个活动连接在做真正的工作(这不算休眠 [idle ] 连接),那么内存使用量将会增加。每个连接都需要每个线程缓冲区。还隐含在内存表中需要更多内存加上全局缓冲区的内存要求。最重要的是,每个连接都可以使用 tmp_table_size/max_heap_table_size,尽管它们不会立即为每个新连接分配。

大多数情况下,连接数过高是由于应用程序中的错误未正确关闭连接或设计错误,例如建立了与 mysql 的连接,但随后应用程序在关闭 MySQL 处理程序之前正忙于做其他事情。在应用程序未正确关闭连接的情况下,wait_timeout 是一个重要参数,用于调整和丢弃未使用或空闲的连接,以最大限度地减少与 MySQL 服务器的活动连接数——这最终会有所帮助以避免“连接过多”错误。尽管某些系统 运行 即使有大量连接线程也没有问题,但大多数连接都是空闲的。一般来说,休眠线程不会占用太多内存——512 KB 或更少。 Threads_running 是一个有价值的监控指标,因为它不计算休眠线程——它显示活动和当前正在处理的查询量,而 threads_connected 状态变量显示所有连接的线程值,包括空闲连接。

如果您在应用程序端使用连接池,max_connections 应该大于池端的最大连接数。如果您期望有大量连接,连接池也是一个不错的选择。现在 max_connections 的推荐值应该是多少?

这个问题没有唯一的正确答案。这取决于每个连接的可用 RAM 量和内存使用量。增加 max_connections 值会增加 mysqld 需要的文件描述符的数量。注意:设置最大 max_connections 值没有硬性限制。因此,您必须根据您的工作量、与 MySQL 服务器的同时连接数等明智地选择 max_connections。通常,不建议允许太高的 max_connections 值,因为以防万一如果所有这些连接 运行 可能会引发巨大的争用问题,则会出现一些锁定条件或减速。在使用 temporary/memory 表的活动连接的情况下,内存使用量可能会更高。在具有小 RAM 或在应用程序端具有硬连接数控制的系统上,我们可以使用较小的 max_connections 值,如 100-300。具有 16G RAM 或更高 max_connections=1000 的系统是一个好主意,当然每个连接缓冲区应该具有 good/default 值,而在某些系统上我们可以看到最多 8k 最大连接,但这样的系统通常成为在负载峰值的情况下关闭。

为了解决这个问题,Oracle 和 MariaDB 团队实施了线程池。使用正确配置的线程池,您可能希望吞吐量不会减少多达几千个并发连接,至少对于某些类型的工作负载。

注意:请注意,在 MySQL 5.6 中,当您将 max_connections 值设置得太高时,会分配大量内存。