在 Ubuntu 22.04 上迁移 MySQL 8 的数据目录到另一个磁盘,一般可以分为 停库 → 拷贝数据 → 修改配置 → 改权限 → 启动验证 这几个步骤。
我给你一个详细且可回滚的方案(不会直接覆盖旧数据,确保安全)。
1. 检查 MySQL 数据目录位置
默认在 /var/lib/mysql
:
sudo systemctl status mysql
# 或
sudo mysql -e "SHOW VARIABLES LIKE 'datadir';"
2. 停止 MySQL 服务
sudo systemctl stop mysql
确保停掉后,ps -ef | grep mysql
没有残留的 mysqld
进程。
3. 拷贝数据到新磁盘目录
假设你要迁移到 /mnt/data/mysql
(新磁盘已经挂载好并有足够空间):
# 创建新目录
sudo mkdir -p /mnt/data/mysql
sudo chown mysql:mysql /mnt/data/mysql
sudo chmod 750 /mnt/data/mysql# 使用 rsync 保持权限和软链接
sudo rsync -av --progress /var/lib/mysql/ /mnt/data/mysql/
注意:
rsync
的末尾/
不能省,否则会多一层mysql
目录。-a
会保留所有权限和时间戳。
4. 修改 MySQL 配置
MySQL 8 在 Ubuntu 22.04 下通常用 mysqld.cnf
:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
找到:
datadir = /var/lib/mysql
改成:
datadir = /mnt/data/mysql
如果 MySQL 使用了 socket 文件路径(socket=/var/run/mysqld/mysqld.sock
),一般不用改,但如果你的新磁盘不在 /var/run
,就要确保 socket 目录权限正确。
5. 更新 AppArmor 配置(Ubuntu 特有)
Ubuntu 默认用 AppArmor 限制 MySQL 访问路径,你需要给新目录放行。
编辑:
sudo nano /etc/apparmor.d/usr.sbin.mysqld
找到类似:
/var/lib/mysql/ r,
/var/lib/mysql/** rwk,
在下面加:
/mnt/data/mysql/ r,
/mnt/data/mysql/** rwk,
保存后重载 AppArmor:
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld
6. 权限确认
sudo chown -R mysql:mysql /mnt/data/mysql
sudo chmod 750 /mnt/data/mysql
7. 启动 MySQL
sudo systemctl start mysql
检查是否正常:
sudo systemctl status mysql
sudo mysql -e "SELECT @@datadir;"
8. 验证无误后删除旧目录
sudo mv /var/lib/mysql /var/lib/mysql.bak # 先备份
# 等一两天确认没问题再删除
sudo rm -rf /var/lib/mysql.bak
可能的坑
- 忘记更新 AppArmor → MySQL 启动报错“Permission denied”。
- 权限不对 →
mysqld
无法访问目录。 - SELinux(CentOS)的问题 → Ubuntu 默认没有 SELinux,所以不用处理。
- socket 路径问题 → 迁移后客户端连接失败,需要确认
/var/run/mysqld
存在并有mysql:mysql
权限。
如果你愿意,我可以帮你写一个 一键迁移脚本,执行后会自动完成拷贝、改配置、更新 AppArmor、验证,并且支持回滚到原目录。
这样就不用担心操作出错。