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

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

MySQL2PG 工具产生的背景

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

  1. 无法全自动转换 MySQL 的 DDL 到 PostgreSQL 上,转换的过程中还存在着较多的语法不兼容问题,还需要手动处理,耗时耗力。
  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 直接编译为机器码具有运行效率快、跨平台、内存占用率少、启动快、可以二进制部署等特点。

工具整体功能效果

使用的软件版本

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

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 模块中把users和table_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. MySQL 的 FUNCTION 的自动转换成 PostgreSQL 函数。
  2. 根据日志的级别在日志中添加转后的 PostgreSQL DDL 的语句。
  3. 数据同步效率进一步优化,提升数据同步的效率。
  4. MySQL 不同版本到 PostgreSQL 不同版本的转换需要测试。
  5. 在进行转换表权限时,需要提示用户权限的详细信息。
  6. 添加日志的级别,来显示不同的日志信息,如 INFO、DEBUG、ERROR 等,避免再次生成 conversion.log 日志和 errors.log 的日志。
相关推荐
hz567896 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
广州浮点FLOATLIC6 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
程序员Sunday6 小时前
MySQL 为什么使用 B+ 树索引?把范围查询、回表和覆盖索引连起来
数据库·mysql
半杯咖啡半行码7 小时前
Qt开发实战:数据库、MV 模式、QProcess与串口通信全攻略
数据库·qt
Yyyyyy~7 小时前
[ Mysql ] 库的操作
mysql
小米里的大麦7 小时前
16 MySQL 事务
数据库·mysql
西柚小萌新7 小时前
【LLM&&AI应用开发 八股文】--4.3.Agent智能体(下)
java·开发语言·数据库
Titan20247 小时前
MySQL访问个人学习笔记
笔记·学习·mysql
邓工说电8 小时前
智慧断路器安全吗?数据加密、离线保护与合规认证全解读
大数据·数据库·人工智能·智能断路器·炜晔科技
for_ever_love__8 小时前
MySQL 全文索引实战:FULLTEXT、ngram 中文分词与 MATCH AGAINST 到底该怎么用
java·python·mysql·全文检索·分词·索引·ngram