如何准备mysql迁移环境_mysql迁移前环境搭建

10次阅读

MySQL 迁移需先确认源库与目标库版本兼容性,检查 JSON 支持、认证插件等差异;导出时禁用 autocommit、使用 –single-transaction 和 utf8mb4 字符集;目标库须预建用户权限、匹配 sql_mode 与时区设置;还原前预建库,强制执行并日志分析,最后校验表结构与行数。

如何准备 mysql 迁移环境_mysql 迁移前环境搭建

确认源库与目标库的 MySQL 版本兼容性

MySQL 迁移失败多数源于版本越级或不兼容特性,比如 JSON 字段在 5.7+ 才原生支持,而 5.6 用 TEXT 模拟会导致 mysqldump 导出后无法导入;又如 8.0 默认认证插件改为 caching_sha2_password,老客户端直连会报 Client does not support authentication protocol

  • SELECT VERSION(); 分别查源库和目标库版本
  • 查官方文档的 Upgrading MySQL 章节,确认是否支持「直接升级」(如 5.7 → 8.0 允许,但 5.6 → 8.0 不推荐)
  • 若目标为 8.0,提前在目标库执行 ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'; 避免连接中断

导出前必须关闭 autocommit 并设置合理参数

默认 mysqldump 在大表场景下容易因超时、锁表或内存溢出失败。关键不是“能不能导”,而是“导出来的能不能安全还原”。

  • --single-transaction(仅对 InnoDB 有效),避免全库锁表;但注意它不能防止 DDL 变更,迁移窗口内禁止执行 ALTER TABLE
  • 禁用 --lock-tables(默认开启),否则 MyISAM 表会锁死整个库
  • 显式指定字符集:--default-character-set=utf8mb4,否则可能因服务端默认 latin1 导致 中文乱码
  • 大库建议加 --skip-triggers --skip-routines --skip-events,这些对象单独导出更可控
mysqldump -h source_host -u user -p --single-transaction --default-character-set=utf8mb4 --routines --triggers --databases db1 db2 > backup.sql

目标库需预建用户、权限及基础配置

很多迁移卡在还原阶段,不是 SQL 有问题,而是目标库缺少对应用户或权限不足,例如 CREATE PROCEDURE 需要 CREATE ROUTINE 权限,而 GRANT ALL PRIVILEGES 并不自动包含它。

  • SHOW CREATE USER 'user'@'%'; 查源库用户定义,注意 REQUIRE SSL 或密码过期策略是否需同步
  • 目标库执行 CREATE USER 后,必须显式 GRANT 所需权限,不要依赖 GRANT ALL
  • 检查 max_allowed_packet:若导出文件含大 BLOB,目标库该值需 ≥ 源库,否则 ERROR 2006 (HY000): MySQL server has gone away
  • 确认 sql_mode 一致,尤其避免目标库开了 STRICT_TRANS_TABLES 而源库没开,导致插入空字符串失败

验证迁移脚本能否在目标环境干净执行

直接 mysql 是最危险的操作——一旦中途报错,库可能处于半还原状态,且无回滚机制。

  • 先用 mysql -h target -u user -p -e "CREATE DATABASE IF NOT EXISTS db1 CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;" 预建库
  • mysql --verbose --force restore.log 强制继续并记录全部输出
  • 重点 grep 日志:grep -E "(ERROR|Warning)" restore.log,常见有 Unknown table 'xxx'(触发器引用了不存在的表)、Cannot add or update a child row(外键顺序错)
  • 还原后立即执行 CHECK TABLESELECT COUNT(*) 对比行数,不要只信“Query OK”

最容易被忽略的是时区和 lower_case_table_names 设置:若源库在 Linux(区分大小写)而目标在 Windows(不区分),mytableMyTable 会被视为同一张表,导致覆盖或丢失。

text=ZqhQzanResources