不支持,MySQL 5.7+ 中 my.cnf 的 error_log 参数仅接受文件名(如 error.log)或别名(如 syslog),不支持绝对路径;指定绝对路径会静默失效或导致启动失败,正确方式是使用 log-error 启动参数或 systemd ExecStart 传参。

error_log 在 my.cnf 中是否真的支持自定义路径?
MySQL 5.7 及以上版本(包括 MySQL 8.0)**不支持**在 my.cnf 中用 error_log 配置项直接指定日志文件路径。该参数只接受**文件名或标准输出别名**(如 syslog),不能带绝对路径。如果你写了 error_log = /var/log/mysql/error.log,MySQL 启动时不会报错,但实际会把日志写到 /var/log/mysql/ 目录下的 error.log —— 前提是 MySQL 进程有该目录的写权限;否则日志可能静默丢失,mysqld 甚至无法启动。
真正生效的写法只有两种:
-
error_log = error.log→ 写入 datadir 目录(例如/var/lib/mysql/error.log) -
error_log = syslog→ 交由系统 rsyslog 或 journald 管理(推荐用于集中管控和轮转)
想指定绝对路径?改用 log-error 启动参数
log-error 是 mysqld 启动时识别的命令行参数,它支持完整路径,且优先级高于 my.cnf 中的 error_log。所以正确做法是:在 my.cnf 的 [mysqld] 段中不设 error_log,而通过 systemd 或启动脚本传参。
以 systemd 为例(Ubuntu/Debian/CentOS 7+):
# 编辑服务文件 sudo systemctl edit mysql
填入:
[Service] ExecStart= ExecStart=/usr/sbin/mysqld --log-error=/var/log/mysql/mysqld.err --pid-file=/run/mysqld/mysqld.pid $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION
注意两点:
- 第一行
ExecStart=是清空默认值的必需写法 -
--log-error必须放在所有其他参数之前,否则可能被覆盖
改完后运行 sudo systemctl daemon-reload && sudo systemctl restart mysql,再确认日志是否写入目标路径:sudo tail -f /var/log/mysql/mysqld.err。
用 logrotate 实现 MySQL error 日志轮转
MySQL 自身不提供 error log 轮转功能(不像 slow_query_log 可配 log_error_services + log_filter_internal)。必须依赖外部工具,logrotate 是最通用选择。
新建配置文件:
sudo tee /etc/logrotate.d/mysql-error <<'EOF'
/var/log/mysql/mysqld.err {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 mysql adm
sharedscripts
postrotate
if systemctl is-active --quiet mysql; then
# MySQL 5.7+ 支持 flush error logs;旧版本需 kill -USR1
mysql -NBe "SELECT VERSION()" >/dev/null 2>&1 && mysql -e "FLUSH ERROR LOGS" 2>/dev/null || \
kill -USR1 $(cat /run/mysqld/mysqld.pid 2>/dev/null) 2>/dev/null || true
fi
endscript
}
EOF
关键点说明:
-
create 640 mysql adm:确保新日志权限正确(MySQL 进程需属mysql组) -
sharedscripts+postrotate:保证所有匹配文件轮转完再执行一次刷新 -
FLUSH ERROR LOGS仅 MySQL 5.7.17+ 支持;低于此版本必须用kill -USR1通知 mysqld 重开日志文件 - 若 MySQL 使用 socket 认证而非密码,
mysql -e命令仍可工作(依赖~mysql/.my.cnf或/etc/mysql/debian.cnf)
常见失败现象与排查线索
轮转后发现新日志没写入、旧日志没压缩、或 MySQL 启动失败,先看这几个地方:
- 检查
mysqld进程实际加载的参数:ps aux | grep mysqld | grep log-error - 确认
/var/log/mysql/所在文件系统是否有空间、inode 余量:df -h /var/log和df -i /var/log - 手动运行 logrotate 测试:
sudo logrotate -d /etc/logrotate.d/mysql-error(-d 查看干了什么,-f 强制执行) - 如果
FLUSH ERROR LOGS报错Access denied,说明 mysql 客户端连接用了非 root 用户,改用debian-sys-maint账户或加--defaults-file=/etc/mysql/debian.cnf - systemd 下若用
KillMode=control-group(默认),kill -USR1可能被拦截,建议改用FLUSH ERROR LOGS或显式设置KillMode=process
路径和权限问题最容易被忽略——MySQL 不会主动创建父目录,也不会自动修复 umask 导致的权限错误。轮转配置写得再准,/var/log/mysql 目录不存在或属主不是 mysql,一切都会静默失败。


















