高性能MySQL到PostgreSQL异构数据库转换工具MySQL2PG

高性能MySQL到PostgreSQL异构数据库转换工具MySQL2PG

MySQL2PG 工具产生的背景

MySQLPostgreSQL 转换同步工具存在着以下诸多的问题:

  1. 无法全自动转换 MySQLDDLPostgreSQL 上,转换的过程中还存在着较多的语法不兼容问题,还需要手动处理,耗时耗力。
  2. 工具无法进行自动化全量表进行同步,需要手动一个表或者一批表进行选择配置、字段映射,在同步数据时进度无法进行可视化展示、很难评估需要同步的整体时间。
  3. 无法进行 MySQL 数据库用户信息的自动同步、需要手动的确认哪些用户需要同步、用户的密码分别是多少、如果密码忘记对于手动进行确认,期间会消耗大量的时间和精力。
  4. 无法进行用户权限的自动化同步,无法精细化的控制用户的权限,存在较大的操作风险。
  5. 特别是 MySQL 上的 FUNCTION 无法进行自动进行转移,几百个 FUNCTION 手动的转换会消耗不少的人力。。

针对以上的问题,首先进行了系统化的梳理了,工具需要哪些模块,以及每个模块都包含哪些功能进行了手稿第一版梳理。

最终实现的各模块及功能如下:

sql 复制代码
开始
 │
 ├─▶ [Step 0] test_only 模式?
 │     ├─ 是 → 测试 MySQL & PostgreSQL 连接 → 显示版本 → 退出
 │     └─ 否 → 继续
 │
 ├─▶ [Step 1] 转换表结构 (tableddl: true)
 │     ├─ 读取 MySQL 表定义
 │     ├─ 字段类型智能映射(如 tinyint(1) → BOOLEAN)
 │     ├─ lowercase_columns 控制字段名大小写
 │     └─ 在 PostgreSQL 中创建表(skip_existing_tables 控制是否跳过)
 │
 ├─▶ [Step 2] 同步数据 (data: true)
 │     ├─ 若 use_table_list=true → 仅同步 table_list 中的表
 │     ├─ 若 truncate_before_sync=true → 清空目标表
 │     ├─ 分批读取 MySQL 数据(max_rows_per_batch)
 │     ├─ 批量插入 PostgreSQL(batch_insert_size)
 │     └─ 并发线程数由 concurrency 控制
 │
 ├─▶ [Step 3] 转换索引 (indexes: true)
 │     ├─ 主键、唯一索引、普通索引 → 自动重建
 │     └─ 批量处理(max_indexes_per_batch=20)
 │
 ├─▶ [Step 4] 转换函数 (functions: true) ←【V1.0 未完全实现】
 │     └─ 支持函数映射(如 NOW() → CURRENT_TIMESTAMP)
 │
 ├─▶ [Step 5] 转换用户 (users: true)
 │     └─ MySQL 用户 → PostgreSQL 角色(带密码)
 │
 ├─▶ [Step 6] 转换表权限 (table_privileges: true)
 │     └─ GRANT SELECT ON table → GRANT USAGE, SELECT
 │
 └─▶ [Final Step] 数据校验 (validate_data: true)
       ├─ 查询 MySQL 和 PostgreSQL 表行数
       ├─ 若 truncate_before_sync=true 且不一致 → 报错中断
       └─ 若 truncate_before_sync=false → 记录不一致表,继续执行
             └─ 最终输出「数据量校验不一致的表统计」表格

源代码仓库在 https://github.com/xfg0218/MySQL2PG 欢迎大家使用和反馈意见,有好的想法及建议也欢迎随时交流。 👏🏻 👏🏻 👏🏻👏🏻

编程工具选择

主要调研了国内主流的AI IDE的工具,包括节旗下的Trae、腾讯云旗下的CodeBuddy和阿里云旗下的通义灵码,优劣势如下:

功能维度 Trae CodeBuddy 通义灵码
AI 核心模式 支持Builder 和Builder MCP的模式 Craft 智能体、双模型驱动 支持智能代码补全、智能校验代码质量、测试CASE生成
代码生成能力 支持从0-1项目的生成 支持不同的语言 支持代码的优化、代码提示、代码续写
多模态支持 支持go/java/Python/C++ 支持流程的编排、智能体的协作 编程智能体、工程级变更
生态集成 支持 VS Code 插件 支持微信的生态、疼腾讯云的服务等 阿里云的生态、可以对接钉钉

由于这个项目需要从0开始并且需要使用golang 语言开发,在开发时仅需要输入需要实现的功能,工具需要理解上下文的内容,和自动代码的编排、以及测试步骤需要由AI 进行完成的需求,最终选择了 Trae 作为了开发的工具。

参考资料:

trae:https://www.trae.cn/

codebuddy:https://www.codebuddy.ai/

通义灵码:https://lingma.aliyun.com/


为什么会选择golang 语言,主要是Golang 直接编译为机器码具有运行效率快、跨平台、内存占用率少、启动快、可以二进制部署等特点。

工具整体功能效果

使用的软件版本

采用 MySQLPostgreSQL 都为单机版进行的测试,版本信息如下:

sql 复制代码
-- go 的版本
$ go version
go version go1.24.2 darwin/amd64

-- mysql的版本
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.44    |
+-----------+
1 row in set (0.00 sec)

-- PG的版本
postgres=# select version();
                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 16.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
(1 row)

使用的数据集

  1. MySQL 的数据库中有不同字段类型、不同储存引擎、不同字符编码、涉及到关键字、主外键、自增列等共 1339 张表进行的自动转换。
  2. MySQL 数据库中的 1339 张上共有 1768 个索引,其中包含主键索引、单字段索引、符合索引等。
  3. MySQL 数据库中存在5个不同的用户,在五个用户中有的用户仅有 SELECT 权限、有的用户仅有DELETE 权限、有的用户仅有 UPDATE 权限,有的用户具有几十张全部的操作权限。
  4. 以下为实际测试转换的对象数量信息汇总:
sql 复制代码
+--------------------------+----------------+
| 阶段                     | 对象数量         |
+--------------------------+----------------+
| 转换表结构                | 1339            |
| 同步表数据                | 1339            |
| 转换表索引                | 1768            |
| 转换库用户                | 5               |
| 转换表权限                | 15              |
+--------------------------+----------------+

仅测试连接部分

config.yml 配置文件中有测试连接数据库的功能参数 test_only 当该参数开启时,表示仅测试数据库的链接,其他的步骤不执行,在测试连接完成后输出日志信息便会退出。

mysql.test_only = true 时代表仅测试连接 MySQL 数据库的部分,日志信息如下 :

sql 复制代码
+-------------------------------------------------------------+
1. MySQL连接测试完成,版本信息已显示,退出程序。
+-------------------------------------------------------------+
| 数据库版本信息:                                             |
+--------------+----------------------------------------------+
| 数据库类型   | 版本信息                                     |
+--------------+----------------------------------------------+
| MySQL       | 5.7.44                                       |
| PostgreSQL  | PostgreSQL 16.1 on x86_64-pc-linux-gn...     |
+--------------+----------------------------------------------+

postgresql.test_only = true 时代表仅测试连接 PostgreSQL 的部分,日志信息如下 :

sql 复制代码
+-------------------------------------------------------------+
2. PostgreSQL 连接测试完成,版本信息已显示,退出程序。
+-------------------------------------------------------------+
| 数据库版本信息:                                             |
+--------------+----------------------------------------------+
| 数据库类型   | 版本信息                                     |
+--------------+----------------------------------------------+
| MySQL       | 5.7.44                                       |
| PostgreSQL  | PostgreSQL 16.1 on x86_64-pc-linux-gn...     |
+--------------+----------------------------------------------+

全流程运行结果

当在 config.yml 配置文件 conversion 模块中分别开启了tableddl/data/indexes/users/table_privileges/validate_data 会按照顺序依次执行,详细的日志输出如下,在转换完成后会总结每个阶段转换的对象及耗时。

sql 复制代码
1. 开始转换表结构...
进度: 3.45% (1/29) : 表 acl_space 已存在,跳过创建
进度: 6.90% (2/29) : 表 users_20251201 已存在,跳过创建
进度: 10.34% (3/29) : 表 act_id_group 已存在,跳过创建
进度: 13.79% (4/29) : 表 user 已存在,跳过创建

2. 同步表数据...

进度: 17.24% (5/29) : 同步表 acl_space 数据成功,共有 0 行数据,数据校验一致
进度: 17.24% (6/29) : 同步表 users_20251201 [--------------------] 100.00%
进度: 20.69% (6/29) : 同步表 users_20251201 数据成功,共有 1 行数据,数据校验一致
进度: 24.14% (7/29) : 同步表 act_id_group 数据成功,共有 0 行数据,数据校验一致
进度: 27.59% (8/29) : 同步表 user 数据成功,共有 0 行数据,数据校验一致

3. 转换表索引...
进度: 31.03% (9/29) : 转换索引 idx_user_id 成功

5. 开始转换用户...
进度: 34.48% (10/29) : 转换用户 mysql2pg@% 的权限成功
进度: 37.93% (11/29) : 转换用户 user1@% 的权限成功
进度: 41.38% (12/29) : 转换用户 user2@% 的权限成功
进度: 44.83% (13/29) : 转换用户 user1@localhost 的权限成功
进度: 48.28% (14/29) : 转换用户 user2@localhost 的权限成功

6. 转换表权限...
进度: 51.72% (15/29) : 转换表权限成功
进度: 58.62% (17/29) : 转换表权限成功
进度: 68.97% (20/29) : 转换表权限成功
进度: 72.41% (21/29) : 转换表权限成功
进度: 82.76% (24/29) : 转换表权限成功
进度: 93.10% (27/29) : 转换表权限成功
进度: 95.30% (28/29) : 转换表权限成功
进度: 100.00% (29/29) : 转换表权限成功

----------------------------------------------------------------------
各阶段及耗时汇总如下:
+--------------------------+----------------+-----------------------+
| 阶段                     | 对象数量       | 耗时(秒)              |
+--------------------------+----------------+-----------------------+
| 转换表结构                | 4              | 0.84                  |
| 同步表数据                | 4              | 1.69                  |
| 转换表索引                | 1              | 0.05                  |
| 转换库用户                | 5              | 0.24                  |
| 转换表权限                | 15             | 1.41                  |
+--------------------------+----------------+-----------------------+
| 总耗时                    |                | 4.23                  |
+--------------------------+----------------+-----------------------+

按照指定表进行同步

当在 config.yml 配置文件 conversion 模块中把use_table_list设置成true 工具便会按照 table_list 内的表名进行转换,方便同步仅关注的表,转换完成后也会汇总该阶段的耗时。

sql 复制代码
2. 同步表数据...

进度: 50.00% (1/2) : 同步表 user 数据成功,共有 0 行数据,数据校验一致
进度: 50.00% (2/2) : 同步表 users_20251201 [--------------------] 100.00%
进度: 100.00% (2/2) : 同步表 users_20251201 数据成功,共有 1 行数据,数据校验一致

----------------------------------------------------------------------
各阶段及耗时汇总如下:
+--------------------------+----------------+-----------------------+
| 阶段                     | 对象数量       | 耗时(秒)              |
+--------------------------+----------------+-----------------------+
| 同步表数据                | 2              | 0.91                  |
+--------------------------+----------------+-----------------------+
| 总耗时                    |                | 0.91                  |
+--------------------------+----------------+-----------------------+

在表数据同步的过程中有百分比的进度可视化,方便了解数据的同步进度。

数据同步不一致时的提示

当在 config.yml 配置文件 conversion 模块中把truncate_before_sync设置成false时存在可能会存在数据重复以及数据不一致的情况,同步时在 控制台的日志中 会显示 数据校验不一致 的提示,同时在转换完成后也会有 数据量校验不一致的表统计 的信息,方便进行排查。

sql 复制代码
2. 同步表数据...

进度: 50.00% (1/2) : 同步表 user 数据成功,共有 0 行数据,数据校验一致
进度: 50.00% (2/2) : 同步表 users_20251201 [--------------------] 100.00%
进度: 100.00% (2/2) : 同步表 users_20251201 数据成功,共有 1 行数据,数据校验不一致

+------------------+----------------+------------------+
数据量校验不一致的表统计:
+------------------+----------------+------------------+
| 表名             | MySQL数据量    | PostgreSQL数据量 |
+------------------+----------------+------------------+
| users_20251201   | 1              | 2                |
+------------------+----------------+------------------+

----------------------------------------------------------------------
各阶段及耗时汇总如下:
+--------------------------+----------------+-----------------------+
| 阶段                     | 对象数量       | 耗时(秒)              |
+--------------------------+----------------+-----------------------+
| 同步表数据                | 2              | 0.66                  |
+--------------------------+----------------+-----------------------+
| 总耗时                    |                | 0.66                  |
+--------------------------+----------------+-----------------------+

仅转换用户及表权限时的提示

当在 config.yml 配置文件 conversion 模块中把userstable_privileges参数开启时,工具会自动转换用户以及表上的权限信息,整个过程无需手动的干预,同时也会汇总转换的对象及耗时。

sql 复制代码
5. 开始转换用户...
进度: 5.00% (1/20) : 转换用户 mysql2pg@% 的权限成功
进度: 10.00% (2/20) : 转换用户 user1@% 的权限成功
进度: 15.00% (3/20) : 转换用户 user2@% 的权限成功
进度: 20.00% (4/20) : 转换用户 user1@localhost 的权限成功
进度: 25.00% (5/20) : 转换用户 user2@localhost 的权限成功

6. 转换表权限...
进度: 30.00% (6/20) : 转换表权限成功
进度: 40.00% (8/20) : 转换表权限成功
进度: 55.00% (11/20) : 转换表权限成功
进度: 60.00% (12/20) : 转换表权限成功
进度: 75.00% (15/20) : 转换表权限成功
进度: 90.00% (18/20) : 转换表权限成功

----------------------------------------------------------------------
各阶段及耗时汇总如下:
+--------------------------+----------------+-----------------------+
| 阶段                     | 对象数量       | 耗时(秒)              |
+--------------------------+----------------+-----------------------+
| 转换库用户                | 5              | 0.24                  |
| 转换表权限                | 15             | 1.35                  |
+--------------------------+----------------+-----------------------+
| 总耗时                    |                | 1.59                  |
+--------------------------+----------------+-----------------------+

错误日志分析及执行日志查看

错误日志

MySQL2PG 工具运行时会默认在当前的路径下生成 errors.log 的日志,该日志主要会保存程序运行过程中相关错误的信息,根据该日志可以分析具体的错误原因。

sql 复制代码
[2025-12-29 13:09:54] ERROR: 插入表 users_20251201 数据失败: 批量插入失败: ERROR: duplicate key value violates unique constraint "users_20251201_pkey" (SQLSTATE 23505), 数据样本: [[49] [50] [51]]

执行日志查看

MySQL2PG 工具运行时会默认在当前的路径下生成 conversion.log 的日志,该日志会详细的记录转换详细的过程,如果发现某一个过程有异常可以根据该日志进行排查。

sql 复制代码
*****
[2025-12-29 14:14:17] 进度: 89.66% (26/29)
[2025-12-29 14:14:17] 表 users 在PostgreSQL中不存在,跳过权限授予
[2025-12-29 14:14:17] 进度: 93.10% (27/29)
[2025-12-29 14:14:17] 表 products 在PostgreSQL中不存在,跳过权限授予
[2025-12-29 14:14:17] 进度: 96.55% (28/29)
[2025-12-29 14:14:17] 表 orders 在PostgreSQL中不存在,跳过权限授予
[2025-12-29 14:14:17] 进度: 100.00% (29/29)

MySQL2PG 工具后续计划

  1. MySQLFUNCTION 的自动转换成 PostgreSQL 函数。
  2. 根据日志的级别在日志中添加转后的 PostgreSQL DDL 的语句。
  3. 数据同步效率进一步优化,提升数据同步的效率。
  4. MySQL 不同版本到 PostgreSQL 不同版本的转换需要测试。
  5. 在进行转换表权限时,需要提示用户权限的详细信息。
  6. 添加日志的级别,来显示不同的日志信息,如 INFODEBUGERROR 等,避免再次生成 conversion.log 日志和 errors.log 的日志。
相关推荐
小Mie不吃饭2 小时前
Spring boot + mybatis-plus + Redis 实现数据多级缓存(模拟生产环境)
java·spring boot·redis·mysql·缓存
摇滚侠2 小时前
RocketMQ 教程丨深度掌握 MQ 消息中间件,RocketMQ 集群,笔记 28-38
数据库·笔记·rocketmq
Gobysec2 小时前
Goby 漏洞安全通告|MongoDB Zlib 信息泄露漏洞(CVE-2025-14847)
数据库·安全·mongodb·漏洞检测工具
醉风塘2 小时前
深入解析与彻底解决:MongoDB“about to fork child process”启动故障
数据库·mongodb
大猫会长2 小时前
新手的postgreSQL笔记
数据库·笔记·postgresql
大鱼>2 小时前
按时间删除MongoDB中按时间命名的Collection
数据库·mongodb
咕噜企业分发小米2 小时前
阿里云服务器如何实现与其他阿里云产品的无缝集成?
服务器·数据库·阿里云
步步为营DotNet2 小时前
深入探究DbContext的ChangeTracker:精准把握Entity状态管理与性能优化
数据库·oracle·性能优化
Gauss松鼠会2 小时前
【openGauss】如何在openGauss/PostgreSQL手动清理XLOG/WAL 文件?
数据库·sql·postgresql·database·opengauss