一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

MySQL从自建服务器迁移到云数据库如何操作?

时间:2026-08-28 09:16:49 编辑:袖梨 来源:一聚教程网

mysqldump适合小库(<10GB)且可接受数小时停机的场景,但需规避陷阱:InnoDB才支持--single-transaction,MyISAM会全局锁表;必须显式加--routines --triggers --events导出存储对象;注意lower_case_table_names和GTID兼容性;云环境需禁用CREATE DATABASE并校验字符集、时区、外键等一致性。

mysqldump 适合小库,但别直接在生产库上跑

如果你的自建 MySQL 数据库不到 10GB,且能接受数小时停机,mysqldump 是最快上手的方式。但它不是“一键迁移”,而是要绕开几个典型陷阱:

  1. mysqldump --single-transaction 只对 InnoDB 有效;如果库中有 MyISAM 表,会隐式加全局锁(FLUSH TABLES WITH READ LOCK),导致写入阻塞
  2. 默认不导出存储过程、触发器和事件,必须显式加 --routines --triggers --events
  3. 如果源库启用了 lower_case_table_names=0(Linux 默认),而云数据库强制 =1(如阿里云 RDS MySQL 8.0),表名大小写会被强制转换,后续 SELECTJOIN 可能报错
  4. 导出文件里带 CREATE DATABASE 语句,但云数据库通常不允许用户执行该语句;需手动删掉或改用 --no-create-db

示例命令(推荐):

mysqldump -h 127.0.0.1 -u root -p --single-transaction --routines --triggers --events --set-gtid-purged=OFF --databases myapp > myapp.sql

注意:--set-gtid-purged=OFF 是为了规避 GTID 冲突,尤其当目标云数据库已启用 GTID 时。

DTS 工具迁移时,权限和参数检查比操作本身更关键

云厂商提供的 DTS(如阿里云 DTS、腾讯云 NewDTS)本质是封装了 binlog 解析 + 增量同步的管道,但失败往往卡在前置条件。

  1. 源库账号至少要有:REPLICATION CLIENTREPLICATION SLAVESHOW VIEWSELECT;如果做全量校验,还需 LOCK TABLES(意味着短时锁表)
  2. 目标云数据库的 lower_case_table_names 必须与源库一致,否则 DTS 校验阶段直接报错退出,不会继续
  3. 若源库 MySQL 版本是 5.6,目标选了 8.0,DTS 会拒绝创建任务——它不自动处理语法兼容性(比如 GROUP BY 严格模式变更)
  4. 云数据库实例的磁盘空间必须 ≥ 源库实际占用空间 × 1.3(预留日志、临时排序、校验缓存)

特别提醒:DTS 迁移任务启动后,源库 binlog format 必须为 MIXEDROWSTATEMENT 模式下某些函数(如 NOW()UUID())会导致主从数据不一致,DTS 同步也会出错。

迁移后数据一致性验证不能只看行数

行数一致 ≠ 数据一致。常见脱节点:

  1. 时间字段精度丢失:源库是 DATETIME(6),目标云数据库默认只支持 DATETIME(0),没显式指定 --skip-tz-utc 或调整时区配置,会导致时间偏移
  2. 字符集隐式转换:utf8mb4_unicode_ciutf8mb4_0900_as_cs 在排序行为上不同,ORDER BY 结果可能变,但 COUNT(*) 不体现
  3. 外键约束未启用:云数据库默认关闭 FOREIGN_KEY_CHECKS,导入后若没手动开,INSERT 不校验外键,脏数据悄然入库

建议验证方式:

  1. 抽样对比:对高频更新表(如订单表),取最新 100 条按主键查,逐字段比对
  2. 使用 pt-table-checksum(Percona Toolkit)跑一次校验,它能穿透复制延迟,定位到具体库/表/行
  3. 检查 information_schema.TABLESDATA_LENGTH + INDEX_LENGTH 是否与源库偏差 < 5%

应用切换前必须改三处配置,漏一不可

不是改完数据库连接地址就完事。

  1. 应用配置里的 max_connections 要重设:云数据库连接数限制通常比自建低(如 RDS 通用型实例默认 2000),而旧应用可能设了 5000,启动即连不上
  2. JDBC URL 加 ?useSSL=false&serverTimezone=Asia/Shanghai:云数据库默认强制 SSL,不加 useSSL=false 会握手失败;时区不显式声明,Java Timestamp 可能差 8 小时
  3. 连接池(如 HikariCP)的 connection-test-query 得换成 SELECT 1:部分云数据库不支持 SELECT 1; 以外的测试语句,旧配置用 SELECT NOW() 会导致连接池反复重建

最易被忽略的是 DNS 缓存:Kubernetes 或本地 hosts 绑定的旧 IP,在切流后仍可能被复用。务必确认应用重启后,nslookup your-rds-endpoint 返回的是云厂商分配的真实域名,而非缓存的旧地址。

热门栏目