phpEnv中MySQL内存持续升高是因默认配置不当:需禁用query_cache、设置固定innodb_buffer_pool_size、调低max_connections并加wait_timeout;PHP层须避免fetchAll、及时释放连接、复用PDO实例。

phpEnv 是 Windows 下的轻量级集成环境,MySQL 默认配置严重不适合长期运行或稍有并发的场景,内存持续升高几乎必然发生——这不是 bug,是默认参数和 Windows 内存管理机制共同导致的“温水煮青蛙”现象。
为什么 phpEnv 的 MySQL 会越跑内存越高
phpEnv 套件里 MySQL 多为 5.7 或 8.0 精简版,my.ini 配置常沿用极老模板(比如 key_buffer_size=16M、sort_buffer_size=2M),且未禁用已废弃功能。关键问题有三个:
- 默认开启
query_cache_type=1(MySQL 8.0 已移除,但 5.7 仍存在),缓存碎片化后不释放,query_cache_size占用持续增长却无实际收益 -
innodb_buffer_pool_size没设值,MySQL 自动按规则分配(如总内存 4GB 时可能分到 1.2GB),但 Windows 下该内存不会主动归还给系统,free -h类指标不可见,任务管理器却显示“已提交内存”持续上涨 -
max_connections=151(默认值)太宽松,PHP 脚本若连接未 close 或复用失败,Threads_connected慢慢堆到 80+,每个连接再吃掉 2–5MB,几小时就多占 300MB+
必须改的三项配置(修改 my.ini 后重启 MySQL)
打开 phpEnv 安装目录下的 mysql\my.ini(通常在 phpEnv\phpEnv\MySQL\my.ini),只动这三处:
- 注释或删掉整行
query_cache_type和query_cache_size(MySQL 5.7 中强制设为 0 才真正禁用) - 显式设置
innodb_buffer_pool_size=512M(4GB 内存机器)或1G(8GB 及以上),**不要写百分比,必须写带单位的字符串**;确认启动后日志出现InnoDB: Using buffer pool size of 512.000MiB - 把
max_connections=151改成max_connections=100,同时加一行wait_timeout=60(空闲 60 秒断开),防止 PHP 连接泄漏后长期挂起
PHP 层配合:别让 MySQL “背锅”
很多“MySQL 内存高”其实是 PHP 拉取数据后没释放,MySQL 连接早关了,但 PHP 进程还在 hold 大数组。重点检查:
立即学习“PHP免费学习笔记(深入)”;
- 用
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=false+foreach ($stmt as $row)替代fetchAll(),尤其处理 >1 万行时;否则整个结果集先塞进 PHP 内存 - 查询后立刻调用
$stmt->closeCursor()或$result->free(),别等脚本结束自动析构 - 避免在循环里 new PDO,改用单例或连接池(哪怕只是全局 static $pdo);phpEnv 无连接池组件,靠代码节制最实际
- 加一句
ini_set('memory_limit', '128M')在入口文件开头,提前暴露内存问题,而不是等 OOM 崩溃
验证是否真改善:两个命令够用
改完重启 MySQL,别信任务管理器的“内存”,看真实指标:
- 登录 MySQL 执行:
SHOW STATUS LIKE 'Threads_connected';—— 正常应 ≤ 20,长期 > 50 就说明 PHP 还在漏连 - 执行:
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages%';—— 关注Innodb_buffer_pool_pages_free是否稳定(不归零)、Innodb_buffer_pool_read_requests/Innodb_buffer_pool_reads比值 > 99% 表示缓存效率 OK
Windows 下没有 free -h,但资源监视器 → “内存”页签里看“已提交”曲线是否趋平。真正的难点不在改参数,而在确认 PHP 有没有把连接真正交还回去——SHOW PROCESSLIST 里 Sleep 状态连接超过 30 个,基本可以断定是代码层没管住。



















