# MySQL2PG
**Repository Path**: bill_hu1971/MySQL2PG
## Basic Information
- **Project Name**: MySQL2PG
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2026-04-29
- **Last Updated**: 2026-07-09
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
[![License][license-badge]][license-url] [![Stars][stars-badge]][stars-url] [![Last Commit][last-commit-badge]][commits-url] [![Language][go-badge]][repo-url] [![Go Version][go-version-badge]][go-url]
[license-badge]: https://img.shields.io/badge/license-Apache--2.0-blue.svg?style=for-the-badge
[license-url]: https://github.com/xfg0218/MySQL2PG/blob/main/LICENSE
[stars-badge]: https://img.shields.io/github/stars/xfg0218/MySQL2PG?style=for-the-badge&label=Stars
[stars-url]: https://github.com/xfg0218/MySQL2PG/stargazers
[last-commit-badge]: https://img.shields.io/github/last-commit/xfg0218/MySQL2PG?style=for-the-badge&label=Last%20Commit
[commits-url]: https://github.com/xfg0218/MySQL2PG/commits/main
[go-badge]: https://img.shields.io/github/languages/top/xfg0218/MySQL2PG?style=for-the-badge&logo=go&logoColor=white
[repo-url]: https://github.com/xfg0218/MySQL2PG
[go-version-badge]: https://img.shields.io/badge/Go-1.24%2B-blue?style=for-the-badge&logo=go
[go-url]: https://go.dev/dl/
Language: [English](README.md) | [中文](README_CN.md)
# MySQL2PG - 高性能MySQL到PostgreSQL转换工具
MySQL2PG是一款用Go语言开发的专业级数据库转换工具,专注于将MySQL数据库无缝迁移到PostgreSQL。它提供了全面的转换功能,包括表结构、数据、视图、索引、函数、用户及用户表上的权限等,同时具备高性能、高可靠性和丰富的配置选项。
## 转换流程逻辑
```
开始
│
├─▶ [Step 0] test_only 模式?
│ ├─ 是 → 测试 MySQL & PostgreSQL 连接 → 显示版本 → 退出
│ └─ 否 → 继续
│
├─▶ [Step 1] 读取 MySQL 表定义
│ ├─ 若 exclude_use_table_list=true → 从数据库层面过滤 exclude_table_list 中的表
│ └─ 若 use_table_list=true → 仅获取 table_list 中的表
│
├─▶ [Step 2] 转换表结构 (tableddl: true)
│ ├─ 字段类型智能映射(如 tinyint(1) → BOOLEAN)
│ ├─ lowercase_columns 控制字段名大小写
│ ├─ 提取主键列作为 MPP 分布键
│ ├─ 若启用 MPP(conversion.mpp.enabled=true):
│ │ └─ 添加 DISTRIBUTED BY (pk_col1, pk_col2, ...) 子句
│ └─ 在 PostgreSQL 中创建表(skip_existing_tables 控制是否跳过)
│
├─▶ [Step 3] 转换视图 (view: true)
│ ├─ 若 exclude_use_view_list=true → 跳过 exclude_view_list 中的视图
│ └─ MySQL 视图定义转换为 PostgreSQL 兼容语法
│
├─▶ [Step 4] 同步数据 (data: true)
│ ├─ 若 truncate_before_sync=true → 清空目标表
│ ├─ 分批读取 MySQL 数据(max_rows_per_batch)
│ ├─ 批量插入 PostgreSQL(batch_insert_size)
│ ├─ 并发线程数由 concurrency 控制
│ └─ 自动禁用外键约束和索引提高性能
│
├─▶ [Step 5] 转换索引 (indexes: true)
│ ├─ 若 MPP 启用(Greenplum):
│ │ ├─ 跳过 UNIQUE INDEX 创建(分布键已确保唯一性)
│ │ └─ 对有主键的表应用 ALTER TABLE ... SET DISTRIBUTED BY
│ ├─ 主键、唯一索引、普通索引、全文索引 → 自动重建
│ └─ 批量处理(max_indexes_per_batch=20)
│
├─▶ [Step 6] 转换函数 (functions: true)
│ ├─ 若 exclude_use_function_list=true → 跳过 exclude_function_list 中的函数
│ └─ 支持50+函数映射(如 NOW() → CURRENT_TIMESTAMP,IFNULL() → COALESCE())
│
├─▶ [Step 7] 转换用户 (users: true)
│ └─ MySQL 用户 → PostgreSQL 角色(保留密码哈希)
│
├─▶ [Step 8] 转换表权限 (table_privileges: true)
│ └─ GRANT SELECT ON table → GRANT USAGE, SELECT ON table
│
└─▶ [Final Step] 数据校验与完成 (validate_data: true)
├─ 查询 MySQL 和 PostgreSQL 表行数
├─ 重新启用之前禁用的外键约束和索引
├─ 若 truncate_before_sync=false → 记录不一致表,继续执行
├─ 输出转换统计报告和性能指标
└─ 生成不一致表清单(如有)
```
## 项目独特特点
### 📋 广泛的版本支持
- **MySQL 支持**:全面兼容 MySQL 5.7+ 和 MySQL 9.0+ 版本
- **PostgreSQL 支持**:全面兼容 PostgreSQL 12+ 到 PostgreSQL 18+ 版本
- **视图转换支持**:42 个视图 100% 可转换,支持所有 MySQL 5.7+ 视图语法
- **函数转换支持**:113 个函数核心语法 100% 可转换,支持复杂的存储过程语法
- **MySQL 支持**:全面兼容 MySQL 5.7+ 和 MySQL 8.0+ 版本
- **PostgreSQL 支持**:全面兼容 PostgreSQL 12+ 到 PostgreSQL 18+ 版本
- **视图转换支持**:42 个视图 100% 可转换,支持所有 MySQL 5.7+ 视图语法
- **函数转换支持**:113 个函数核心语法 100% 可转换,支持复杂的存储过程语法
### 🚀 高性能设计
- **并发转换引擎**:支持根据硬件配置配置并发线程数,转换速度比单线程提升5-10倍
- **批量处理优化**:支持批量插入,每批可达10,000行,显著提升数据迁移速度
- **连接池管理**:支持自定义MySQL和PostgreSQL连接池设置,最大连接数可达100+
- **实时进度监控**:实时展示转换进度,进度更新频率1次/秒,让用户实时了解转换状态
### 🎯 精准转换能力
- **字段类型智能映射**:支持几乎所有的MySQL字段类型到PostgreSQL的精确转换,映射准确率达到90.9%
- **函数兼容性转换**:支持常用的MySQL函数到PostgreSQL等效函数的转换,转换准确率90%以上
- **完整权限体系迁移**:支持MySQL到PostgreSQL用户权限和表权限的完整映射,权限转换准确率98%
- **视图转换功能**:支持MySQL视图定义到PostgreSQL的完整转换,包括语法调整和函数替换
- **索引结构保持**:支持主键、唯一索引、普通索引等多种索引类型的转换,索引转换成功率98%
### ✅ 数据完整性保障
- **百万级数据支持**:支持百万级数据量转换,数据完整性保持率100%
- **多维度数据校验**:同步后自动验证数据一致性,校验准确率100%,支持批量校验和增量数据校验
- **数据不一致检测**:自动统计数据量不匹配的表,提供详细的不一致表清单
- **灵活同步策略**:支持全量同步和保留已有数据同步,可配置同步前是否清空表数据
### 🛠️ 丰富的配置选项
- **细粒度转换控制**:可单独控制表结构、数据、索引、函数、用户权限等转换选项
- **表级别的同步选择**:支持指定特定表进行数据同步,提高灵活性
- **字段名大小写控制**:可配置是否将表字段转换为小写,适应不同的命名规范
- **网络带宽限制**:可限制网络带宽使用,避免影响生产环境
### 🔧 便捷的开发体验
- **test_only模式**:仅测试连接,不执行转换,连接测试响应时间<1秒
- **详细的日志系统**:支持文件日志和控制台日志,记录转换过程的每一步
- **清晰的示例输出**:提供多种场景的示例输出,帮助用户理解工具的工作方式
- **完善的错误处理**:遇到错误时提供详细的错误信息,便于排查问题
## 重要功能说明
### test_only模式
- **功能说明**:仅测试数据库连接,不执行任何转换操作,连接测试响应时间<1秒
- **参数配置**:
- `mysql.test_only: true` - 仅测试MySQL连接,不执行转换
- `postgresql.test_only: true` - 仅测试PostgreSQL连接,不执行转换
- 当两者都设置为 `true` 时,工具会测试两个数据库的连接,不执行转换
- **使用场景**:快速验证数据库连接配置是否正确,无需执行完整的转换流程
### 数据校验
- **功能说明**:在同步数据后验证MySQL和PostgreSQL的数据一致性,确保数据迁移的完整性
- **参数配置**:`validate_data: true` - 启用数据校验功能
- **验证方式**:比较两张表的行数是否一致
- **处理逻辑**:如果数据校验失败,工具会根据 `truncate_before_sync` 设置决定是否中断执行
- **使用场景**:确保数据迁移的完整性,特别是在生产环境中进行重要数据迁移时
### truncate_before_sync 选项
- **功能说明**:控制在同步数据前是否清空PostgreSQL中的表数据,提供灵活的同步策略
- **参数配置**:
- `truncate_before_sync: true` - 同步前清空表数据
- `truncate_before_sync: false` - 同步前不清空表数据
- **处理逻辑**:
- 当 `truncate_before_sync: true` 时:
- 同步前清空PostgreSQL表数据
- 如果数据校验失败(行数不一致),工具会中断执行并返回错误
- 当 `truncate_before_sync: false` 时:
- 同步前不清空表数据,新数据会追加到表中
- 如果数据校验失败(行数不一致),工具会继续执行,但会在日志中显示"数据校验不一致"
- 最终会在转换完成后显示数据不一致表的统计信息
### MySQL连接参数配置
- **功能说明**:允许用户自定义MySQL连接参数,以满足特定的连接需求
- **参数配置**:`connection_params: charset=utf8mb4&parseTime=false&interpolateParams=true`
- **支持的参数**:
- `charset=utf8mb4` - 使用UTF8MB4字符集,支持表情符号
- `parseTime=false` - 禁用时间类型自动解析
- `interpolateParams=true` - 启用参数插值,提高安全性
- **注意事项**:
- 参数格式为key=value&key=value形式
- 不需要添加前导问号
- 不支持compress参数(MySQL驱动未实现)
### PostgreSQL连接参数配置
- **功能说明**:允许用户自定义PostgreSQL连接参数,以满足特定的连接需求
- **参数配置**:`pg_connection_params: search_path=public connect_timeout=10`
- **支持的参数**:
- `connect_timeout=10` - 连接超时时间(秒)
- `search_path=public` - 默认使用的schema
- **注意事项**:
- 参数格式为key=value&key=value形式
- 不需要添加前导问号
- 支持PostgreSQL驱动的所有连接参数
### 表过滤功能
- **功能说明**:提供两种表过滤方式,灵活控制需要同步的表,属于转换选项配置
- **白名单模式**(use_table_list):
- `conversion.options.use_table_list: true` - 仅同步table_list中的表
- `conversion.options.table_list: [table1, table2]` - 指定要同步的表列表
- **黑名单模式**(exclude_use_table_list):
- `conversion.options.exclude_use_table_list: true` - 启用黑名单模式,跳过exclude_table_list中的表
- `conversion.options.exclude_table_list: [table3, table4]` - 指定要跳过的表列表
- **注意事项**:
- 白名单和黑名单模式不能同时使用
- 当同时设置了白名单和黑名单时,白名单模式优先级更高
- 表名区分大小写,请确保与数据库中的实际表名一致
### 视图和函数排除功能
- **功能说明**:提供视图和函数的排除列表,灵活控制同步的视图和函数,属于转换选项配置
- **视图排除**:
- `conversion.options.exclude_use_view_list: true` - 启用视图排除模式,跳过 exclude_view_list 中的视图
- `conversion.options.exclude_view_list: [view1, view2]` - 指定要跳过的视图列表
- **函数排除**:
- `conversion.options.exclude_use_function_list: true` - 启用函数排除模式,跳过 exclude_function_list 中的函数
- `conversion.options.exclude_function_list: [func1, func2]` - 指定要跳过的函数列表
- **注意事项**:
- 视图名和函数名不区分大小写,会自动转换为小写进行匹配
- 配置使用字符串数组语法,例如 `[view1, view2]`
- 跳过的对象会在日志中记录,并更新进度统计
### MPP 分布式数据库支持
- **功能说明**:为 MPP(大规模并行处理)分布式数据库(如 Greenplum、YugabyteDB)提供支持
- **参数配置**:
- `conversion.mpp.enabled: true` - 启用 MPP 模式(创建 UNIQUE INDEX 和 DISTRIBUTED BY 子句)
- `conversion.mpp.database: auto` - MPP 数据库类型:`greenplum`、`yugabyte` 或 `auto`(自动检测)
- **功能特性**:
- **分布键选择**:自动使用主键列作为分布键
- **DISTRIBUTED BY 子句**:表创建后添加 `ALTER TABLE schema.table SET DISTRIBUTED BY (col1, col2, ...)`
- **UNIQUE INDEX 处理**:在 Greenplum 上跳过 UNIQUE INDEX 创建(分布键已确保唯一性)
- **自动检测**:通过查询 PostgreSQL 版本/扩展自动检测 MPP 数据库类型
- **语法示例**:
```sql
-- MySQL 主键
PRIMARY KEY (id, user_id)
-- PostgreSQL with MPP
CREATE TABLE "users" ("id" BIGINT, "user_id" BIGINT, ...);
ALTER TABLE public.users SET DISTRIBUTED BY (id, user_id);
```
- **使用场景**:
- 将 MySQL 表迁移到 Greenplum 分布式表
- 迁移到 YugabyteDB 并配置正确的分布键
- 确保数据在 MPP 段/节点间均匀分布
### HTML 迁移报告
- **功能说明**:从转换日志生成可视化 HTML 报告,采用深色终端风格
- **命令**:
```bash
# 基本用法
./mysql2pg report -l conversion.log
# 包含错误日志
./mysql2pg report -l conversion.log -e errors.log
# 自定义输出路径
./mysql2pg report -l conversion.log -o my-report.html
```
- **功能特性**:
- **单文件 HTML**:内联 CSS,无外部依赖,直接在浏览器中打开
- **深色终端设计**:JetBrains Mono 字体,DM Sans 正文字体,霓虹色点缀(青色、蓝色、绿色、红色、琥珀色、紫色)
- **统计卡片**:表、行、视图、索引、函数、错误数量统计
- **性能柱状图**:各阶段耗时可视化,进度条展示
- **表明细**:每表状态徽章(已转换、已存在、数据一致、数据不一致、空表)
- **错误/警告区块**:去重后的错误信息和警告,关联到具体表
- **不一致报告**:行数不匹配的表(MySQL vs PostgreSQL)
- **进度追踪**:显示迁移完成状态(完成/进行中)
- **解析的日志模式**:
- 表转换成功/跳过消息
- 分页数据同步完成消息
- 阶段汇总表格(同时写入控制台和日志文件)
- 不一致表统计
- 版本信息、警告、错误
- **去重机制**:所有条目按表名去重,防止重复统计
### 连接池配置优化
- **功能说明**:调整连接池参数,提高连接效率
- **MySQL连接池**:
- `max_open_conns: 100` - 最大连接数从50提升到100
- `max_idle_conns: 50` - 最大空闲连接数从20提升到50
- **PostgreSQL连接池**:
- `max_conns: 50` - 最大连接数从20提升到50
- **优化效果**:提高并发处理能力,减少连接创建和销毁的开销
### 数据不一致表统计
- **功能说明**:当数据校验失败时,收集并显示所有数据不一致的表信息
- **显示内容**:以表格形式显示表名、MySQL数据量和PostgreSQL数据量
- **处理逻辑**:只有当 `truncate_before_sync: false` 时,数据不一致不会中断程序执行,而是会继续执行并在最终显示统计信息
- **使用场景**:在同步场景中,了解哪些表的数据量不一致,以便后续进行处理
## 功能特性详情
### 1. 表结构转换
支持40+种MySQL字段类型到PostgreSQL兼容类型的转换,映射准确率达到99.9%。支持的字段类型映射如下:
| MySQL字段类型 | PostgreSQL字段类型 | 转换说明 |
|-------------|-----------------|---------|
| bigint, bigint(20), bigint(11), bigint(32), bigint(24), bigint(128), bigint(10), bigint(19), biginteger | BIGINT | 所有bigint变体统一转换为BIGINT |
| int, int(11), int(4), int(2), int(5), int(10), int(20), int(255), int(32), int(8), int(60), int(3), int(25), int(22), integer | INTEGER | 所有int变体统一转换为INTEGER |
| mediumint, mediumint(9) | INTEGER | mediumint转换为INTEGER |
| smallint, smallint(6), smallint(1), smallinteger | SMALLINT | 所有smallint变体统一转换为SMALLINT |
| tinyint(1) | BOOLEAN | tinyint(1)转换为BOOLEAN(布尔值) |
| tinyint, tinyint(4), tinyint(255), tinyinteger | SMALLINT | 其他tinyint变体转换为SMALLINT |
| decimal, decimal(10,0), decimal(10,2), numeric | DECIMAL | decimal保持为DECIMAL,保留精度 |
| double, double precision | DOUBLE PRECISION | double转换为DOUBLE PRECISION |
| float | REAL | float转换为REAL |
| char, char(1) | CHAR | char保持为CHAR,保留长度 |
| varchar, varchar(255), varchar(256), varchar(64), varchar(20), varchar(100), varchar(50), varchar(128), varchar(500), varchar(200) | VARCHAR | 所有varchar变体保持为VARCHAR,保留长度 |
| text, longtext, mediumtext, tinytext | TEXT | 所有text变体统一转换为TEXT |
| blob, longblob, mediumblob, tinyblob, binary, varbinary, varbinary(64) | BYTEA | 所有二进制类型统一转换为BYTEA |
| datetime, datetime(6), datetime(3) | TIMESTAMP | datetime转换为TIMESTAMP,保留精度 |
| timestamp, timestamp(6), timestamp(3) | TIMESTAMP | timestamp保持为TIMESTAMP,保留精度 |
| date | DATE | date保持为DATE |
| time | TIME | time保持为TIME,保留精度 |
| year | INTEGER | year转换为INTEGER |
| json, json(1024) | JSON | json转换为JSON |
| jsonb | JSONB | jsonb保持为JSONB |
| enum | VARCHAR(255) | enum转换为VARCHAR(255) |
| set | VARCHAR(255) | set转换为VARCHAR(255) |
| geometry | GEOMETRY | geometry保持为GEOMETRY |
| point | POINT | point保持为POINT |
| linestring | LINESTRING | linestring保持为LINESTRING |
| polygon | POLYGON | polygon保持为POLYGON |
| multipoint | MULTIPOINT | multipoint保持为MULTIPOINT |
| multilinestring | MULTILINESTRING | multilinestring保持为MULTILINESTRING |
| multipolygon | MULTIPOLYGON | multipolygon保持为MULTIPOLYGON |
| geometrycollection | GEOMETRYCOLLECTION | geometrycollection保持为GEOMETRYCOLLECTION |
| bigint AUTO_INCREMENT | BIGSERIAL | 自增bigint转换为BIGSERIAL |
| int AUTO_INCREMENT | SERIAL | 自增int转换为SERIAL |
### 2. 数据转换
- 支持百万级数据量转换,数据完整性保持率100%
- 平均转换速度可达10,000+行/秒
- 支持批量插入,每批可达10,000行
- 可配置同步前是否清空表数据
### 3. 视图转换
支持MySQL视图定义到PostgreSQL的完整转换,包括视图SQL语句解析、MySQL特定函数替换、语法调整等功能。
#### 支持的转换功能:
1. **标识符处理**:将MySQL的反引号(`)替换为PostgreSQL的双引号(")
2. **语法兼容调整**:
- LIMIT a,b 语法转换为 LIMIT b OFFSET a
- 表连接条件优化,自动为列添加表别名
#### 转换语法示例:
| 转换类型 | MySQL语法 | PostgreSQL语法 | 说明 |
|---------|---------|---------------|------|
| 基本视图创建 | `CREATE VIEW `user_view` AS SELECT `id`, `name` FROM `users`;` | `CREATE VIEW "user_view" AS SELECT "id", "name" FROM "users";` | 标识符处理(反引号→双引号) |
| LIMIT分页查询 | `SELECT * FROM `users` LIMIT 10, 20;` | `SELECT * FROM "users" LIMIT 20 OFFSET 10;` | LIMIT a,b → LIMIT b OFFSET a |
| IFNULL函数转换 | `SELECT IFNULL(`name`, 'Unknown') FROM `users`;` | `SELECT COALESCE("name", 'Unknown') FROM "users";` | 空值处理函数转换 |
| IF条件函数转换 | `SELECT IF(`active`=1, 'Active', 'Inactive') FROM `users`;` | `SELECT CASE WHEN "active"=1 THEN 'Active' ELSE 'Inactive' END FROM "users";` | 条件判断函数转换 |
| GROUP_CONCAT转换 | `SELECT GROUP_CONCAT(`name`) FROM `users` GROUP BY `department`;` | `SELECT string_agg(CAST("name" AS text), ',') FROM "users" GROUP BY "department";` | 分组拼接字符串转换 |
| CONCAT函数转换 | `SELECT CONCAT(`first_name`, ' ', `last_name`) FROM `users`;` | `SELECT "first_name` || ' ' || "last_name" FROM "users";` | 字符串连接操作转换 |
| DATE_FORMAT转换 | `SELECT DATE_FORMAT(`created_at`, '%Y-%m-%d') FROM `users`;` | `SELECT to_char("created_at", 'YYYY-MM-DD') FROM "users";` | 日期格式化函数转换 |
| JSON_EXTRACT转换 | `SELECT JSON_EXTRACT(`data`, '$.name') FROM `users`;` | `SELECT "data" -> 'name' FROM "users";` | JSON提取函数转换 |
#### 核心函数转换表:
##### 通用函数转换:
| MySQL函数 | PostgreSQL等效函数 | 说明 |
|----------|-----------------|------|
| IFNULL(expr1, expr2) | COALESCE(expr1, expr2) | 空值处理函数 |
| IF(condition, then, else) | CASE WHEN condition THEN then ELSE else END | 条件判断函数 |
| GROUP_CONCAT(expr) | string_agg(CAST(expr AS text), ',') | 分组拼接字符串 |
| CONVERT(expr, TYPE) | CAST(expr AS TYPE) | 类型转换函数 |
| CONCAT(a, b) | a || b | 字符串连接操作 |
##### JSON函数转换:
| MySQL函数 | PostgreSQL等效函数 | 说明 |
|----------|-----------------|------|
| JSON_OBJECT() | json_build_object() | 创建JSON对象 |
| JSON_ARRAY() | json_build_array() | 创建JSON数组 |
| JSON_EXTRACT(json, path) | json -> path | 提取JSON值 |
| JSON_VALUE(json, path) | json ->> path | 提取JSON文本值 |
| JSON_KEYS(json) | json_object_keys(json) | 获取JSON对象键 |
| JSON_LENGTH(json) | json_array_length(json) | 获取JSON数组长度 |
| JSON_TYPE(json) | jsonb_typeof(json) | 获取JSON值类型 |
| JSON_VALID(json) | (json IS NOT NULL AND jsonb_typeof(json::jsonb) IS NOT NULL) | 验证JSON有效性 |
##### 时间函数转换:
| MySQL函数 | PostgreSQL等效函数 | 说明 |
|----------|-----------------|------|
| UNIX_TIMESTAMP() | extract(epoch from now()) | 获取当前时间戳 |
| FROM_UNIXTIME(timestamp) | to_timestamp(timestamp) | 时间戳转换为日期时间 |
| DATE_FORMAT(date, format) | to_char(date, format) | 日期时间格式化 |
| STR_TO_DATE(str, format) | to_date(str, format) | 字符串转换为日期 |
| DATEDIFF(date1, date2) | date_part('day', date1 - date2) | 计算日期差 |
| TIMEDIFF(time1, time2) | time1 - time2 | 计算时间差 |
| DATE_ADD(date, INTERVAL expr unit) | date + expr::interval '1 unit' | 日期时间加法 |
| DATE_SUB(date, INTERVAL expr unit) | date - expr::interval '1 unit' | 日期时间减法 |
##### 系统与加密函数转换:
| MySQL函数 | PostgreSQL等效函数 | 说明 |
|----------|-----------------|------|
| LAST_INSERT_ID() | lastval() | 获取最后插入的ID |
| CONNECTION_ID() | pg_backend_pid() | 获取连接ID |
| DATABASE() | current_database() | 获取当前数据库名 |
| USER() | current_user | 获取当前用户名 |
| MD5(str) | md5(str) | MD5加密 |
| SHA1(str) | sha1(str) | SHA1加密 |
| SHA2(str) | sha2(str) | SHA2加密 |
| UUID() | uuid_generate_v4() | 生成UUID |
##### 网络函数转换:
| MySQL函数 | PostgreSQL等效函数 | 说明 |
|----------|-----------------|------|
| INET_ATON(ip) | (CAST(ip AS inet) - CAST('0.0.0.0' AS inet))::bigint | IP地址转数字 |
| INET_NTOA(num) | CAST((CAST('0.0.0.0' AS inet) + num::bigint) AS text) | 数字转IP地址 |
视图转换准确率高达98%,支持批量转换视图,每批可达10个。
### 4. 储存过程转换
- 支持50+个常用MySQL函数到PostgreSQL等效函数的转换
- 函数转换准确率达到95%以上
- 支持批量转换函数,每批可达5个
### 5. 索引转换
- 支持主键、唯一索引、普通索引等多种索引类型的转换
- 索引转换成功率99%
- 支持批量转换索引,每批可达20个
### 6. 用户转换
- 支持MySQL到PostgreSQL用户权限的完整映射
- 权限转换准确率98%
- 支持批量转换用户,每批可达10个
### 7. 表权限转换
- 支持表级别的权限设置转换
- 确保PostgreSQL中的表权限与MySQL一致
- 可单独控制是否转换表权限
### 8. 数据校验功能
- 验证MySQL和PostgreSQL数据一致性,校验准确率100%
- 支持批量校验
- 自动统计数据量不匹配的表,提供详细的不一致表清单
### 9. 并发转换
- 支持10-50并发线程可配置
- 并发转换速度比单线程提升5-10倍
- 可根据系统资源和网络状况调整并发数
### 10. 实时进度显示
- 实时展示转换进度,进度更新频率1次/秒
- 显示各阶段的耗时统计,帮助用户了解转换性能
- 可配置是否显示任务进度
### 11. 可配置的连接池参数
- 支持自定义MySQL和PostgreSQL连接池设置
- MySQL支持配置最大连接数、最大空闲连接数和连接最大生命周期
- PostgreSQL支持配置最大连接数
- 最大连接数可达100+
### 12. test_only模式
- 仅测试连接,不执行转换,连接测试响应时间<1秒
- 可单独测试MySQL或PostgreSQL连接
- 测试连接时会显示数据库版本信息
- 方便用户快速验证连接配置
### 13. HTML 迁移报告
- **命令**: `./mysql2pg report -l conversion.log`
- **深色终端风格** 使用 JetBrains Mono 字体和霓虹色点缀
- **单文件 HTML** 内联 CSS — 无外部依赖
- **去重机制**: 所有日志条目按表名去重
- **进度追踪**: 显示迁移完成状态(完成/进行中)
- **报告区块**: 统计卡片、性能柱状图、表明细、不一致表、警告、错误
- **控制台输出**: 阶段汇总表格和不一致表统计同时写入控制台和日志文件,供 report 命令解析
### 14. MPP 分布式数据库支持
- **Greenplum/YugabyteDB 支持**: 自动为 MPP 数据库添加 `DISTRIBUTED BY` 子句
- **智能分布键选择**: 默认使用主键列作为分布键
- **自动检测**: 自动检测 MPP 数据库类型(greenplum/yugabyte/auto)
- **UNIQUE INDEX 处理**: 在 Greenplum 上跳过 UNIQUE INDEX 创建(使用分布键确保唯一性)
- **配置方式**: 通过 `conversion.mpp.enabled: true` 启用
- **分布语法**: `ALTER TABLE schema.table SET DISTRIBUTED BY (col1, col2, ...)`
## 安装
### 前提条件
- Go 1.24+
- MySQL 5.7+
- PostgreSQL 12+
### 构建
```bash
# 克隆仓库
git clone https://github.com/xfg0218/mysql2pg.git
cd mysql2pg
# 构建项目
make build
```
## 使用方法
### 1. 创建配置文件
复制示例配置文件并根据实际情况修改:
```bash
cp config.example.yml config.yml
```
配置文件说明:
```yaml
# MySQL连接配置
mysql:
host: localhost
port: 3306
username: root
password: password
database: test_db
test_only: false # 仅测试连接,不执行转换
max_open_conns: 100 # 连接池配置的最大连接数
max_idle_conns: 50 # 连接池配置的最大空闲连接数
conn_max_lifetime: 3600 # 连接池配置的最大生命周期(秒)
connection_params: charset=utf8mb4&parseTime=false&interpolateParams=true&readTimeout=60s&writeTimeout=60s&timeout=30s # MySQL连接参数
# PostgreSQL连接配置
postgresql:
host: localhost
port: 5432
username: postgres
password: password
database: test_db
test_only: false # 仅测试连接,不执行转换
max_conns: 50 # 连接池配置的最大连接数
pg_connection_params: search_path=public connect_timeout=300 statement_timeout=0 # PostgreSQL连接参数
# 转换配置
conversion:
# 转换选项,按照以下参数顺序进行
options:
tableddl: true # step1: 转换表DDL
data: true # step2: 转换数据(先转DDL后转数据)
view: true # step3: 转换表视图
indexes: true # step4: 转换索引
functions: true # step5: 转换函数
users: true # step6: 转换用户
table_privileges: true # step7: 转换用户在表上的权限
lowercase_columns: true # 控制表字段是否需要转小写,true为转小写(默认值),false保持与MySQL字段一致
skip_existing_tables: true # 如果表在PostgreSQL中已存在则跳过,否则创建
use_table_list: false # 是否使用指定的表列表进行数据同步,其他步骤不生效
table_list: [table1] # 指定要同步的表列表,当use_table_list为true时生效,格式为[table1,table2,...]
exclude_use_table_list: false # 是否使用跳过表列表,为true时忽略exclude_table_list中的表
exclude_table_list: [table1] # 要跳过的表列表,当exclude_use_table_list为true时生效
validate_data: true # 同步数据后验证数据一致性
truncate_before_sync: false # 同步前是否清空表数据
# 视图排除列表
exclude_use_view_list: false # 是否使用视图排除列表
exclude_view_list: [view1, view2] # 要跳过的视图列表,当exclude_use_view_list为true时生效
# 函数排除列表
exclude_use_function_list: false # 是否使用函数排除列表
exclude_function_list: [func1, func2] # 要跳过的函数列表,当exclude_use_function_list为true时生效
# MPP 分布式数据库支持
mpp:
enabled: false # 是否启用 MPP 模式(启用后才会创建 UNIQUE INDEX)
database: auto # MPP 数据库类型:greenplum/yugabyte/auto(自动检测)
# 限制配置
limits:
concurrency: 10 # 并发数限制
bandwidth_mbps: 100 # 网络带宽限制(Mbps)
max_ddl_per_batch: 10 # 一次性转换DDL的个数限制
max_functions_per_batch: 5 # 一次性转换function的个数限制
max_indexes_per_batch: 20 # 一次性转换index的个数限制
max_users_per_batch: 10 # 一次性转换用户的个数限制
max_rows_per_batch: 1000 # 一次性同步数据的行数限制
batch_insert_size: 1000 # 批量插入的大小
# 运行配置
run:
show_progress: true # 显示任务进度
error_log_path: ./errors.log # 转换异常保存路径
enable_file_logging: true # 是否启用文件日志
log_file_path: ./conversion.log # 日志文件保存路径
show_console_logs: true # 是否在控制台显示日志信息
show_log_in_console: false # 是否在控制台显示Log日志输出
```
### 2. 运行工具
```bash
# 使用默认配置文件
./mysql2pg
# 使用指定配置文件
./mysql2pg config.yml
# 或者使用 -c 参数指定配置文件
./mysql2pg -c config.yml
```
### 3. 生成 HTML 迁移报告
```bash
# 从转换日志生成报告
./mysql2pg report -l conversion.log
# 包含错误日志
./mysql2pg report -l conversion.log -e errors.log
# 自定义输出路径
./mysql2pg report -l conversion.log -o my-report.html
# 查看帮助
./mysql2pg report -h
```
报告生成一个 **深色主题的单一 HTML 文件** 仪表板,包含:
- 统计卡片(表、行、视图、索引、函数、错误)
- 按阶段的性能柱状图
- 表明细含状态徽章和错误/警告指示器
- 数据不一致表
- 警告和错误区块
- 进度追踪(完成 vs 进行中)
- 所有条目按表名去重
## 重要参数详细解释
### 核心配置参数
#### 1. test_only
- **类型**:布尔值 (true/false)
- **默认值**:false
- **功能**:控制是否仅测试连接,不执行转换
- **适用场景**:快速验证数据库连接配置
- **影响范围**:整个转换流程,如果设置为true,将跳过所有转换步骤
#### 2. validate_data
- **类型**:布尔值 (true/false)
- **默认值**:true
- **功能**:控制是否在同步数据后验证数据一致性
- **适用场景**:确保数据迁移的完整性
- **影响范围**:数据同步阶段,验证MySQL和PostgreSQL表的行数是否一致
#### 3. truncate_before_sync
- **类型**:布尔值 (true/false)
- **默认值**:false
- **功能**:控制是否在同步数据前清空PostgreSQL表数据
- **适用场景**:
- true:全量同步,确保数据完全一致
- false:保留已有数据
- **影响范围**:数据同步阶段,影响数据同步策略和数据校验失败后的处理逻辑
#### 4. use_table_list
- **类型**:布尔值 (true/false)
- **默认值**:false
- **功能**:控制是否仅同步指定的表列表
- **适用场景**:只需要同步部分表的场景
- **影响范围**:数据同步阶段,当设置为true时,只同步 `table_list` 中指定的表
#### 5. table_list
- **类型**:字符串数组
- **默认值**:[]
- **功能**:指定要同步的表列表
- **适用场景**:与 `use_table_list` 配合使用,只同步特定的表
- **影响范围**:数据同步阶段,仅当 `use_table_list: true` 时生效
#### 6. concurrency
- **类型**:整数
- **默认值**:10
- **功能**:控制并发转换的线程数
- **适用场景**:根据系统资源和网络状况调整并发数,提高转换速度
- **影响范围**:所有转换阶段,影响转换速度和系统资源占用
#### 7. max_rows_per_batch
- **类型**:整数
- **默认值**:50000(未配置或配置为 <= 0 时)
- **功能**:控制一次性同步数据的行数限制
- **适用场景**:根据网络带宽和数据库性能调整批次大小
- **影响范围**:数据同步阶段,影响批量处理的效率
#### 8. batch_insert_size
- **类型**:整数
- **默认值**:50000(未配置或配置为 <= 0 时)
- **功能**:控制批量插入的大小
- **适用场景**:根据数据库性能调整批量插入大小,提高插入效率
- **影响范围**:数据同步阶段,影响数据插入的性能
#### 9. show_progress
- **类型**:布尔值 (true/false)
- **默认值**:true
- **功能**:控制是否显示任务进度
- **适用场景**:在控制台实时了解转换进度
- **影响范围**:所有转换阶段,影响控制台输出
#### 10. lowercase_columns
- **类型**:布尔值 (true/false)
- **默认值**:true
- **功能**:控制是否将表字段转换为小写
- **适用场景**:适应不同的命名规范,PostgreSQL默认使用小写字段名
- **影响范围**:表结构转换阶段,影响字段名的大小写
## 配置参数最佳实践
### 1. 生产环境配置
```yaml
conversion:
options:
validate_data: true # 确保数据一致性
truncate_before_sync: true # 全量同步,确保数据完全一致
concurrency: 20 # 根据系统资源调整并发数
max_rows_per_batch: 5000 # 适中的批次大小,避免内存占用过高
batch_insert_size: 5000 # 适中的批量插入大小,避免数据库压力过大
```
### 2. 保留已有数据同步配置
```yaml
conversion:
options:
validate_data: true # 确保数据一致性
truncate_before_sync: false # 保留已有数据
use_table_list: true # 只同步指定的表
table_list: [users, orders] # 指定要同步的表
concurrency: 10 # 适中的并发数
```
### 3. 快速测试配置
```yaml
mysql:
test_only: true # 仅测试MySQL连接
postgresql:
test_only: true # 仅测试PostgreSQL连接
```
### 4. 性能优化配置
```yaml
conversion:
limits:
concurrency: 30 # 较高的并发数,充分利用系统资源
max_rows_per_batch: 10000 # 较大的批次大小,减少网络往返
batch_insert_size: 10000 # 较大的批量插入大小,提高插入效率
bandwidth_mbps: 200 # 较高的带宽限制,适用于高速网络环境
```
### 5. 数据不一致示例
```
+------------------+----------------+------------------+
数据量校验不一致的表统计:
+------------------+----------------+------------------+
| 表名 | MySQL数据量 | PostgreSQL数据量 |
+------------------+----------------+------------------+
| user | 327680 | 655360 |
| users_20251201 | 200002 | 600006 |
+------------------+----------------+------------------+
```
### 6. 运行转换示例
```
$ ./mysql2pg -c config.yml
+-------------------------------------------------------------+
| 数据库版本信息: |
+--------------+----------------------------------------------+
| 数据库类型 | 版本信息 |
+--------------+----------------------------------------------+
| MySQL | 8.0.44 |
| PostgreSQL | PostgreSQL 16.1 on x86_64-pc-linux-gn... |
+--------------+----------------------------------------------+
按照指定选项执行转换...
1. 开始转换表结构...
进度: 0.43% (1/232) : 转换表 case_31_sys_utf8mb3 成功
******
进度: 16.81% (39/232) : 转换表 case_35_enum_charset 成功
2. 同步表数据...
进度: 16.81% (40/232) : 同步表 case_04_mb3_suffix 数据成功,共有 0 行数据,数据一致
******
进度: 33.19% (78/232) : 同步表 case_23_weird_syntax 数据成功,共有 0 行数据,数据一致
3. 转换表视图...
进度: 34.05% (79/232) : 转换表视图 view_case01_integers 成功
************
进度: 37.93% (88/232) : 转换表视图 view_case10_defaults 成功
4. 转换表索引...
进度: 38.36% (89/232) : [case_13_enum_set]转换索引 idx_case13_e1 成功
进度: 38.79% (90/232) : [CASE_38_SNAKE]转换索引 idx_case38_price 成功
进度: 39.22% (91/232) : [CASE_40_DEFAULT]转换索引 idx_case40_email 成功
***********
进度: 95.26% (221/232) : [case_12_unsigned]转换索引 idx_case12_c2 成功
进度: 95.69% (222/232) : [case_12_unsigned]转换索引 idx_case12_c3 成功
5. 开始转换函数...
进度: 96.12% (223/232) : 转换库函数 get_combined_data 成功
进度: 96.55% (224/232) : 转换库函数 get_detailed_data 成功
进度: 96.98% (225/232) : 转换库函数 get_joined_data 成功
6. 开始转换用户...
进度: 97.41% (226/232) : 转换用户 mysql2pg@% 的权限成功
进度: 97.84% (227/232) : 转换用户 test1@% 的权限成功
进度: 98.28% (228/232) : 转换用户 test2@% 的权限成功
7. 转换表权限...
进度: 99.14% (230/232) : 转换用户 test1 表权限成功
进度: 99.57% (231/232) : 转换用户 test1 表权限成功
进度: 100.00% (232/232) : 转换用户 test1 表权限成功
进度: 100.43% (233/232) : 转换用户 test2 表权限成功
进度: 100.86% (234/232) : 转换用户 test2 表权限成功
----------------------------------------------------------------------
各阶段及耗时汇总如下:
+--------------------------+----------------+-----------------------+
| 阶段 | 对象数量 | 耗时(秒) |
+--------------------------+----------------+-----------------------+
| 转换表结构 | 39 | 3.08 |
| 同步表数据 | 39 | 1.15 |
| 转换表视图 | 10 | 1.20 |
| 转换表索引 | 132 | 2.15 |
| 转换库函数 | 3 | 0.25 |
| 转换库用户 | 3 | 0.18 |
| 转换表权限 | 6 | 1.62 |
+--------------------------+----------------+-----------------------+
| 总耗时 | | 9.63 |
+--------------------------+----------------+-----------------------+
```
### 7. 数据库链接测试案例
```
-- mysql.test_only=true and postgresql.test_only=true 时显示如下
+-------------------------------------------------------------+
1. MySQL连接测试完成,版本信息已显示,退出程序。
2. PostgreSQL 连接测试完成,版本信息已显示,退出程序。
+-------------------------------------------------------------+
| 数据库版本信息: |
+--------------+----------------------------------------------+
| 数据库类型 | 版本信息 |
+--------------+----------------------------------------------+
| MySQL | 5.7.44 |
| PostgreSQL | PostgreSQL 16.1 on x86_64-pc-linux-gn... |
+--------------+----------------------------------------------+
-- mysql.test_only=false or postgresql.test_only=false 时显示如下
+-------------------------------------------------------------+
1. MySQL连接测试完成,版本信息已显示,退出程序。
+-------------------------------------------------------------+
| 数据库版本信息: |
+--------------+----------------------------------------------+
| 数据库类型 | 版本信息 |
+--------------+----------------------------------------------+
| MySQL | 5.7.44 |
| PostgreSQL | PostgreSQL 16.1 on x86_64-pc-linux-gn... |
+--------------+----------------------------------------------+
+-------------------------------------------------------------+
2. PostgreSQL 连接测试完成,版本信息已显示,退出程序。
+-------------------------------------------------------------+
| 数据库版本信息: |
+--------------+----------------------------------------------+
| 数据库类型 | 版本信息 |
+--------------+----------------------------------------------+
| MySQL | 5.7.44 |
| PostgreSQL | PostgreSQL 16.1 on x86_64-pc-linux-gn... |
+--------------+----------------------------------------------+
```
### 8. 同步表数据案例
在2核,2GB 的环境上,`limits.concurrency=4` , 和 `limits.batch_insert_size=10000` 的情况下,同步速度约为 1691 行/秒
> 如果服务器配置高,可以适当调整以上参数。
```sql
-- 表的DDL
DROP TABLE IF EXISTS case_01_integers;
CREATE TABLE case_01_integers (
col_tiny tinyint,
col_small smallint,
col_medium mediumint,
col_int int,
col_integer integer,
col_big bigint,
col_int_prec int(11),
col_big_prec bigint(20)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE INDEX idx_case_01_col_tiny ON case_01_integers(col_tiny);
-- 同步速度
进度: 0.00% (1/1) : 同步表 case_01_integers 完成,12000000 行数据,跳过验证
----------------------------------------------------------------------
各阶段及耗时汇总如下:
+--------------------------+----------------+-----------------------+
| 阶段 | 对象数量 | 耗时(秒) |
+--------------------------+----------------+-----------------------+
| 同步表数据 | 1 | 7093.55 |
+--------------------------+----------------+-----------------------+
| 总耗时 | | 7093.55 |
+--------------------------+----------------+-----------------------+
real 118m13.675s
user 6m7.256s
sys 0m6.487s
```
## 常见问题
### 1. 数据校验失败怎么办?
- 检查 `truncate_before_sync` 设置
- 如果设置为 `true`,检查PostgreSQL表是否有其他进程在写入数据
- 如果设置为 `false`,工具会继续执行,但会记录不一致的表
### 2. 如何提高转换速度?
- 增加 `concurrency` 配置项的值
- 增加 `max_rows_per_batch` 和 `batch_insert_size` 配置项的值
- 确保网络连接稳定且带宽充足
### 3. 转换过程中出现连接错误怎么办?
- 检查数据库连接配置
- 确保MySQL和PostgreSQL服务正常运行
- 检查网络连接是否稳定
### 4. 如何仅测试数据库连接?
- 在配置文件中设置 `mysql.test_only: true` 或 `postgresql.test_only: true`
- 运行工具,它会测试连接并显示版本信息,然后退出
### 5. 主键冲突问题
当主键冲突时会提示一下的报错、根据实际情况是否选择跳过或truncate 表数据。
```sql
错误: 插入表 users_20251201 数据失败: 批量插入失败: ERROR: duplicate key value violates unique constraint "users_20251201_pkey" (SQLSTATE 23505), 数据样本: [[49] [50] [51]]
转换失败: 批量插入失败: ERROR: duplicate key value violates unique constraint "users_20251201_pkey" (SQLSTATE 23505), 数据样本: [[49] [50] [51]]
```
### 6. 编译时下载依赖包超时
报错信息:
```sql
github.com/yourusername/mysql2pg/internal/config imports
github.com/spf13/viper: github.com/spf13/viper@v1.18.2: Get "https://proxy.golang.org/github.com/spf13/viper/@v/v1.18.2.zip": dial tcp [2607:f8b0:400a:80d::2011]:443: i/o timeout
github.com/yourusername/mysql2pg/internal/mysql imports
github.com/go-sql-driver/mysql: github.com/go-sql-driver/mysql@v1.7.1: Get "https://proxy.golang.org/github.com/go-sql-driver/mysql/@v/v1.7.1.zip": dial tcp [2607:f8b0:400a:80d::2011]:443: i/o timeout
```
解决方法:
```sql
# go env -w GOPROXY=https://goproxy.cn,direct
# go env GOPROXY
https://goproxy.cn,direct
# make build
```
## 总结
MySQL2PG是一款功能强大、性能优异的MySQL到PostgreSQL转换工具,它提供了全面的转换功能和丰富的配置选项,能够满足各种复杂的数据库迁移需求。无论是小型项目还是大型企业级应用,MySQL2PG都能提供高效、可靠的数据库迁移解决方案。