☰
MySQL 迁移 GaussDB 实战:DRS 在线迁移与手动离线迁移全攻略
2026/9/25 20:45:32 网站建设 项目流程

1. 背景

随着国产数据库的普及,越来越多的企业将业务从 MySQL 迁移到华为云 GaussDB。迁移过程中,如何保证数据一致性、缩短停机时间、处理语法兼容性,是每个 DBA 和开发人员必须面对的问题。

本文将介绍两种主流的迁移方案:

  • 方案一:使用华为云数据复制服务(DRS)进行在线迁移,支持全量 + 增量同步,停机时间最短,适合生产环境。
  • 方案二:手动离线迁移,采用「M 兼容模式建库 + mysqldump 导出结构/数据 + gsql 导入」方案,适合无 DRS 环境或小数据量场景。

2. 方案一:使用 DRS 在线迁移(推荐,生产环境首选)

2.1 适用场景

  • 华为云环境,源库与目标库网络互通。
  • 要求低停机时间,业务连续性要求高。
  • 希望自动处理部分语法转换,减少人工干预。

2.2 操作步骤

第一步:创建 GaussDB 实例

在华为云控制台创建 GaussDB 实例,确保与源 MySQL 网络互通(VPC / 安全组配置)。

第二步:创建 DRS 任务

  1. 登录 DRS 控制台,创建实时同步任务。
  2. 源库:选择 MySQL,填写 IP、端口、账号密码。
  3. 目标库:选择 GaussDB,填写实例 ID、账号密码。
  4. 迁移类型:选择「全量 + 增量」。

第三步:预检查与启动

执行预检查,修复报错项后启动任务。

第四步:业务割接

  1. 等待 DRS 状态变为「增量同步」。
  2. 停止源库写入业务。
  3. 确认 DRS 无延迟后,结束 DRS 任务。
  4. 修改应用连接地址指向 GaussDB。

3. 方案二:手动离线迁移(无 DRS 或小数据量)

3.1 关键前提

GaussDB 必须创建为M 兼容模式(DBCOMPATIBILITY='M'),以最大程度兼容 MySQL 语法(如自增主键、反引号等)。

3.2 目标库准备

在 GaussDB 中创建兼容 MySQL 的数据库:

-- 创建M兼容模式的数据库CREATEDATABASEtarget_db DBCOMPATIBILITY='M';

3.3 导出源库结构(Schema)

使用mysqldump仅导出表结构,去除触发器和 GTID 信息,避免兼容性问题。

# 导出结构到 schema.sqlmysqldump-h<MYSQL_IP>-u<USER>-p\--no-data\--skip-triggers\--set-gtid-purged=OFF\--skip-quote-names\source_db>schema.sql

命令参数逐行解析:

参数含义
-h <MYSQL_IP>指定源 MySQL 数据库的主机 IP 地址
-u <USER>指定连接数据库的用户名
-p提示输入密码(交互式输入,避免密码出现在命令行历史中)
--no-data只导出表结构(DDL),不导出表中的数据
--skip-triggers跳过触发器,避免 GaussDB 不兼容的触发器语法
--set-gtid-purged=OFF不生成 GTID 相关的SET @@GLOBAL.GTID_PURGED语句,避免导入时报错
--skip-quote-names不使用反引号(`)包裹表名和字段名,因为 GaussDB 不识别反引号
source_db要导出的源数据库名称
> schema.sql将导出结果重定向写入schema.sql文件

为什么这样配置?

  • --no-data:这一步只迁移表结构,数据在后续步骤单独处理,避免结构文件过大、导入超时。
  • --skip-triggers:GaussDB 对 MySQL 触发器语法支持有限,跳过可减少兼容性问题。
  • --set-gtid-purged=OFF:GTID 是 MySQL 主从复制的特性,GaussDB 不识别,必须关闭。
  • --skip-quote-names:MySQL 默认用反引号包裹标识符,而 GaussDB M 模式虽兼容反引号,但去掉后能减少不必要的转义问题。

注意:若遇到索引名冲突或特殊字符,可能需要手动编辑schema.sql。GaussDB M 模式下索引名在 Schema 内唯一,而非表内唯一。

3.4 导入结构到 GaussDB

使用gsql客户端导入结构文件。

# 导入结构gsql-h<GAUSSDB_IP>-p<PORT>-U<USER>-W<PASSWORD>-dtarget_db-fschema.sql

3.5 导出数据并导入

为避免大事务超时,建议按表导出数据和导入。

导出所有表数据:

exportMYSQL_PWD="<YOUR_PASSWORD>"# 循环导出每个表的数据为单独SQL文件forTABLEin$(mysql-u<USER>-h<MYSQL_IP>-N-e"SHOW TABLES FROM source_db");domysqldump-u<USER>-h<MYSQL_IP>\--no-create-info\--skip-triggers\--compact\--complete-insert\--set-gtid-purged=OFF\--skip-quote-names\source_db"$TABLE">"${TABLE}.sql"done

导入数据到 GaussDB:

# 循环导入每个表的数据forFILEin*.sql;doecho"Importing$FILE..."gsql-h<GAUSSDB_IP>-p<PORT>-U<USER>-W<PASSWORD>-dtarget_db-f"$FILE"done

3.6 手工迁移中容易踩坑的点

1. 字符集与排序规则不一致

MySQL 默认utf8mb4,而 GaussDB 默认UTF8。若源库表使用了utf8mb4_general_ci等排序规则,导入 GaussDB 后可能出现中文乱码或排序异常。

-- 导出前确认源库字符集SHOWCREATETABLEsource_table;-- 导入前在 GaussDB 中设置客户端编码SETclient_encoding='UTF8';

2. 外键约束导致导入顺序错误

MySQL 导出时默认按表名排序,若表之间存在外键依赖,直接按字母序导入会因父表未建而报错。

# 导出时禁用外键检查(在 schema.sql 开头添加)SET session_replication_role='replica';

3. 大字段(BLOB/TEXT)导入超时

gsql默认单条语句超时时间较短,导入包含大字段的表时容易中断。

# 导入时增加超时时间gsql-h<GAUSSDB_IP>-p<PORT>-U<USER>-W<PASSWORD>\-dtarget_db-f"$FILE"--statement-timeout=0

4. 空字符串与 NULL 的差异

MySQL 中''和NULL是不同值,但 GaussDB 某些场景下会将空字符串转换为NULL,导致数据不一致。

-- 导入后检查空字符串是否被转换SELECTCOUNT(*)FROMtarget_tableWHEREcolumn_name='';

5. 分区表语法不兼容

MySQL 的分区表语法(如PARTITION BY HASH)在 GaussDB 中写法不同,需手动改写为 GaussDB 的分区语法。

6. 视图与存储过程需单独处理

mysqldump导出的视图和存储过程在 GaussDB 中可能无法直接执行,需逐个检查并改写。

# 单独导出视图mysqldump-h<MYSQL_IP>-u<USER>-p\--no-data --skip-triggers --set-gtid-purged=OFF\source_db view_name>view_name.sql

7. 导入后索引失效

GaussDB 导入数据后,部分索引可能未自动重建,需手动执行ANALYZE更新统计信息。

-- 更新统计信息ANALYZEtarget_table;

4. 常见兼容性修正与注意事项

4.1 自增主键

M 模式下支持AUTO_INCREMENT,但插入数据时若指定 ID 值需注意序列同步。若手动插入数据后,需重置序列:

-- 示例:重置表 test_table 的 id 序列SELECTsetval('test_table_id_seq',(SELECTMAX(id)FROMtest_table));

4.2 数据类型差异

  • MySQLTINYINT(1)通常映射为 GaussDBBOOLEAN或SMALLINT,需检查业务逻辑。
  • MySQLDATETIME默认值'0000-00-00 00:00:00'在 GaussDB M 模式中不支持,需改为NULL或合法时间。
  • MySQLENUM/SET类型在 GaussDB 中支持有限,建议转换为VARCHAR或字典表。

4.3 保留字冲突

GaussDB 有更多保留字(如order、user),若表名或字段名为保留字,需用双引号包裹,如"user"。

4.4 JSON 类型

GaussDB M 模式对 JSON 支持有所限制,复杂 JSON 操作可能需调整为JSONB或文本处理。

4.5 大小写敏感

GaussDB 默认标识符小写,若 MySQL 表名大写,需在 SQL 中使用双引号或统一转换为小写。

5. 数据校验

迁移完成后,对比源库和目标库的记录数及关键字段哈希值。

-- 在GaussDB中执行SELECTCOUNT(*)FROMtarget_table;-- 在MySQL中执行SELECTCOUNT(*)FROMsource_table;

6. 总结

对比项DRS 在线迁移手动离线迁移
停机时间最短(增量同步)较长(需停写导出导入)
操作复杂度低(控制台可视化)高(需脚本处理)
语法转换自动处理部分转换需手动修正兼容性
适用场景生产环境、大数据量无 DRS 环境、小数据量

选择哪种方案,取决于您的业务场景和对停机时间的容忍度。生产环境强烈推荐使用 DRS 在线迁移;若条件受限,手动离线迁移配合 M 兼容模式也能顺利完成迁移任务。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询