【Linux】MySQL数据目录迁移步骤(含流程图&踩坑经验)

发布于:2025-09-09 ⋅ 阅读:(25) ⋅ 点赞:(0)

在生产环境中,有时候你会遇到一些看似简单但实际上很棘手的问题。最近我就碰到了一次典型的服务器磁盘空间告急,最后通过迁移 MySQL 数据目录成功解决了问题。本文记录整个过程,包括我的分析思路、迁移步骤、踩坑和经验总结,希望对你有帮助。


一、问题背景

公司的一台业务数据库服务器,运行的是 MySQL 8.0.20,数据目录默认放在:

/data/mysql-8.0.20/data

随着业务数据的增长,/data 分区的空间渐渐被吃满,监控报警开始提示:

Disk space usage on /data exceeds 98%

打开 df -h 一看,果然 /data 分区只剩不到 1GB,而 /home 分区却很空闲,有几十 MB 可用。


二、分析思路

  1. 确认空间问题是否由 MySQL 引起

    du -sh /data/mysql-8.0.20/data
    

    结果:

    38G /data/mysql-8.0.20/data
    

    → 明确是 MySQL 数据目录占了大头。

  2. 能否扩容 /data 分区?

    • 由于这台是虚拟机,业务部门不方便短期扩容。
    • 考虑将数据目录迁移至磁盘更大的 /home 分区
  3. 迁移 MySQL 数据目录的关键点

    • 必须 停库迁移,否则数据会不一致。
    • 迁移后需要修改 配置文件 datadir
    • 新路径权限必须正确(mysql:mysql,SELinux 要处理)。
    • 迁移过程要有 回退方案(先复制,验证成功后再删旧数据)。

三、实现步骤

在正式进行迁移前,我们先看一下整个迁移的流程图,帮助你对后续的步骤有直观印象。
在这里插入图片描述

1. 停止 MySQL 服务

sudo systemctl stop mysqld
ps -ef | grep mysqld   # 确认进程关闭

2. 创建新目录

sudo mkdir -p /home/mysql/data

3. 迁移数据

建议先复制,确保安全:

sudo cp -av /data/mysql-8.0.20/data/* /home/mysql/data/

(等验证 OK 再删除旧目录)


4. 修改 MySQL 配置

编辑 /etc/my.cnf(路径可能不同,根据实际环境调整):

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

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

5. 更新权限

sudo chown -R mysql:mysql /home/mysql/data
sudo chmod 750 /home/mysql/data

6. SELinux 处理(重要)

CentOS / RHEL 默认 /home 属于 home_t 类型,MySQL 无法直接访问,需要修改安全上下文:

查看 SELinux 状态:

getenforce

如果输出 Enforcing,执行:

sudo semanage fcontext -a -t mysqld_db_t "/home/mysql/data(/.*)?"
sudo restorecon -Rv /home/mysql/data

(如果只是验证,可以先用 setenforce 0 暂时关闭 SELinux)


7. 启动 MySQL

sudo systemctl start mysqld

8. 验证新目录生效

SHOW VARIABLES LIKE 'datadir';

结果应为:

/home/mysql/data/

9. 清理旧目录

确认 MySQL 稳定运行几天再删除旧目录:

sudo rm -rf /data/mysql-8.0.20/data

四、踩坑记录

在迁移过程中我踩了一些坑,也分享出来避免大家踩同样的雷:

  1. 忘记改权限 → 启动失败

    The server quit without updating PID file
    

    解决:chown -R mysql:mysql /home/mysql/data

  2. SELinux 拒绝访问新目录

    • 关闭 SELinux 后启动成功 → 说明是安全上下文问题
    • 永久解决:使用 semanage fcontextrestorecon 修改为 mysqld_db_t
  3. 客户端连接失败

    • 因为 socket 文件路径变了,要同步修改 [client] 部分的 socket 配置

五、经验总结

  1. 生产环境操作一定要有回退方案

    • cp 而不是直接 mv
    • 保留旧数据目录,确认没问题后再删
  2. 权限和 SELinux 是 MySQL 无法启动的核心原因

    • 迁移路径后务必 chown + SELinux 规则调整
  3. 提前规划数据目录的位置

    • 尽量放在可扩容的分区,或者挂载点规划时预留足够磁盘空间
  4. 验证后再清理

    • 保留一段时间旧目录,是救命稻草

六、参考命令速查表

# 停mysql
systemctl stop mysqld

# 拷贝数据目录
cp -av /data/mysql-8.0.20/data/* /home/mysql/data/

# 修改配置文件
vim /etc/my.cnf

# 权限
chown -R mysql:mysql /home/mysql/data
chmod 750 /home/mysql/data

# SELinux规则调整
semanage fcontext -a -t mysqld_db_t "/home/mysql/data(/.*)?"
restorecon -Rv /home/mysql/data

# 启动MySQL
systemctl start mysqld

# 验证数据目录
SHOW VARIABLES LIKE 'datadir';

💡 写在最后
这次迁移虽然只是换了个目录,但背后体现的是处理 🛠 生产问题的三个关键能力

  • 快速定位根因
  • 制定低风险方案
  • 预留回退路径

实际生产中,看似琐碎的小问题,通过“按步骤 + 防风险”去执行,才不会把小问题变成大事故。


网站公告

今日签到

点亮在社区的每一天
去签到