mysql数据目录迁移需先确认datadir路径、磁盘占用及io状态;停库前须执行flush tables with read lock、记录主从位点、安全shutdown;挂载新盘时注意文件系统选择、挂载参数与rsync细节;迁移后须校验权限、selinux上下文、配置项一致性,并验证表空间元数据与i/o调度器设置。

确认 MySQL 数据目录当前路径和磁盘使用情况
先别急着挂载新盘,得知道现在 datadir 在哪、占了多少空间、是否真被 IO 卡住。很多人直接迁移,结果发现慢其实是查询没加索引,或者 innodb_buffer_pool_size 配得太小。
- 查当前数据目录:
mysql -e "SHOW VARIABLES LIKE 'datadir';" - 看磁盘占用和 IO 等待:
df -h /var/lib/mysql+iostat -x 1(关注%util和await) - 确认 MySQL 是否用了 LVM 或 RAID——这会影响你后续挂载方式和故障恢复逻辑
停库前必须做的三件事
MySQL 停库迁移不是“cp 一下再改配置”就完事。跳过任何一步,轻则启动失败,重则数据字典损坏,mysqld 直接拒绝启动。
- 执行
FLUSH TABLES WITH READ LOCK;(仅在主库需同步时用),然后SHOW MASTER STATUS;记下位点 - 运行
mysqladmin shutdown,**不要 kill -9** ——否则ib_logfile可能不完整,重启时触发崩溃恢复失败 - 备份原
datadir的权限和 SELinux 上下文:ls -ldZ /var/lib/mysql,迁移后权限/上下文错一个,mysqld启动会报Can't open the mysql.plugin table或直接 silent exit
挂载新盘并迁移数据的实操要点
新盘格式化、挂载、拷贝,每步都有隐性陷阱。尤其注意 rsync 参数和挂载选项,MySQL 对文件系统行为很敏感。
- 建议用
xfs(CentOS/RHEL 默认)或ext4(带noatime,nobarrier),避免btrfs或zfs(除非你明确调优过事务日志刷盘) - 挂载时加
noatime,errors=remount-ro,并确认mount | grep mysql输出里没有relatime或defaults - 用
rsync -avP --delete-after /var/lib/mysql/ /mnt/newdisk/mysql/(注意末尾斜杠!少一个会嵌套复制) - 拷完立刻
chown -R mysql:mysql /mnt/newdisk/mysql,再restorecon -Rv /mnt/newdisk/mysql(SELinux 环境下必须)
修改配置并验证启动是否真正成功
改完 my.cnf 里的 datadir,不代表万事大吉。MySQL 启动成功日志里一堆 warning,但连接进去一查表就报错,是常见假成功。
- 只改
datadir不够,还得同步检查:socket路径(如果也挪了)、pid-file、log-error是否仍指向旧路径 - 启动后别急着连业务,先跑:
mysql -e "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys');"确认所有库都可见 - 重点验证
INFORMATION_SCHEMA.INNODB_TABLESPACES和INFORMATION_SCHEMA.INNODB_SYS_TABLES是否有缺失记录——这是表空间元数据损坏的早期信号
最常被忽略的是:新盘的 I/O 调度器(如 deadline vs none)和队列深度(nr_requests)没调,SSD 性能可能只发挥出 60%。这事没法靠 MySQL 配置补救,得看 cat /sys/block/nvme0n1/queue/scheduler 和 /sys/block/nvme0n1/queue/nr_requests。











