MySQL datadir所有权必须设为mysqld运行用户,即执行sudo chown -R mysql:mysql /var/lib/mysql并设chmod 750;迁移后还需同步更新SELinux或AppArmor策略,否则仍因安全模块拦截启动失败。

MySQL datadir 所有权必须设为 mysqld 运行用户
MySQL 启动失败报 Can't create/write to file 或 Permission denied,八成是 datadir 所有权不对。别急着 chmod 777,那是直接拆锁。
正确做法是让 MySQL 进程真正“拥有”这个目录:
- 查运行用户:
ps aux | grep mysqld | grep -v grep,常见为mysql或mysqld - 确认路径:
mysql -e "SHOW VARIABLES LIKE 'datadir';",典型值如/var/lib/mysql - 重置所有权:
sudo chown -R mysql:mysql /var/lib/mysql(路径按你实际的来) - 禁止其他用户读写:
sudo chmod 750 /var/lib/mysql(仅限目录本身;内部文件由 MySQL 自己管理,不手动改)
迁移或自定义 datadir 后必须同步更新 SELinux/AppArmor 策略
即使 chown 和 chmod 都对了,Linux 安全模块仍可能拦住 MySQL 访问新路径——这是最常被忽略的“隐形权限”。
现象:MySQL 日志里出现 Operation not permitted 或反复报错无法初始化,但文件权限检查全绿。
- SELinux 环境下,用
ls -Z /your/new/datadir检查上下文,应匹配默认mysqld_db_t;否则执行:sudo semanage fcontext -a -t mysqld_db_t "/your/new/datadir(/.*)?",再sudo restorecon -Rv /your/new/datadir - AppArmor 用户需编辑
/etc/apparmor.d/usr.sbin.mysqld,在{...}块内添加类似/your/new/datadir/** rwk,,然后sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld - 临时验证可用
sudo setenforce 0(SELinux)或sudo systemctl stop apparmor测试,但生产环境严禁长期关闭
备份与恢复过程中的权限继承容易出错
用 mysqldump 导出再导入时不会动文件系统权限,但用物理拷贝(如 cp/rsync/XtraBackup)恢复 datadir 后,原权限极大概率丢失。
- 恢复后必须立刻重跑
chown -R mysql:mysql和chmod 750,不能依赖备份前的设置 - 若用 XtraBackup,
--copy-back默认不保留属主,需加--rsync或后续手动修复 - Docker 环境尤其注意:宿主机挂载的
datadir卷,容器内mysql用户 UID 可能和宿主机不一致,导致权限错位;建议显式指定--user $(id -u):$(id -g)
MySQL 8.0+ 的数据字典目录不能被外部修改
MySQL 8.0 引入事务性数据字典,将系统表元数据存于 datadir 下的 mysql.ibd 和 mysql/ 子目录中。这些文件一旦被非 mysqld 进程写入或删改,实例将拒绝启动且无法自动修复。
- 绝对禁止对
datadir/mysql/目录执行rm -rf、chown或chmod操作 - 备份脚本若遍历
datadir并递归chown,必须排除mysql/子目录 - 监控告警可加入检查:
find /var/lib/mysql/mysql -type f ! -user mysql | wc -l,结果非 0 即异常
文件系统权限只是防线的一环,它防不住逻辑越权,也拦不住已认证用户的恶意 SQL。真正安全的起点,是让 MySQL 进程只拥有它必须拥有的路径所有权,且不给任何外部进程留下篡改系统元数据的机会。


















