log_error必须配置绝对路径,否则静默回退至默认位置;需提前创建目录、设置mysql用户权限,并注意systemd保护机制及log_error_services插件覆盖影响。

log_error 必须用绝对路径,否则静默失效
MySQL 的 log_error 参数只认绝对路径,写成 logs/error.log 或 ~/mysql/error.log 都不会报错,但 MySQL 会直接回退到默认位置(通常是 /var/lib/mysql/hostname.err),你根本看不到日志出现在目标目录。
- 必须用完整路径,例如:
log_error = /var/log/mysql/error.log - 目标目录需提前创建:
sudo mkdir -p /var/log/mysql - 属主必须是 MySQL 进程用户(通常是
mysql):sudo chown mysql:mysql /var/log/mysql - systemd 管理的系统(如 Ubuntu 22.04+、CentOS 8+)还需检查
ProtectHome=true或PrivateTmp=true是否拦截——若日志目录在/home或/tmp下,得在/usr/lib/systemd/system/mysqld.service里加ReadWritePaths=/var/log/mysql并重载服务
log_bin 指定路径后,必须手动迁移 index 文件
log_bin = /data/binlog/mysql-bin 看似设好了,但 MySQL 启动时只按这个前缀生成新文件(如 mysql-bin.000001),**不会自动把旧 binlog 文件挪过去,也不会更新 mysql-bin.index**。如果忽略这步,主从复制可能中断,SHOW MASTER STATUS 显示的文件名和实际磁盘不一致。
- 停库后,先复制所有旧 binlog 文件到新目录:
cp /var/lib/mysql/mysql-bin.* /data/binlog/ - 编辑新目录下的
mysql-bin.index,把每行路径替换成绝对路径,例如把./mysql-bin.000001改成/data/binlog/mysql-bin.000001 - 确认
datadir和log_bin不在同一个挂载点——否则 I/O 争用没解决,分离就失去意义
slow_query_log_file 和 general_log_file 必须配合开关启用
只写 slow_query_log_file = /var/log/mysql/slow.log 是无效的。MySQL 要求对应日志功能必须显式开启,否则路径设置被忽略,SHOW VARIABLES LIKE 'slow_query_log' 返回 OFF。
- 启用慢日志:
slow_query_log = ON(或= 1),再配路径 - 通用日志同理:
general_log = ON+general_log_file = /var/log/mysql/general.log - 这两个路径也必须是绝对路径,且父目录存在、权限正确;MySQL 不会自动创建缺失的父目录,失败时直接关闭日志,不提示
-
general_log对性能影响显著,生产环境建议保持OFF;slow_query_log的long_query_time建议调低到2秒再观察,避免漏掉真实慢查询
MySQL 8.0+ 的 log_error_services 可能覆盖 log_error
MySQL 8.0 引入了日志服务插件机制,默认配置是 log_error_services = 'log_filter_internal:; log_sink_syseventlog:; log_sink_json:'。如果你只改了 log_error,但没关掉 log_sink_syseventlog,错误日志可能同时写进系统日志(/var/log/syslog 或 journald),导致你以为配置没生效。
- 要完全控制输出位置,推荐显式设置:
log_error_services = 'log_filter_internal:; log_sink_file:' - 确保
log_sink_file插件已加载(默认启用),否则启动会报错 - 修改后必须重启 MySQL,
SET PERSIST对这类服务类变量无效
路径分离不是改几个配置就完事的事——log_bin.index 文件的手动修正、systemd 权限限制、8.0 的日志服务插件,这三个点最容易被跳过,结果就是日志看似“配置成功”,实则写在别处或压根没写。


















