mysql迁移后启动失败主因是datadir权限未对齐及selinux/apparmor拦截:需先停服务,用select @@datadir或mysqld --help查真实路径,再chown -r mysql:mysql、chmod 750,补selinux上下文或apparmor规则,并同步更新socket/pid-file/log-error路径。

直接改 datadir 配置却不处理权限和 SELinux 上下文,90% 会导致 MySQL 启动失败,报 Can't change dir to '/new/path/' (Errcode: 13) 或静默退出。
确认当前 datadir 和运行用户
别信配置文件里写的,得看 MySQL 实际在用哪个路径、以谁的身份跑:
- 连上 MySQL 执行
SELECT @@datadir;—— 这是唯一权威值 - 查进程属主:
ps aux | grep mysql,重点关注mysqld主进程的用户名(常见是mysql,但 Docker 或一键包可能用root或自定义用户) - 如果 systemd 管理,还要检查
/usr/lib/systemd/system/mysqld.service是否通过Environment=MYSQLD_OPTS=--datadir=...强制覆盖了配置
迁移数据必须用 rsync -avp,不能 cp -r
cp -r 会丢 socket 文件权限、忽略扩展属性,MySQL 启动时可能卡在初始化阶段;rsync -avp 才能完整保留属主、权限、时间戳和特殊文件类型:
- 停服务后执行:
rsync -avp /var/lib/mysql/ /data/mysql/(注意源路径末尾有斜杠,否则会嵌套成/data/mysql/mysql/) - 目标目录必须为空或全新创建,不能混入其他文件——哪怕一个隐藏文件都可能干扰 InnoDB 恢复
- 迁移完立刻验证关键文件是否存在:
ibdata1、ib_logfile0、mysql/、performance_schema/
授权不只是 chown,还要过 SELinux/AppArmor 这关
Linux 下即使 chown -R mysql:mysql /data/mysql 且 chmod 750 全对,SELinux 仍会拦截访问,错误日志里只显示模糊的 Permission denied,没提 SELinux:
- CentOS/RHEL:运行
sudo semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?",再sudo restorecon -Rv /data/mysql - Ubuntu/Debian:检查 AppArmor 是否启用(
aa-status),若启用需编辑/etc/apparmor.d/usr.sbin.mysqld,把新路径加进/data/mysql/** rwk,规则 - 父目录也要可进入:
/data至少得有r-x权限给mysql用户,否则启动时连目录都进不去
配置文件修改后必须同步检查 socket/pid-file/log-error
datadir 改了,但 socket、pid-file、log-error 如果还指向旧路径下的相对位置(比如 socket = /var/lib/mysql/mysql.sock),MySQL 会因无法绑定 socket 或写日志而失败:
- 在
[mysqld]段中显式设置这些路径,例如:socket = /data/mysql/mysql.sock、pid-file = /data/mysql/mysqld.pid、log-error = /data/mysql/error.log - 改完配置必须
sudo systemctl daemon-reload(systemd 环境),再sudo systemctl start mysql - 启动失败时第一反应不是重试,而是看
sudo journalctl -u mysql -n 50 -f,重点搜Can't start server、Permission denied、failed to load
最容易被忽略的是配置加载顺序和 systemd 覆盖参数——my.cnf 里改了 datadir,但 systemd 的 MYSQLD_OPTS 又把它顶掉了,结果 MySQL 还在老地方找文件。动手前先跑一遍 mysqld --help --verbose | grep "Default options",确认真正生效的配置文件路径。











