log_error必须在[mysqld]段中用小写绝对路径配置,重启生效;否则静默失败、日志仍写默认路径。需检查段落位置、权限、selinux/apparmor限制,并用show variables like 'log_error'验证。

必须改配置文件并重启,运行时 SET GLOBAL 会报错“Variable 'log_error' is a read only variable”
log_error 必须写在 [mysqld] 段落里
写错段落是静默失败的最常见原因。比如放在 [client] 或 [mysql] 下,MySQL 完全忽略,仍往默认路径(如 /var/lib/mysql/hostname.err)写日志,且不提示任何错误。
- 用
grep -A 5 -B 5 "log_error" /etc/my.cnf确认它紧贴在[mysqld]下方 - 若配置文件含多个
[mysqld](如[mysqld1]),注意匹配实际启动所用的段落 - 不要混用大小写:
LOG_ERROR或Log_Error都无效,只能是小写log_error
路径必须是绝对路径,且目录已存在、有写权限
log_error = error.log 或 log_error = ./error.log 是相对路径,MySQL 会把它拼接到 @@datadir 下,不是你想象的位置——结果日志“消失”在数据目录里。
- 一律用绝对路径,例如:
log_error = /var/log/mysql/error.log - 提前创建目录:
sudo mkdir -p /var/log/mysql - 赋权给 MySQL 进程用户(通常是
mysql):sudo chown mysql:mysql /var/log/mysql - 权限不够时,启动直接失败,报错:
Can't open the error log file: Permission denied
SELinux 或 AppArmor 可能拦截写入,即使路径和权限都对
尤其在 CentOS/RHEL(SELinux)或 Ubuntu/Debian(AppArmor)上,安全模块会阻止 mysqld 向非标准路径写日志,且错误表现很隐蔽:服务启动失败,但你甚至看不到明确的日志报错。
- 临时验证是否是 SELinux 导致:
sudo setenforce 0,再试重启 mysqld - 永久放行(RHEL/CentOS):
sudo setsebool -P mysqld_read_error_log on - Ubuntu 上检查 AppArmor 日志:
sudo dmesg | grep -i avc | grep mysqld - 别跳过这步——很多线上环境卡在这儿半天查不出原因
验证是否真正生效,不能只看配置文件
改完配置、重启服务后,必须进 MySQL 执行命令确认,因为配置语法错、路径不可写、SELinux 拦截等都会导致“看似重启成功,实则回退到默认路径”。
- 登录后执行:
SHOW VARIABLES LIKE 'log_error';,返回值必须是你设的绝对路径 - 用
tail -f /your/specified/path/error.log实时观察,启动信息(如mysqld: Shutdown complete)是否出现 - 如果仍看到旧日志在
@@datadir下更新,说明配置根本没加载,回头检查段落位置和文件路径
最容易被忽略的是:log_error 不记录 SQL 错误(比如 ERROR 1062 (23000): Duplicate entry),它只管 mysqld 自身的生命周期事件。想抓 SQL 层异常,得靠应用层捕获或开启 general_log——但那不是错误日志的事。











