MySQL迁移datadir需先查清当前路径和运行用户,再用rsync复制数据,同步修改my.cnf、SELinux/AppArmor策略、InnoDB日志路径及socket路径,最后通过error.log定位启动失败原因。

确认 MySQL 当前 datadir 路径和运行用户
不查清楚当前状态就改,八成会启动失败。先连上 MySQL 执行:
SELECT @@datadir;再看系统里 MySQL 进程以谁的身份跑:
ps aux | grep mysql通常为
mysql 用户,但有些发行版用 mysqld 或 root(后者极危险,需先改掉)。关键点:新目录的属主必须和这个用户完全一致,不能只靠 chmod 755 补救。
停库后复制数据,别用 mv 直接移动
直接 mv 风险高——万一新磁盘空间不足、权限没设好、SELinux 拦着,MySQL 启不来,又没备份,就只能翻日志硬扛。稳妥做法是:
- 执行
sudo systemctl stop mysql(或mysqld,依服务名而定) - 用
rsync -avh --progress /var/lib/mysql/ /new/path/mysql/复制(注意末尾斜杠!) - 复制完校验:
sudo diff -r /var/lib/mysql /new/path/mysql(忽略auto.cnf和binlog文件) - 确认无误再删旧目录(可先重命名留底)
修改 my.cnf 并处理 SELinux / AppArmor
编辑主配置文件(常见路径:/etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),在 [mysqld] 段下写死:
datadir = /new/path/mysql然后重点来了:
- Linux 发行版带 SELinux(如 CentOS/RHEL):运行
sudo semanage fcontext -a -t mysqld_db_t "/new/path/mysql(/.*)?",再sudo restorecon -Rv /new/path/mysql - Ubuntu/Debian 启用了 AppArmor:需更新
/etc/apparmor.d/usr.sbin.mysqld,把旧路径替换成新路径,再sudo systemctl reload apparmor - 跳过这步?MySQL 日志里大概率出现
Can't open the mysql.plugin table或Permission denied,但错误信息根本不会提 SELinux
启动失败时优先检查 error log 和 socket 路径
改完启动报错,别急着重启。先看真实日志:
sudo tail -n 50 /var/log/mysql/error.log(路径以
log_error 配置项为准)。高频问题有:
-
Can't find file: './mysql/plugin.frm'→ 权限或 SELinux 没到位 -
Failed to open log (file './ib_logfile0')→innodb_log_group_home_dir还指向旧路径,需同步修改 -
Can't start server: Bind on TCP/IP port→ 实际是 socket 文件路径不对,检查socket配置项是否还卡在/var/run/mysqld/mysqld.sock,要一并改成新路径下的对应位置
datadir 本身的问题。
最麻烦的从来不是复制文件,而是那些没写在文档里、却实际拦路的策略机制——SELinux 上下文、AppArmor 规则、InnoDB 日志路径、socket 文件位置、甚至 systemd 的 ProtectHome=true 设置。改之前通读一遍 mysqld --verbose --help | grep -A1 "Default options",比反复重启试错快得多。


















