mysql数据目录迁移失败主因是权限、selinux、配置加载顺序、socket路径、挂载参数未同步调整。需依次检查并修正这五点,缺一不可。

MySQL 数据文件路径改到新目录后启动失败
直接改 datadir 启动不起来,大概率是权限或 SELinux 挡着了。MySQL 进程(通常是 mysqld 用户)必须对新路径有完整读写权限,且不能只靠 chown mysql:mysql 就完事。
- 先停掉 MySQL:
systemctl stop mysqld(或mysql.server stop) - 用
rsync -avP /var/lib/mysql/ /new/path/mysql/迁移,别用cp—— 保留属主、权限、socket 文件等细节 - 修改
/etc/my.cnf或/etc/mysql/my.cnf中的datadir,比如改成datadir=/new/path/mysql - 检查新路径父目录权限:MySQL 不会自己创建多级目录,
/new/path至少得让mysqld用户能进入(即执行权限),常见坑是/new目录权限为700且属主不是mysql - SELinux 开启时,必须加上下文:
semanage fcontext -a -t mysqld_db_t "/new/path/mysql(/.*)?",再restorecon -Rv /new/path/mysql
my.cnf 里改了 datadir 但 MySQL 还读旧路径
配置没生效,八成是 MySQL 加载了别的配置文件,或者 datadir 被命令行参数覆盖了。
- 运行
mysqld --verbose --help | grep "Default options"看它实际读哪些配置文件(顺序很重要,后面覆盖前面) - 检查是否有
/etc/my.cnf.d/*.cnf或~/.my.cnf里也写了datadir,尤其注意[mysqld]段落是否写对了——写成[client]或漏段落名就无效 - 确认没在 systemd service 文件里硬编码启动参数,比如
/usr/lib/systemd/system/mysqld.service中的ExecStart=...后面带了--datadir=... - 改完配置务必用
mysqld --validate-config(MySQL 5.7.20+)或至少mysqld --defaults-file=/etc/my.cnf --verbose --help | grep datadir验证值是否被正确读取
迁移后连接报错 Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'
socket 文件路径没跟着变,客户端还在找旧位置的 sock 文件。
- 在
[mysqld]段加上socket=/new/path/mysql/mysql.sock(和datadir同级) - 同时在
[client]和[mysql]段也写一遍socket=...,否则mysql命令行工具连不上 - 如果用 socket 连接的应用(比如 PHP 的
mysqli)仍失败,检查它们是否显式指定了unix_socket参数,或是否依赖MYSQL_UNIX_PORT环境变量 - 重启后用
ss -l | grep mysql或ls -l /new/path/mysql/mysql.sock确认 sock 文件真生成了,且属主是mysql
从 ext4 迁移到 XFS 或挂载新磁盘后性能反而下降
路径迁了,但文件系统挂载选项或 I/O 调度器没调,MySQL 写密集型负载容易卡住。
- 新挂载点必须加
noatime,nobarrier(XFS)或data=writeback,barrier=0(ext4),否则每次写都刷 atime 或 journal,吞吐掉一半 - 确认磁盘调度器是
deadline或none(SSD):cat /sys/block/sdX/queue/scheduler,别留cfq - 如果新路径在 LVM 或 RAID 上,确保
read_ahead_kb调大(比如echo 16384 > /sys/block/vg-lv/queue/read_ahead_kb),InnoDB 随机读受益明显 - 别忘了调整
innodb_log_file_size和innodb_buffer_pool_size—— 新磁盘空间大了,旧配置可能严重浪费或过载











