phpEnv 的 MySQL 默认不记录死锁,因其精简版关闭了 innodb_print_all_deadlocks 且错误日志路径易被忽略;需手动修改 my.ini/my.cnf 启用该参数并重启 MySQL 服务,或通过脚本轮询 SHOW ENGINE INNODB STATUS 持久化捕获。

phpEnv 是纯本地开发环境套件,不自带 MySQL 死锁监控能力,必须手动配置 MySQL 服务端参数或脚本采集——它本身不干预、也不暴露任何死锁相关配置界面。
为什么 phpEnv 的 MySQL 默认不记录死锁
phpEnv 安装的 MySQL(通常是 5.7 或 8.0 精简版)默认关闭 innodb_print_all_deadlocks,且错误日志路径常设为 ./mysql/data/hostname.err(相对路径),容易被忽略或权限限制。你执行 SHOW ENGINE INNODB STATUS\G 能看到最近一次死锁,但这个输出是瞬态的,重启 MySQL 就清空,phpEnv 下更难持久化捕获。
开启 innodb_print_all_deadlocks 需要改 my.ini
phpEnv 的 MySQL 配置文件通常在:phpenv\mysql\my.ini(Windows)或 phpenv/mysql/my.cnf(macOS/Linux)。编辑它,在 [mysqld] 段落下添加:
innodb_print_all_deadlocks = ON log_error = ./data/mysql-error.log
注意两点:
- 必须重启 phpEnv 的 MySQL 服务(不是整个 phpEnv,仅 MySQL)才能生效
-
log_error路径要用相对路径或绝对路径,确保 MySQL 进程有写入权限;若用./data/...,确认phpenv/mysql/data/目录存在且可写 - 该参数仅对 MySQL ≥ 5.6.2 有效;phpEnv 若装的是 5.5,则必须升级或换用轮询
SHOW ENGINE INNODB STATUS方案
用脚本轮询 SHOW ENGINE INNODB STATUS(兼容所有版本)
在 phpEnv 环境下,最稳妥的死锁捕获方式是写一个本地定时脚本,绕过 phpEnv 界面直接调用 MySQL CLI。例如 Windows 下新建 watch-deadlock.bat:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
@echo off :loop mysql -uroot -proot -e "SHOW ENGINE INNODB STATUS\G" 2>nul | findstr /C:"LATEST DETECTED DEADLOCK" >> deadlock.log timeout /t 20 >nul goto loop
关键点:
- 账号密码需匹配 phpEnv 实际设置(常见是
-uroot -proot,但有些版本初始无密码,得留空) - 输出重定向用
>>追加,避免覆盖历史;findstr只提取含关键字的行+后续 20 行(用grep -A 20替代适用于 Linux/macOS) - 不要依赖 phpEnv 自带的“服务管理器”启动该脚本——它没提供后台守护功能,建议用系统任务计划或
start /B后台运行
死锁日志里真正要盯住的三行
无论用哪种方式拿到死锁日志,别通读全文。90% 内容是干扰项,只看这三处:
-
*** (1) HOLDS THE LOCK(S):—— 记下后面的space id和page no,再查表名:SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE SPACE = ? -
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:—— 看它想锁哪一行、什么索引,和上一条比对是否冲突 -
MySQL thread id和query id—— 对应到information_schema.INNODB_TRX查具体 SQL,确认是不是 PHP 里那条UPDATE ... WHERE id IN (?)
phpEnv 没有自动解析工具,这些字段全靠手动对照。最容易被忽略的是:死锁日志里的 trx id 和 thread id 不是 PHP 的 mysqli_thread_id(),而是 InnoDB 内部事务 ID,只能通过查询系统表关联。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










