必须先确认datadir路径和mysql运行用户,否则90%启动失败;迁移需停库→复制→改配置→授权,注意权限、selinux/apparmor策略及日志排查。

确认当前 datadir 路径和 MySQL 运行用户
不查清这两点就改路径,90% 会启动失败。先连上 MySQL 执行:
SELECT @@datadir;
再看进程属主:
ps aux | grep mysql
常见情况是 mysql 用户(不是 root),但有些 Docker 或一键包可能用 root 或其他用户。迁移后目录权限必须匹配该用户,否则 mysqld 启动时直接报 Can't change dir to '/new/path/' (Errcode: 13) 或类似拒绝访问错误。
关键点:
-
datadir值末尾不能带斜杠(如/var/lib/mysql/是错的,应写成/var/lib/mysql) - 新路径父目录需存在,且
mysql用户对其有r-x权限(至少能进入) - 新路径本身必须为空或完全由 MySQL 初始化生成(不能混入其他文件)
停库 → 复制数据 → 修改配置 → 授权目录
别跳步骤,尤其不能边跑边拷。复制必须用 rsync -avp 或 cp -a,保留所有属主、权限、时间戳。示例流程:
systemctl stop mysql<br>rsync -avp /var/lib/mysql/ /data/mysql/<br>chown -R mysql:mysql /data/mysql<br>chmod 755 /data/mysql
然后改配置文件(通常是 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf):
[mysqld]<br>datadir = /data/mysql
注意:socket、pid-file、log-error 等路径如果也写在 [mysqld] 下,且依赖旧 datadir 结构,要一并检查是否需要调整;否则可能报 Can't start server: Bind on unix socket。
SELinux 和 AppArmor 会拦截新路径访问
CentOS/RHEL 默认开 SELinux,Ubuntu/Debian 可能启用 AppArmor —— 它们不会报 MySQL 权限错,而是静默拒绝文件操作,导致启动卡住或日志里只写 Starting MySQL... FAILED!。
临时验证是否是它挡路:
- CentOS:执行
setenforce 0再试启动;若成功,说明 SELinux 策略没更新 - Ubuntu:执行
aa-status查看 apparmor 是否运行,再sudo aa-disable /usr/sbin/mysqld临时关掉
长期方案不是关防护,而是打策略补丁:
- SELinux:用
semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?",再restorecon -Rv /data/mysql - AppArmor:编辑
/etc/apparmor.d/usr.sbin.mysqld,在/var/lib/mysql/** rwk,下加一行/data/mysql/** rwk,,然后sudo systemctl reload apparmor
启动失败时最该盯的日志位置
别只看 systemctl status mysql 的一句话状态。真正线索在:
- MySQL 错误日志:由配置中
log-error指定,若没设,默认在datadir下的hostname.err文件里 - 系统日志:
journalctl -u mysql -n 50 -f(systemd)或tail -n 20 /var/log/syslog | grep mysql(sysv)
典型卡点错误包括:
-
InnoDB: Operating system error number 13 in a file operation→ 权限或 SELinux -
Can't find file: './mysql/plugin.frm'→datadir指向了空目录或结构不全 -
Failed to initialize databases→ 新路径下残留旧ibdata1但没对应ib_logfile*,或 InnoDB 日志大小不匹配
迁移后首次启动若提示初始化数据库,说明路径完全没识别到原有数据,大概率是复制没到位或 datadir 配置写错位置(比如写进了 [client] 段)。











