Ubuntu 下 MySQL 数据库迁移方法
一 迁移方式总览
- 逻辑迁移:使用 mysqldump 导出为 SQL 脚本,在目标库导入。适合跨版本、跨平台、跨主机迁移,操作安全、可控,推荐作为首选方案。
- 物理迁移:直接拷贝数据目录(如 /var/lib/mysql)到新位置或新服务器,速度快,但要求 MySQL 版本与配置高度一致,多用于同版本同构环境。
- 版本升级场景:低版本到高版本可用 mysqldump 全量迁移,必要时配合二进制日志做时间点恢复;不建议跨大版本直接降级。
二 逻辑迁移步骤(跨主机 跨版本通用)
- 1 备份源库
- 全库导出(不含 mysql 系统库,便于跨版本导入):
mysqldump -uroot -p --databases 你的库1 你的库2 > backup.sql
- 全量导出(含系统库,适合同版本原地恢复):
mysqldump -uroot -p -A > backup.sql
- 一致性快照(InnoDB):
mysqldump -uroot -p --single-transaction --routines --triggers --events --master-data=2 你的库 > backup.sql
- 传输到目标机:
scp backup.sql user@目标IP:/path/
- 2 准备目标库
- 安装同系列 MySQL(跨版本时目标版本需高于或等于源版本),创建同名数据库(若按库导出可省略建库)。
- 3 导入数据
- mysql -uroot -p < backup.sql
- 4 校验
- 登录检查:SHOW DATABASES; USE 库名; SHOW TABLES; SELECT COUNT(*) FROM 表名;
- 5 可选时间点恢复(有写入时)
- 从备份点起截取 binlog:mysqlbinlog --start-datetime=“2025-11-28 10:00:00” /var/log/mysql/mysql-bin.00000X | mysql -uroot -p
三 物理迁移步骤(同版本 同构 或 仅更换数据目录)
- 1 确认当前数据目录
- mysql -uroot -p -e “SHOW VARIABLES LIKE ‘datadir’;”
- 常见路径:/var/lib/mysql
- 2 停止 MySQL
- sudo systemctl stop mysql
- 3 迁移数据目录
- 推荐先复制保留原始数据:
sudo cp -a /var/lib/mysql /mnt/data/mysql
- 或移动:
sudo mv /var/lib/mysql /mnt/data/mysql
- 4 修改配置
- 编辑 /etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf,在 [mysqld] 下设置:
datadir=/mnt/data/mysql
- 保持 socket 路径不变(如 /var/run/mysqld/mysqld.sock),避免应用改动。
- 5 配置 AppArmor(Ubuntu 特有)
- 编辑 /etc/apparmor.d/usr.sbin.mysqld,将旧路径的权限规则替换为新路径:
/mnt/data/mysql/ r,
/mnt/data/mysql/** rwk,
- 如 abstractions/mysql 中有旧 sock 规则,一并替换为新路径。
- 6 启动服务
- sudo systemctl reload apparmor
- sudo systemctl start mysql
- 7 权限与上级目录可访问性
- 确保 /mnt/data 及其上级目录对 mysql:mysql 具备执行(x)与读取(r)权限,否则可能出现“Can’t connect to local MySQL server through socket”或“只读”类错误。
- 8 校验
- 登录验证:mysql -uroot -p -e “SHOW VARIABLES LIKE ‘datadir’;” 并查看错误日志 /var/log/mysql/error.log。
四 跨版本迁移注意事项
- 版本策略:优先选择 低到高 的升级路径;跨大版本不建议直接降级(如 5.7 → 5.6),因系统库不兼容会导致旧版本无法启动。
- 导出选项:InnoDB 建议使用 –single-transaction 获取一致性快照;含存储过程/触发器/事件请加 –routines --triggers --events;需要基于时间点的恢复加 –master-data=2。
- 导入后检查:必要时执行 mysql_upgrade(MySQL 5.7/8.0 常用)以升级系统表与字典对象;导入后核对视图/触发器/外键/存储过程是否可用。
- 字符集与 SQL 模式:确认 character_set_server/collation_server 与目标一致,避免乱码或约束差异。
- 权限与账户:导入后使用 FLUSH PRIVILEGES; 刷新权限;跨主机迁移时,注意复制用户的主机限制(如从 localhost 改为 %)。
五 常见问题与排查
- 无法启动或报“Table ‘plugin’ is read only”
- 检查新 datadir 及所有上级目录对 mysql:mysql 的 r/x 权限;确认 AppArmor 已放行新路径;查看 /var/log/mysql/error.log 定位具体报错。
- ERROR 2002 (HY000): Can’t connect to local MySQL server through socket
- 多数因 socket 路径 配置不一致或 AppArmor 未放行;保持 my.cnf 中 socket 为 /var/run/mysqld/mysqld.sock,并在 AppArmor 为 /mnt/data/mysql{,d}/mysql{,d}.sock 增加读写权限。
- 权限设置过宽
- 不建议将上层目录设为 777;仅确保到 datadir 的路径具备必要权限(mysql 用户能进入并读写),更安全可控。