MySQL连接数耗尽(Too many connections)怎么解决?排查与配置优化指南

MySQL连接数耗尽(Too many connections)怎么解决?排查与配置优化指南

“Too many connections”——数据库拒绝新连接了

当 MySQL 报错 ERROR 1040 (HY000): Too many connections,说明当前活跃连接数已达到 max_connections 上限,新的连接请求被直接拒绝。这通常导致网站出现数据库连接失败的错误页面。


一、紧急处置:先恢复服务

出现此错误时,优先恢复服务,再分析根因:

# 以 root 身份登录 MySQL(root 账户有专用连接槽,通常不受限制)
mysql -u root -p

# 查看当前所有连接
SHOW PROCESSLIST;

# 查看连接数统计
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';

# 找出长时间空闲或挂起的连接,强制关闭
KILL 进程ID;

# 批量关闭 Sleep 状态超过 60 秒的连接(谨慎使用)
SELECT CONCAT('KILL ', id, ';') FROM information_schema.processlist
WHERE command = 'Sleep' AND time > 60;

二、临时提高 max_connections(立即生效,重启后失效)

-- 临时调整(不重启 MySQL 即可生效)
SET GLOBAL max_connections = 500;

-- 查看当前设置
SHOW VARIABLES LIKE 'max_connections';

三、永久修改 max_connections

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# 根据服务器内存调整(每个连接约占 1–10MB 内存)
# 1G 内存建议:100–200
# 2G 内存建议:200–300
# 4G 内存建议:300–500
max_connections = 300

# 同时调整相关参数
wait_timeout = 60          # 空闲连接超时关闭(秒)
interactive_timeout = 60   # 交互连接超时(秒)
connect_timeout = 10       # 连接建立超时
sudo systemctl restart mysql

四、从根本上减少连接数:应用层优化

单纯提高 max_connections 只是治标,真正的解决方案是减少不必要的连接。

方案一:启用 MySQL 连接池

不要在每次请求时新建数据库连接,使用连接池复用现有连接:

# Python(SQLAlchemy 连接池)
from sqlalchemy import create_engine

engine = create_engine(
    'mysql+pymysql://user:password@localhost/mydb',
    pool_size=10,           # 连接池大小
    max_overflow=20,        # 超出 pool_size 时最多额外创建的连接数
    pool_timeout=30,        # 等待连接的超时时间(秒)
    pool_recycle=3600,      # 连接复用超过此时间后自动重建(防止连接断开)
)
// Node.js(mysql2 连接池)
const mysql = require('mysql2/promise');

const pool = mysql.createPool({
  host: 'localhost',
  user: 'myuser',
  password: 'mypassword',
  database: 'mydb',
  connectionLimit: 10,    // 连接池最大连接数
  waitForConnections: true,
  queueLimit: 0,
});

方案二:启用 ProxySQL 数据库代理

对于高并发场景,在应用和 MySQL 之间部署 ProxySQL,在代理层做连接池和负载均衡,可以将实际到 MySQL 的连接数压缩到极低水平:

sudo apt install proxysql -y
sudo systemctl start proxysql

方案三:WordPress 启用持久数据库连接

wp-config.php 中开启持久连接:

define('DB_HOST', 'localhost:3306');
// 注意:持久连接在某些环境下反而增加连接数,需测试效果

五、监控连接数趋势

# 每秒输出当前连接数(持续监控)
watch -n 1 "mysql -u root -p密码 -e 'SHOW STATUS LIKE \"Threads_connected\";' 2>/dev/null"

# 查看连接数历史峰值
mysql -u root -p -e "SHOW STATUS LIKE 'Max_used_connections';"

总结

MySQL 连接数耗尽的处理顺序:紧急关闭僵尸连接恢复服务 → 临时调高 max_connections → 应用层启用连接池(根本解决方案)→ 永久调整 MySQL 参数 → 建立连接数监控。其中应用层的连接池优化是最重要的一步,能从根本上减少对 MySQL 连接的需求。

数据库频繁出现连接耗尽,可能是服务器配置已不满足业务需求。IDC.Net 香港独立服务器提供独占物理内存,数据库性能稳定不受邻居影响,月付 299 元起,支持支付宝 / USDT 付款。

📄 文章 04  方向九(故障排查)

Focus Keyword:Nginx 502 Bad Gateway解决

Meta Title:Nginx返回502 Bad Gateway的8种原因与解决方案

Meta Description:Nginx报502 Bad Gateway怎么解决?本文详解8种常见原因,包含PHP-FPM未运行、upstream连接超时、Unix socket权限错误、后端应用崩溃等场景,附完整排查命令和配置修复方案。

502 的本质:Nginx 能工作,但后端出问题了

502 Bad Gateway 的含义是:Nginx 成功接收了客户端请求,但在向后端(PHP-FPM、Node.js、Python 应用等)转发时出错。这说明 Nginx 本身在运行,问题出在后端服务上。

正因如此,排查 502 要重点关注 Nginx 的反向代理配置和后端应用的状态,而不是 Nginx 自身。


原因 1:PHP-FPM 未运行或崩溃

这是 WordPress / PHP 网站出现 502 最常见的原因。

# 检查 PHP-FPM 状态
sudo systemctl status php8.1-fpm

# 如果未运行,启动
sudo systemctl start php8.1-fpm

# 查看 PHP-FPM 错误日志
sudo tail -n 50 /var/log/php8.1-fpm.log

如果 PHP-FPM 频繁崩溃,检查 pm.max_children 配置是否过低:

sudo nano /etc/php/8.1/fpm/pool.d/www.conf

# 调整进程数(每个 PHP-FPM 进程约占 30–50MB 内存)
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10

原因 2:Unix Socket 路径或权限错误

Nginx 通过 Unix Socket 与 PHP-FPM 通信,路径或权限不一致会导致 502:

# 查看 PHP-FPM 实际监听的 socket 路径
sudo grep "listen = " /etc/php/8.1/fpm/pool.d/www.conf

# 对应 Nginx 配置中的 fastcgi_pass 必须与上面一致
# 常见路径:/var/run/php/php8.1-fpm.sock

# 检查 socket 文件是否存在
ls -la /var/run/php/php8.1-fpm.sock

确保 Nginx 配置中的路径与 PHP-FPM 配置完全一致:

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    # 不要写错版本号,8.1 对应 8.1,不能混用
}

原因 3:后端应用未启动(Node.js / Python)

# 检查后端应用是否在目标端口监听
sudo ss -tlnp | grep :3000  # Node.js 默认端口
sudo ss -tlnp | grep :8000  # Python 应用端口

# 检查服务状态
sudo systemctl status myapp

# 查看应用日志
sudo journalctl -u myapp -n 50 --no-pager

原因 4:upstream 连接超时

后端应用响应太慢,超过 Nginx 等待时间导致 502:

sudo nano /etc/nginx/nginx.conf  # 或站点配置文件
location / {
    proxy_pass http://127.0.0.1:3000;

    # 增加超时时间(默认 60s,可适当调大)
    proxy_connect_timeout 60s;
    proxy_send_timeout 120s;
    proxy_read_timeout 120s;
}

原因 5:后端应用内存耗尽被 OOM Killer 杀死

# 查看 OOM Killer 日志,确认是否有进程被杀
sudo dmesg | grep -i "out of memory"
sudo journalctl -k | grep -i "oom"

如果确认是 OOM 问题,需要优化应用内存使用或升级服务器内存配置。


原因 6:Nginx upstream 配置地址错误

# 检查 Nginx 配置中 proxy_pass 或 fastcgi_pass 的地址是否正确
sudo nginx -t

# 常见错误:端口写错、使用了已停用的 Unix Socket 路径
grep -r "proxy_pass\|fastcgi_pass" /etc/nginx/sites-enabled/

原因 7:服务器磁盘满导致应用无法写入

df -h

# 如果根分区 100%,应用无法创建临时文件,PHP 报错导致 502
# 快速清理
sudo journalctl --vacuum-time=3d
sudo apt clean
sudo find /tmp -mtime +1 -delete

原因 8:PHP max_execution_time 过短

PHP 脚本执行超过 max_execution_time 时被强制终止,Nginx 收到中断连接,返回 502:

sudo nano /etc/php/8.1/fpm/php.ini

# 适当增加执行时间(默认 30s)
max_execution_time = 120

sudo systemctl restart php8.1-fpm

502 排查流程总结

排查步骤命令
确认 Nginx 在运行systemctl status nginx
查看 Nginx 错误日志tail -n 50 /var/log/nginx/error.log
确认后端服务在运行systemctl status php-fpm / myapp
确认端口/Socket 监听ss -tlnp
检查磁盘是否满df -h
检查内存是否耗尽free -h / dmesg | grep oom

如需稳定的香港服务器运行 Nginx + PHP 业务,IDC.Net 香港云服务器首月 10 元起,SSD 硬盘,CN2 GIA 线路,7×24 工单支持,支付宝付款即可开通。

Telegram