1. 背景
随着国产数据库的普及,越来越多的企业将业务从 MySQL 迁移到华为云 GaussDB。迁移过程中,如何保证数据一致性、缩短停机时间、处理语法兼容性,是每个 DBA 和开发人员必须面对的问题。
本文将介绍两种主流的迁移方案:
- 方案一:使用华为云数据复制服务(DRS)进行在线迁移,支持全量 + 增量同步,停机时间最短,适合生产环境。
- 方案二:手动离线迁移,采用「M 兼容模式建库 + mysqldump 导出结构/数据 + gsql 导入」方案,适合无 DRS 环境或小数据量场景。
2. 方案一:使用 DRS 在线迁移(推荐,生产环境首选)
2.1 适用场景
- 华为云环境,源库与目标库网络互通。
- 要求低停机时间,业务连续性要求高。
- 希望自动处理部分语法转换,减少人工干预。
2.2 操作步骤
第一步:创建 GaussDB 实例
在华为云控制台创建 GaussDB 实例,确保与源 MySQL 网络互通(VPC / 安全组配置)。
第二步:创建 DRS 任务
- 登录 DRS 控制台,创建实时同步任务。
- 源库:选择 MySQL,填写 IP、端口、账号密码。
- 目标库:选择 GaussDB,填写实例 ID、账号密码。
- 迁移类型:选择「全量 + 增量」。
第三步:预检查与启动
执行预检查,修复报错项后启动任务。
第四步:业务割接
- 等待 DRS 状态变为「增量同步」。
- 停止源库写入业务。
- 确认 DRS 无延迟后,结束 DRS 任务。
- 修改应用连接地址指向 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.sql3.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"done3.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=04. 空字符串与 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.sql7. 导入后索引失效
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 数据类型差异
- MySQL
TINYINT(1)通常映射为 GaussDBBOOLEAN或SMALLINT,需检查业务逻辑。 - MySQL
DATETIME默认值'0000-00-00 00:00:00'在 GaussDB M 模式中不支持,需改为NULL或合法时间。 - MySQL
ENUM/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 兼容模式也能顺利完成迁移任务。