最常见原因是mysql用户对log_error路径无写权限;需确保目录存在、属主为mysql:mysql、权限755,且selinux上下文为mysqld_log_t,logrotate后还需执行flush-logs。

log_error路径存在但MySQL写不进去
最常见的情况是目录存在,但mysql用户没权限创建或写入日志文件。比如/var/log/mysql/目录由root创建,所有权还是root:root,而mysqld进程以mysql用户运行,自然被拒。
- 执行
sudo -u mysql touch /var/log/mysql/test.log 2>/dev/null || echo "权限不足"快速验证 - 修复命令:先确保父目录存在,再设所有权和权限:
sudo mkdir -p /var/log/mysql→sudo chown mysql:mysql /var/log/mysql→sudo chmod 755 /var/log/mysql - 注意:MySQL 不会自动创建中间目录,
/var/log/mysql必须手动建好;如果配置的是/var/log/mysql/error.log,只建/var/log不够
log_error指向的路径根本不存在
配置里写了log_error = /var/log/mysql/error.log,但/var/log/mysql/这个目录压根没创建过,mysqld_safe启动前就直接报错退出,连日志都来不及写。
- 查配置位置:
grep -A2 "\[mysqld\]" /etc/my.cnf /etc/mysql/my.cnf 2>/dev/null,确认log_error值 - 别只看文件名,重点看路径的每一级是否存在:
ls -ld /var/log /var/log/mysql - 若某一级缺失(比如
/var/log/mysql),用sudo mkdir -p补全,再立即设权,不能等启动失败后再修
SELinux阻止写入日志目录(RHEL/CentOS系)
即使chown和chmod都对了,mysqld仍写不了日志——大概率是SELinux上下文不对。默认/var/log/mysql/的上下文是var_log_t,但mysqld只被允许往mysqld_log_t类型目录里写。
- 检查当前上下文:
ls -Z /var/log/mysql,输出里如果不是mysqld_log_t就需修正 - 临时放行(仅调试):
sudo setenforce 0,看是否立刻能写;若能,说明就是SELinux问题 - 永久修复:
sudo semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?"→sudo restorecon -Rv /var/log/mysql
logrotate后日志“消失”了
轮转后tail -f /var/log/mysql/error.log看不到新内容,但mysqld明明在跑——这是因为mysqld进程还拿着旧文件的句柄,logrotate新建的文件它根本不认识。
- 验证:运行
lsof -p $(pgrep mysqld) | grep log,看输出的路径是不是轮转前的老文件名 - 关键动作:logrotate配置里必须加
postrotate mysqladmin -u root -p'xxx' flush-logs endscript(密码需实际填写) - 绝对避免用
copytruncate,它靠截断原文件实现轮转,但mysqld对已打开的文件截断后可能写乱偏移,导致日志损坏











