mysql启动失败因权限不足时,应先查运行用户和datadir路径,再用chown -r mysql:mysql重置所有权并设chmod 750,禁用777;迁移目录需同步更新配置、selinux/apparmor策略;备份须用mysqldump或xtrabackup等安全方式。

MySQL启动失败报 Can't create/write to file 或 Permission denied
这是最常见信号:MySQL进程(通常是 mysqld 用户)没权限读写 datadir 目录下的文件。别急着加 chmod 777,那等于把锁撬了扔地上。
正确做法是让 mysqld 进程用户真正拥有该目录所有权,且禁止其他用户越权访问:
- 先查 MySQL 实际运行用户:
ps aux | grep mysqld | grep -v grep,常见是mysql或mysqld - 确认当前
datadir路径:mysql -e "SHOW VARIABLES LIKE 'datadir';",典型值如/var/lib/mysql - 执行所有权重置:
sudo chown -R mysql:mysql /var/lib/mysql(路径按你实际的来) - 设置最小必要权限:
sudo chmod 750 /var/lib/mysql(目录本身 750,内部文件由 MySQL 自己管理,不手动改)
迁移 data 目录后 MySQL 拒绝启动
换路径不是改个配置就完事——SELinux 或 AppArmor 会立刻拦截,尤其在 CentOS/RHEL 或 Ubuntu 上。
关键检查点有三个:
- 确认
my.cnf中datadir配置已更新,且路径末尾**不能有多余斜杠**(/data/mysql/和/data/mysql在某些版本行为不同) - SELinux 环境下必须打标签:
sudo semanage fcontext -a -t mysqld_db_t "/new/path(/.*)?",再sudo restorecon -Rv /new/path - AppArmor(Ubuntu)需编辑
/etc/apparmor.d/usr.sbin.mysqld,在/var/lib/mysql/**行下方追加新路径规则,然后sudo systemctl reload apparmor
为什么不能用 chmod 777 或 chown root:root
MySQL 安全模型依赖进程用户隔离。一旦用 777,任意本地用户都能读取 ibdata1、表结构文件甚至未刷盘的 redo log;而 root 所有权会导致 mysqld 启动时因无法降权失败(多数发行版强制要求非 root 用户运行)。
更隐蔽的风险:
- 二进制日志(
binlog)若被非 MySQL 进程写入或截断,主从复制直接中断且难以恢复 -
innodb_file_per_table=ON下每个.ibd文件权限由 MySQL 维护,外部 chmod 可能破坏其一致性校验 - systemd 启动时若检测到 datadir 权限过宽(如 777),部分新版会静默拒绝启动并只在
journalctl -u mysqld里记一条警告
备份脚本或定时任务访问 data 目录失败
不要让备份脚本直接读 /var/lib/mysql —— 这是 MySQL 正在使用的活数据,直接 cp 极大概率损坏。
安全替代方案分场景:
- 需要冷备(停库):停掉
mysqld后,用rsync -av --delete /var/lib/mysql/ /backup/mysql/,确保目标目录属主也设为mysql:mysql - 热备需求:用
mysqldump或 Percona XtraBackup;后者要求额外授权:GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup'@'localhost'; - 如果必须挂载 NFS 或 CIFS 做远程归档:挂载选项务必含
noexec,nosuid,nodev,且服务端导出权限严格限制 IP + 用户映射
权限这事,不是“能跑就行”,而是“谁碰得到、谁改得了、出事能不能溯源”。MySQL 的 data 目录权限链上,任何一环松动,后面排查的坑都比权限本身深得多。











