MySQL 5.7 默认开启 innodb_file_per_table,但必须执行 SHOW VARIABLES LIKE 'innodb_file_per_table'; 确认返回 ON 才能确保新建表使用独立 .ibd 文件;若为 OFF,则所有表数据写入 ibdata1,且动态修改仅对后续新建或重建的表生效,旧表需逐个执行 ALTER TABLE ... ENGINE=InnoDB 迁移。

直接改 datadir 并复制数据是可行的,但必须同步处理权限、SELinux/AppArmor、socket 路径和系统服务配置,漏掉任意一项都会导致启动失败。
停服务前先确认 innodb_file_per_table 是否开启
MySQL 5.7 默认已启用该选项,但需验证:登录后执行 SHOW VARIABLES LIKE 'innodb_file_per_table';。返回 ON 才能确保每个表有独立 .ibd 文件,后续迁移才安全可靠。若为 OFF,不建议直接迁移整库——先用 ALTER TABLE tbl_name ENGINE=InnoDB; 逐个重建表,否则所有数据会挤在 ibdata1 里,无法按表拆分存放。
复制数据时用 rsync -av 而不是 cp -r
rsync 能保留所有关键元数据,cp -r 在某些发行版上会丢掉 SELinux 上下文或 ACL 权限,导致 MySQL 启动报错 Can't open the mysql.plugin table 或 Permission denied。
-
rsync -av --progress /var/lib/mysql/ /new/disk/mysql/(注意源路径末尾有斜杠,表示同步内容而非目录本身) - 复制完成后立即执行
chown -R mysql:mysql /new/disk/mysql - 若系统启用了 SELinux(如 CentOS/RHEL),还需运行:
semanage fcontext -a -t mysqld_db_t "/new/disk/mysql(/.*)?"; restorecon -Rv /new/disk/mysql
配置文件里不止 datadir 一行要改
只改 datadir 是最常见失误。MySQL 启动时还会读取以下路径,若仍指向旧位置,服务会卡在初始化阶段:
-
socket:必须与新datadir下的mysql.sock实际位置一致,例如socket = /new/disk/mysql/mysql.sock -
pid-file:默认常写成/var/lib/mysql/mysqld.pid,需同步改为新路径下的对应位置 -
log-error:错误日志路径,若旧路径不可写,MySQL 直接拒绝启动 -
innodb_log_group_home_dir:若显式设置了该参数(非默认),也必须指向新磁盘上的redo log存放目录
启动失败优先查 Windows 事件查看器或 journalctl -u mysqld
命令行 systemctl start mysqld 报错信息往往太简略。真实原因藏在更底层:
- Linux 下执行
journalctl -u mysqld -n 50 -f,看最后一屏具体报错,比如Can't create test file /new/disk/mysql/...就是权限或 SELinux 拦截 - Windows 下打开“事件查看器 → Windows 日志 → 应用程序”,过滤来源为
Mysql,错误详情会明确指出哪个路径访问被拒、缺哪个 DLL 或配置项拼写错误 - 切勿依赖
ps aux | grep mysql判断是否启动成功——进程可能闪退后残留,实际未进入服务状态
真正麻烦的从来不是复制数据,而是那些配置项之间隐性的路径耦合。哪怕只漏改一个 pid-file,MySQL 就会在写入时失败并静默退出,连错误日志都落不下去。


















