最可靠方式是登录后执行SELECT @@datadir;获取实际datadir路径,再用mysqld --help --verbose | grep "Default options"查看配置加载顺序,优先级由高到低依次为:/etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf等,且systemd环境变量可最高优先级覆盖。

直接查当前真实 datadir 路径,别信配置文件
MySQL 启动时实际用的路径,和 my.cnf 里写的不一定一致。最可靠的方式是登录后执行:SELECT @@datadir;。返回值就是它正在读写的目录,哪怕 my.cnf 里改错了、systemd 覆盖了、或者配置加载顺序搞混了,这个结果也永远准确。
顺带查下配置加载顺序:mysqld --help --verbose | grep "Default options",看它到底读了哪些文件(比如 /etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf),谁在前谁生效。Ubuntu/Debian 的宝塔或官方包还可能在 /usr/lib/systemd/system/mysqld.service 里用 Environment=MYSQLD_OPTS=--datadir=... 强制覆盖——这种写法不进配置文件,但优先级最高。
迁移前必须停服务 + 用 rsync 复制 + 重打 SELinux 标签
没停干净就复制,极大概率损坏 ibdata1 或事务日志;用 cp -r 复制,会丢 socket 文件权限和扩展属性,启动报 Can't start server: Bind on unix socket: Permission denied。
- 先彻底停服务:
sudo systemctl stop mysqld,再确认无残留进程:ps aux | grep mysql - 用
rsync -avh --progress /var/lib/mysql/ /new/path/mysql/(注意源路径末尾有斜杠!否则会把整个mysql/目录嵌套进去) - Linux 启用了 SELinux(CentOS/RHEL 默认开)必须重打标签:
sudo semanage fcontext -a -t mysqld_db_t "/new/path/mysql(/.*)?",然后sudo restorecon -Rv /new/path/mysql - 权限要设对:
sudo chown -R mysql:mysql /new/path/mysql,父目录也得让mysql用户能进入
改配置只动 datadir,但 socket/pid-file/log-error 得同步更新
datadir 改了,其他路径没跟着动,MySQL 启动时会卡在第一步:找不到 socket、写不了 pid、打不开 error log。常见报错包括 Can't start server: Bind on unix socket 或 Cannot write into log file。
打开 my.cnf,在 [mysqld] 段落里确保这几项都指向新路径或合理位置:
datadir = /new/path/mysqlsocket = /new/path/mysql/mysql.sockpid-file = /new/path/mysql/mysqld.pid-
log-error = /new/path/mysql/error.log(或保持原 error log 路径,只要权限 OK)
别漏掉注释掉旧的 datadir 行——配置文件里出现两行 datadir,MySQL 会取最后一行,容易误判。
启动失败先看 error log,重点搜 Permission denied 和 Can't open file
90% 的失败不是路径写错,而是环境没对齐。别急着重启,先看日志:sudo tail -n 50 $(grep "log-error" /etc/my.cnf | awk '{print $3}')(或默认位置 /var/log/mysqld.log)。
高频线索:
- 出现
Permission denied:不是权限没设,八成是 SELinux/AppArmor 拦截,或父目录缺少x权限(mysql用户进不去) - 出现
Can't open file: './mysql/plugin.frm'或Table 'mysql.plugin' doesn't exist:说明datadir指向空目录,数据根本没复制过去,或复制时漏了隐藏文件(rsync带-a才保全) - 启动后连不上:
mysql -u root -S /new/path/mysql/mysql.sock测试 socket 是否可访问,别只用-h localhost(那走 TCP,绕过 socket 权限问题)
真正麻烦的点不在“怎么改”,而在“改完之后 MySQL 信不信你给的新路径”——它要能进目录、能建 socket、能写 pid、能追 error log、还能读到 ibdata1 和 mysql/ 子目录。少一环,就起不来。


















