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 mysqldstatus 命令确认状态是 inactive (dead)。
这一步很关键。
数据库还在跑的时候拷贝数据文件,拷过去的东西大概率是坏的,innodb 表空间和 redo log 状态不一致,起不来。
第三步:创建新目录并设置属主
本次是迁移数据目录到 /data1/mysql/data。
mkdir -p /data1/mysql/data
chown -R mysql:mysql /data1/mysqlMySQL 进程是以 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/