Ubuntu系统下MySQL迁移实用指南

一 场景分析与迁移方案选择
- 跨服务器或跨实例迁移:优先选择逻辑备份与恢复方式(如 mysqldump),兼容性高、安全性好,可跨版本、跨平台迁移,适用于绝大多数 MySQL 数据迁移场景。
- 同机更换数据目录或挂载新硬盘:建议采用物理迁移(移动 datadir),对性能影响较小,但需要同步处理 AppArmor 策略与目录权限配置。
- 数据量特别大或业务停机时间极短:可考虑物理复制 InnoDB 表空间,并结合主从复制或分批导入方案,以尽可能缩短停机窗口,但前提是做好严格的一致性校验与回滚预案。
二 跨服务器或跨实例迁移步骤
- 准备与评估
- 先确认源库与目标库的 MySQL 版本、字符集、存储引擎以及关键参数差异;生产环境迁移前,建议务必在测试环境完整演练一次。
- 提前规划停机时间窗口和回滚策略,例如保留旧库为只读状态,或采用延迟切换方式降低风险。
- 备份与传输
- 逻辑备份(推荐):
- 单库:
- mysqldump -u [user] -p --single-transaction --routines --triggers --default-character-set=utf8mb4 [db] > backup.sql
- 全库(排除系统库):
- mysqldump -u [user] -p --single-transaction --routines --triggers --databases $(mysql -u [user] -p -Nse “SHOW DATABASES LIKE ‘yourdb_%’”) > backup.sql
- 压缩传输:
- gzip backup.sql && scp backup.sql.gz user@new_host:/backup/
- 单库:
- 文件传输到目标服务器后进行解压:gunzip backup.sql.gz
- 逻辑备份(推荐):
- 目标库准备
- 如果目标 MySQL 中已存在同名数据库,请先做好备份或改用新的库名;必要时同步调整 lower_case_table_names、字符集与排序规则等参数,避免导入后出现兼容性或一致性问题。
- 恢复与校验
- mysql -u [user] -p [db] < backup.sql(如为整库恢复,可直接执行:mysql -u [user] -p < backup.sql)
- 校验:登录 MySQL 后检查数据库和数据表数量、关键表记录数、主键外键关系,以及视图、存储过程是否可正常使用,并通过抽样查询确认数据准确无误。
- 切换与回滚
- 在正式切换前短暂停止源库写入,完成最终一致性核验后再修改应用连接配置;同时保留旧库只读运行一段时间,以便在出现异常时快速回滚。
三、同机更换数据目录或迁移至新盘
- 停库与确认路径
- sudo systemctl stop mysql
- 确认当前数据目录:mysql -e “SHOW VARIABLES LIKE ‘datadir’;”(常见默认路径为 /var/lib/mysql)
- 迁移数据
- 更推荐先复制后切换:sudo cp -a /var/lib/mysql /mnt/data/mysql
- 也可以直接移动:sudo mv /var/lib/mysql /mnt/data/mysql
- 配置调整
- 编辑配置文件(Ubuntu 常见路径为 /etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/mysql/my.cnf):
- [mysqld] 下设置:datadir = /mnt/data/mysql
- 如果 socket 路径也发生变化,需要同时更新 [mysqld] 与 [client] 中的 socket 配置,避免 MySQL 客户端无法连接。
- 编辑配置文件(Ubuntu 常见路径为 /etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/mysql/my.cnf):
- AppArmor 放行新路径
- 编辑 /etc/apparmor.d/usr.sbin.mysqld,将
- /var/lib/mysql/ r,
- /var/lib/mysql/** rwk,
替换为 - /mnt/data/mysql/ r,
- /mnt/data/mysql/** rwk,
- 如果 [client] 使用了自定义 socket,还需要在 /etc/apparmor.d/abstractions/mysql 中同步放行对应 socket 路径的读写权限。
- 编辑 /etc/apparmor.d/usr.sbin.mysqld,将
- 权限与启动
- sudo chown -R mysql:mysql /mnt/data/mysql
- sudo systemctl restart apparmor
- sudo systemctl start mysql
- 验证
- 登录 MySQL 检查:mysql -e “SHOW VARIABLES LIKE ‘datadir’;” 返回值应为新的数据目录;同时建议查看错误日志:tail -n 100 /var/log/mysql/error.log。
四 常见问题与排查要点
- 权限与所有权
- MySQL 数据目录及其子文件必须归属 mysql:mysql,目录权限通常建议为 700;否则 InnoDB 可能无法正常创建或写入文件,例如 ibdata1。
- AppArmor 误报
- 如果 MySQL 启动失败并提示权限错误,应优先检查 /var/log/mysql/error.log,同时确认 AppArmor 是否已正确放行新的 datadir 和 socket;必要时可使用 aa-status 查看状态并重新加载 AppArmor 配置。
- 配置文件读取顺序
- MySQL 会按照固定顺序加载配置文件(如 /etc/my.cnf → /etc/mysql/my.cnf → ~/.my.cnf),因此要确认修改的是实际生效的配置文件,并重点检查 [mysqld] 与 [client] 中 socket 配置是否保持一致。
- 大表与停机时间
- 对于大库或大表,逻辑导出与导入通常耗时较长,建议安排在业务低峰期执行,并通过 --single-transaction 尽量减少锁表影响;如果是超大数据库,可按库、按表拆分并行处理,或采用物理迁移结合复制的方案来进一步缩短停机时间。
