目录

MariaDB / MySQL 数据目录搬家怎么搞?一步都不能错的迁移流程

系统盘越用越满,/var/lib/mysql 眼看要爆。

云磁盘数据盘 /data1 空着一大片,最直接的办法就是把 MariaDB 的数据目录整个搬过去。

某些情况下也需要更改数据库的数据目录位置,不再使用默认的 /var/lib/mysql

听起来只是 mv 一下的事,真动手才发现坑不少:权限、SELinux、配置文件路径、应用侧的连接顺序,任何一环没对齐,服务就起不来。

下面这套流程在生产环境跑通过,照着做基本不会翻车。

为什么要迁移 datadir?

数据库的数据文件默认放在 /var/lib/mysql,也就是跟操作系统同一块盘。

小项目无所谓。数据量一上来,问题就来了。

一是磁盘空间告急,系统盘和数据混在一起谁也别想扩。

二是 IO 抢占,日志、包管理、数据库读写全挤在一块盘上,性能被拖累。

把 datadir 单独挪到一块大容量的数据盘(比如 /data1),是最省事的解决方案。

不用改应用代码,不用停业务太久,几个 rsync 命令搞定。

还有些情况可能为了方便数据管理,不再使用默认的位置 /var/lib/mysql

迁移前的准备工作

动手前先确认三件事,能少踩一半的坑。

第一,新盘挂载点是不是稳定的(如果只是迁移目录,可以忽略此步骤)。

df -h 看一下 /data1 是不是已经挂载好,别搞完发现是临时目录,重启就丢。

第二,数据量有多大,rsync 会跑多久。

du -sh /var/lib/mysql 心里有个数。几十 G 的库用 rsync 拷贝,通常几分钟到十几分钟。

第三,业务方是否可以停服。

数据库停止期间应用会 502,最好挑低峰期或者维护窗口执行。

完整迁移步骤

第一步:停止应用层服务

数据库是被业务依赖的,先把上层应用停掉,避免迁移过程中还有写请求进来。

具体停止因业务服务不同操作不同

停完后验证下服务是否不能正常访问。

如果还能访问,说明有别的进程在跑,需要检查下服务是否仍旧在执行。

第二步:停止 mysql 服务

如果装的不是 mysql,而是 mariadb,则将下面的 mysqld 改为 mariadb。

systemctl stop mysqld
systemctl status mysqld

status 命令确认状态是 inactive (dead)

这一步很关键。

数据库还在跑的时候拷贝数据文件,拷过去的东西大概率是坏的,innodb 表空间和 redo log 状态不一致,起不来。

第三步:创建新目录并设置属主

本次是迁移数据目录到 /data1/mysql/data

mkdir -p /data1/mysql/data
chown -R mysql:mysql /data1/mysql

MySQL 进程是以 mysql 用户身份跑的,目录属主必须是 mysql。

这里最容易踩的坑是只 chown 了最内层的 data 目录,父目录 /data1/mysql 还是 root,结果 mysql 用户没有遍历权限,启动失败。

chown -R/data1/mysql 顶层,一次性搞定。

第四步:用 rsync 同步数据

rsync -av /var/lib/mysql/ /data1/mysql/data/

注意源路径末尾的斜杠 /,加不加意义完全不同。

带斜杠是把 mysql 目录里面的内容拷贝到 data 目录里。

不带斜杠是把整个 mysql 目录作为子目录拷进去,路径会变成 /data1/mysql/data/mysql,多套一层,数据库直接找不到系统表。

-av 参数保留权限、属主、时间戳,这个不能省。

第五步:重命名旧数据目录(不删)

mv /var/lib/mysql /var/lib/mysql-bak-20260917

不要用 rm -rf 直接删。

万一新目录起不来还能回滚。等新服务跑稳几天再删也不迟。

后缀带上日期,一眼看出啥时候备份的,比 mysql-bak 强多了。

第六步:备份并替换配置文件

datadir 变了,配置文件必须跟着改。

先备份旧配置(Debian / Ubuntu 系一般在 /etc/mysql/conf.d/,CentOS / RHEL 系一般在 /etc/my.cnf.d/,按实际发行版调整):

mv /etc/mysql/conf.d/my.cnf /etc/mysql/conf.d/my.20260917.cnf

然后按新目录改 my.cnf,一般改这几段:

[mysqld]
datadir=/data1/mysql/data
socket=/data1/mysql/data/mysql.sock

[client]
socket=/data1/mysql/data/mysql.sock

[mysql]
socket=/data1/mysql/data/mysql.sock

新配置里 datadir= 那一行要指向 /data1/mysql/data,还有 socket 路径也要检查,很多应用连的是 /var/lib/mysql/mysql.sock,如果 socket 也挪了位置,应用侧的连接串得同步改。

不确定的话,socket 路径保留在 /var/lib/mysql/mysql.sock 是最稳的选择,需要在旧路径下建一个空目录并给 mysql 用户权限。

第七步:启动数据库验证

systemctl start mysqld
systemctl status mysqld

状态是 active (running) 才算成功。

启动失败别慌,看日志:

journalctl -u mysqld -n 100 --no-pager

九成的报错都是权限问题或者 SELinux 拦截。

第八步:验证数据库

先进 mysql 客户端:

mysql -uroot -p

然后敲两条命令:

show databases;
SHOW VARIABLES LIKE 'datadir';

第一条确认库都在,第二条确认现在读的确实是新目录。

两条都过了才算迁移真正生效。

第九步:启动业务应用

具体启动命令视业务而定,跟第一步的停止操作对应即可。

启动后打开业务地址验证功能,尤其是涉及写库的接口,跑一遍确认能正常读写。

第十步:清理和归档

新服务稳定跑几个小时到一天后,可以打包旧数据留个存档:

sudo tar -czpf /data1/mysql-bak-20260917.tar.gz -C /var/lib mysql-bak-20260917

-p 参数保留权限信息,恢复的时候用得上。

最后稳定后就可以把旧的数据目录删除了。

另外可以使用 du -sh * | sort -hr 看下当前目录哪个占的最多,方便继续清理。

关键路径一览

项目 旧路径 新路径
数据目录 /var/lib/mysql /data1/mysql/data
备份目录 /var/lib/mysql-bak-20260917
主配置文件 /etc/mysql/conf.d/my.cnf(发行版可能不同) 同路径(内容已更新)
归档包 /data1/mysql-bak-20260917.tar.gz

常见问题 FAQ

Q1. rsync 迁移和 mysqldump 迁移有啥区别?

rsync 是文件级拷贝,需要停服,但速度快、数据一致性有保障,适合本机换目录。

mysqldump 是逻辑备份,可以热备但恢复慢,适合跨版本、跨机器迁移。

同一台机器搬 datadir,rsync 是首选。

Q2. 一定要停服吗?可以不停机迁移吗?

同一实例的 datadir 迁移必须停服。

真的要不停机,得搭主从:新机器搭一个 slave,同步完再做主从切换,业务几乎无感知。

但这个方案复杂度高一个数量级,几十 G 的库不值得。

Q3. 启动报错 “Can’t create test file” 怎么办?

这是权限问题。

检查三个地方:/data1/mysql/data 属主是不是 mysql、SELinux 上下文对不对、AppArmor(Ubuntu 系统)有没有拦截。

Ubuntu 上还要改 /etc/apparmor.d/usr.sbin.mysqld 加上新路径。

Q4. 迁移后 socket 文件找不到怎么办?

MariaDB 默认 socket 在 /var/lib/mysql/mysql.sock,如果这个目录被删了,socket 也没了。

两种解法:一是配置里改 socket 路径到新目录,同时改应用连接串;二是保留 /var/lib/mysql 目录(属主给 mysql)专门放 socket,最省事。

Q5. 旧数据什么时候能真删?

保守做法是跑满一周没问题再删。

生产环境的数据,宁可多留几天占点盘,也不要图省事直接 rm。

打包成 tar.gz 归档到别的目录,随时能恢复,心里踏实。

写在最后

数据库运维这活,看着都是几个命令的事,坑基本都在细节里:斜杠加没加、属主对不对、SELinux 开没开、socket 挪没挪。

按上面这套流程走一遍,基本能把常见问题都规避掉。

真遇到起不来的情况,先看 journalctl -u mysqld(MariaDB 就换成 mariadb),日志比猜测靠谱得多。

如果大家在迁移过程中遇到别的报错,或者有更优雅的方案,欢迎在评论区交流~~~

版权声明

未经授权,禁止转载本文章。
如需转载请保留原文链接并注明出处。即视为默认获得授权。
未保留原文链接未注明出处或删除链接将视为侵权,必追究法律责任!

本文原文链接: https://fiveyoboy.com/articles/how-to-migrate-mariadb-mysql-datadir/

备用原文链接: https://blog.fiveyoboy.com/articles/how-to-migrate-mariadb-mysql-datadir/