MySQL迁移到PostgreSQL数据库-FGMySQL2PG工具
MySQL迁移到PostgreSQL数据库-FGMySQL2PG工具
本手册覆盖FGMySQL2PG程序介绍、功能特性、命令行与可视化操作、各类案例场景与故障排查。
一、FGMySQL2PG程序介绍
1.1 工具简介
FGMySQL2PG 是一款面向企业级数据库迁移场景的高性能 MySQL 到 PostgreSQL 全栈迁移工具。它不仅覆盖表结构、数据、索引、视图、函数、用户与权限的迁移,还在底层实现了语法转换、字符集规范化、批量写入优化、并发控制、断点续传与失败重试等关键工程能力,能够在 PB 级数据量、复杂业务对象、严格一致性要求的场景下保持稳定运行。
工具同时提供两种使用入口:
- 命令行入口(
fgmysql2pg/python -m fgmysql2pg):适合脚本化、批处理、CI/CD 集成、无人值守迁移场景; - 可视化控制台(Web Console):基于 Flask + 原生 JavaScript 构建的单页应用,无需记忆参数,浏览器中即可完成连接测试、迁移评估、启动/停止迁移、查看报告的完整流程,适合运维人员手工操作与排错。
两类入口共享同一套核心引擎(converter / mysql_conn / pg_conn / native),转换规则与稳定性机制完全一致,用户可按场景自由切换。
1.2 作者信息
作者:风哥
官方网站: http://www.fgedu.net.cn , http://www.itpux.com
数据库教程: https://edu.51cto.com/lecturer/8020378.html
1.3 设计理念
- 简洁强大:单页 Web UI 集成所有功能,无页面跳转;命令行参数极简,子命令清晰;
- 稳定优先:采用 COPY FROM STDIN 批量写入、3 次指数退避重试、死锁检测、UTF8MB4 字符集规范化、PG 会话级 statement_timeout/lock_timeout 等机制,保证迁移不中断、不乱码、不丢行;
- 可观测:实时进度条、逐表状态网格、滚动日志、HTML 迁移报告四位一体,让每一次迁移都"看得见";
- 可回放:所有配置可保存为 YAML 文件,支持反复载入复用,适合多环境部署。
1.4 与同类工具的差异
- 函数映射覆盖更广(348 个映射,覆盖 JSON / 日期 / 正则 / 聚合 / 字符串 / 加密 / 系统 / 流程控制等全部常用类别);
- 存储过程流程控制语法自动转换(IF/ELSEIF/WHILE/REPEAT/DECLARE/LEAVE/ITERATE → PL/pgSQL 等价语法);
- PG 端用 psycopg2 的 COPY FROM STDIN,性能接近 Go 的 pgx.CopyFrom;
- Web 控制台原生单页,无任何前端构建依赖,部署即用。
二、功能特性
2.1 核心迁移能力
| 模块 | 能力描述 |
|---|---|
| 表结构 DDL | MySQL 建表语句自动转 PG 建表语句,40+ 类型映射,覆盖 UNSIGNED / ZEROFILL / BIT / ENUM / SET / JSON / BLOB / VARBINARY 等边界 |
| 数据同步 | COPY FROM STDIN 批量写入;键集分页(有主键)与全列排序分页(无主键大表)双策略,避免丢行;并发调度,吞吐量 5-8 倍于 executemany |
| 索引迁移 | 自动重建主键、唯一索引、普通索引、复合索引、FULLTEXT 索引;Greenplum / YugabyteDB 等 MPP 库自动降级为普通 CREATE INDEX |
| 视图迁移 | MySQL 视图 DDL 自动转 PG 视图 DDL,反引号→双引号、函数名映射、复杂函数参数重组(CONCAT_WS / JSON_EXTRACT / IF 等) |
| 函数 / 存储过程 | 348 个函数映射;存储过程流程控制语法自动转 PL/pgSQL(IF/ELSEIF/WHILE/REPEAT/DECLARE/LEAVE/ITERATE) |
| 用户与权限 | MySQL 用户迁移为 PG 角色;表权限映射为 GRANT 语句;密码无法迁移(MySQL 用 caching_sha2,PG 用 SCRAM) |
| 数据校验 | 同步后逐表比对 MySQL 与 PG 行数,不一致表直接列清单 |
| HTML 迁移报告 | 一条命令生成单文件可视化报告,含完整统计与错误详情 |
2.2 函数与语法兼容
JSON 函数族(13 个):JSON_OBJECT→json_build_object、JSON_ARRAY→json_build_array、JSON_INSERT/REPLACE/SET→jsonb_set、JSON_REMOVE→jsonb_delete、JSON_EXTRACT→->、JSON_VALUE→->>、JSON_MERGE_PATCH→||、JSON_VALID→jsonb_typeof 等。
日期/时间函数:YEARWEEK、DAYNAME、MONTHNAME、QUARTER、WEEK、DATE_ADD/SUB INTERVAL、TIME_FORMAT、TIME_TO_SEC、SEC_TO_TIME、ADDDATE、SUBDATE、TIMEDIFF、MICROSECOND、UTC_TIMESTAMP、MAKEDATE、MAKETIME 等。
正则函数:REGEXP_LIKE、REGEXP_INSTR、REGEXP_REPLACE、REGEXP_SUBSTR。
聚合/字符串函数:GROUP_CONCAT(DISTINCT ... ORDER BY ... SEPARATOR ...)→string_agg、CONCAT_WS(sep,a,b,c)→ARRAY_TO_STRING(ARRAY[a,b,c], sep)、IF(cond,a,b)→CASE WHEN、CAST(x USING charset)→x、BIT_AND/OR/XOR、STD/STDDEV/VARIANCE、SUBSTRING_INDEX、ELT、QUOTE、SPACE、BIT_LENGTH 等。
存储过程流程控制:ELSEIF→ELSIF、WHILE...DO...END WHILE→WHILE...LOOP...END LOOP、REPEAT...UNTIL→LOOP...EXIT WHEN、LEAVE→EXIT、ITERATE→CONTINUE、DECLARE var TYPE DEFAULT x→DECLARE var TYPE := x、SET @x:=→x:=、DELIMITER 剥离、CREATE PROCEDURE→CREATE FUNCTION ... RETURNS void。
全文检索:MATCH(col) AGAINST(q)→to_tsvector(col) @@ to_tsquery(q)。
2.3 稳定性强化(核心特性)
- UTF8MB4 字符集规范化:MySQL 端强制
charset=utf8mb4+use_unicode=True,PostgreSQL 端强制client_encoding=UTF8;BLOB/VARBINARY 列直接返回 bytes 不被错误解码,从根本上防止 emoji、4 字节字符、二进制内容乱码。 - 无主键表分档策略:
- 行数 ≤ 200 万:流式 OFFSET 分页,性能足够;
- 行数 > 200 万:全列 ORDER BY + OFFSET 分页,保证顺序稳定,避免并发写入下丢行/重行;
- 单列主键:
WHERE pk > last_pk ORDER BY pk LIMIT n,O(n); - 复合主键:行构造器
(pk1,pk2) > (?,?),O(n)。
- COPY FROM STDIN 批量写入:相比
executemany提升 5-10 倍性能;自动对 None/bytes/制表符/换行符/反斜杠做转义;失败自动回退到execute_values,确保即使在 JSON、特殊字符、类型不匹配场景下也能完成迁移。 - 重试与死锁检测:识别 14 类可重试 SQLSTATE(
40P01死锁、40001序列化失败、08000连接异常、53300连接数满、53M00Yugabyte 临时不可用等),3 次指数退避(1s/2s/4s),不可重试错误直接回退。 - PG 会话参数白名单:从
pg_connection_params解析statement_timeout/lock_timeout/search_path/idle_in_transaction_session_timeout等,在连接建立后自动SET,防止长查询挂死整个迁移进程。 - 进度更新合并机制:前端节流由"丢弃"改为"合并",被节流的最后状态会在 200ms 后兜底 poll,彻底解决"进度条卡在 95%"的 Bug,保证 100% 最终状态不丢失。
- 协作式停止:用户点击"停止迁移"或 Ctrl+C 后,停止信号会在下一个批次/表边界被检测到,当前批次正常完成,避免数据半截写入。
- 连接池探活:每次借出连接先
SELECT 1探活,失效连接自动剔除重建,避免长时间空闲后的连接超时。 - 数据类型边界处理:
BIGINT UNSIGNED上限 18446744073709551615 超 PG BIGINT → 升档为NUMERIC(20,0);INT UNSIGNED→BIGINT;SMALLINT UNSIGNED→INTEGER;BIT(n)保留长度,不被_normalize误剥离;TINYINT(1)可选映射BOOLEAN或SMALLINT;ZEROFILL仅显示属性,剥离不影响存储;ENUM/SET统一映射为TEXT(PG 原生 enum 类型需手动维护值域);JSON→JSONB(PG 推荐,支持索引与 GIN)。
2.3.1 大数据量迁移能力(100GB - 5TB)
针对企业级核心库的大数据量迁移场景,工具内置一套完整的 TB/PB 级迁移引擎,核心机制如下:
-
MySQL 流式游标(SSCursor)
- 使用 PyMySQL 的
SSCursor服务端游标,逐批fetchmany(batch_size)读取,不在客户端缓存全量数据; - 默认
read_timeout=28800(8 小时)放宽,避免长时间无数据返回被强制断开; - 配合键集分页(
WHERE pk > last_pk)实现 O(n) 复杂度的全表扫描,避免 OFFSET 在大表上的 O(n²) 性能塌方。
- 使用 PyMySQL 的
-
生产者-消费者流式管道
- 单表迁移采用双线程架构:生产者线程持续从 MySQL 流式读取,主线程持续向 PG COPY 写入,两端并行;
- 有界队列(默认容量 4)连接生产者与消费者,限制内存峰值在 GB 级(而非数据量级);
- 队列满时生产者自动阻塞,避免数据堆积导致 OOM;
- 队列空时消费者等待,自动适应生产者读取速率。
-
断点续传
- 每张表独立检查点文件(
./.checkpoint/{schema}.{table}.json),记录已迁移主键值/偏移量、已插入行数、总行数、列定义; - 迁移中断(进程崩溃、网络断开、用户 Ctrl+C)后重启,自动加载检查点,从最近位置继续,避免重头再来;
- 检查点文件采用原子写入(临时文件 + rename),防止中断时半截 JSON 损坏;
- 表迁移完成后检查点自动删除,避免下次重复加载;
- 启动时通过
list_pending()识别上次中断的表,并在进度事件中上报resumed_tables统计。
- 每张表独立检查点文件(
-
动态批大小(AIMD 简化版)
- 根据队列水位与内存压力自适应调整批次大小:
- 队列使用率 > 75%:消费者慢,批大小 × 0.8 降低单批延迟;
- 队列使用率 < 25% 且批次填满:生产者慢,批大小 × 1.2 提高吞吐;
- RSS 内存超
memory_limit_mb:批大小立即减半;
- 批大小在 [1000, 200000] 范围内调整,避免极端值。
- 根据队列水位与内存压力自适应调整批次大小:
-
内存硬保护
- 两级内存阈值:
memory_limit_mb(软限,触发 GC)和memory_hard_limit_mb(硬限,触发生产者阻塞); - RSS 超
memory_hard_limit_mb时生产者主动阻塞,等待消费者消化队列,最长 60 秒; - 阻塞期间持续 GC,内存仍超
hard_limit * 1.25时再次 GC; - 5TB 场景建议
memory_hard_limit_mb: 4096,实测峰值稳定在 2-3 GB。
- 两级内存阈值:
-
连接断开重连
- MySQL 生产者线程:捕获
Lost connection/server has gone away/broken pipe/Connection reset等错误,指数退避重试 3 次(1s/2s/4s),重试时从断点位置继续读取; - PG 消费者:
batch_insert内置 3 次指数退避重试,连接池自动丢弃坏连接重建; - TCP keepalive(idle=30s/interval=10s/count=3)防止长时间迁移被中间设备超时断开。
- MySQL 生产者线程:捕获
-
多表并行调度
ThreadPoolExecutor并发同步多张表(默认concurrency=10),单表失败不影响其他表;- 每张表独立生产者-消费者管道,互不干扰;
- 全局内存监控在 Manager 启动时上报 RSS,供前端预警。
-
进度与 ETA
- 单表进度:每批 COPY 完成后上报
inserted/total/pct/rows_per_sec/eta_sec/rss_mb; - ETA 基于最近 5 批的滑动窗口均值,避免早期抖动或尾部偏置;
- 全局进度:按表完成度计算,显示
done/total表数与累计行数。
- 单表进度:每批 COPY 完成后上报
2.3.2 大数据量迁移配置项
在 config.yml 的 conversion.limits 段配置大数据量迁移参数:
conversion:
limits:
# 并发表数(5TB 场景建议 4-8,避免内存叠加)
concurrency: 8
# 单批 INSERT 行数(大表建议 50000-100000)
batch_insert_size: 50000
# ===== TB 级迁移扩展 =====
# 流式游标(SSCursor),必开
streaming_cursor: true
# 生产者-消费者队列容量(每表独立,5TB 建议 4-8)
queue_size: 4
# 内存软限(MB),触发 GC 与批大小减半
memory_limit_mb: 2048
# 内存硬限(MB),触发生产者阻塞;5TB 建议 4096
memory_hard_limit_mb: 4096
# 大表阈值(行数),超过启用断点续传
large_table_threshold: 1000000
# 超大表阈值(行数),超过启用流式管道
huge_table_threshold: 10000000
# 断点续传检查点目录(空字符串禁用)
checkpoint_dir: "./.checkpoint"
# COPY 单批最大行数
copy_chunk_size: 100000
# 重试次数与退避基数
retry_max: 3
retry_backoff_base: 1.0
# 单表最大耗时(秒),0 无限制;5TB 建议 86400(1 天)
per_table_timeout: 86400
# 全局最大耗时(秒),0 无限制;5TB 建议 432000(5 天)
global_timeout: 432000
# 迁移规模预设:small/medium/large/huge
scale_preset: huge
2.4 可观测性
- 实时进度条:按表完成度计算百分比,显示
done/total计数; - 速率与 ETA:基于 EMA(指数移动平均)平滑显示 rows/s,根据已完成表数估算剩余时间;
- 逐表状态网格:pending / syncing(蓝色脉冲动画)/ done / error 四态可视化,显示行数、索引数、DDL 状态、校验 M/P 行数对比;
- 滚动日志:彩色分级(phase/data/table/ok/warn/err),自动滚动,最多保留 500 行;
- 不一致表列表:迁移完成后高亮显示 MySQL 与 PG 行数不一致的表;
- HTML 报告:一键打开迁移报告页面,含完整统计与错误详情。
2.5 命令行子命令
| 子命令 | 用途 |
|---|---|
fgmysql2pg -c config.yml |
执行转换(默认) |
fgmysql2pg convert -c config.yml |
同上 |
fgmysql2pg test -c config.yml |
仅测试连接,打印版本 |
fgmysql2pg assess -c config.yml |
迁移前评估,输出 HTML 报告 |
fgmysql2pg report -l conversion.log |
从日志生成 HTML 报告 |
fgmysql2pg web -c config.yml -p 8088 |
启动可视化控制台 |
fgmysql2pg -v / --version |
显示版本 |
2.6 Web 单页全功能界面
- 连接配置:MySQL 源库与 PostgreSQL 目标库的主机/端口/用户/密码/库;
- 转换选项:12 个开关(表结构/数据/索引/视图/函数/用户/权限/校验/清空/跳过/字段小写/表名小写/tinyint→BOOLEAN);
- 高级选项(折叠):白/黑名单表/视图/函数、批量插入大小、最大行数/批、带宽限制、MPP 模式、日志路径;
- 操作按钮:测试连接、迁移评估、开始转换、查看报告、保存配置、载入配置、开始迁移、停止迁移;
- 配置管理:
/api/config/save保存为 YAML,/api/config/load载入 YAML,支持反复复用。
2.7 控制脚本
项目根目录提供 webctl.py 脚本,用于管理 Web 控制台生命周期:
| 命令 | 用途 |
|---|---|
python3 webctl.py start [-c config.yml] [-H 0.0.0.0] [-p 8088] |
后台启动,写 PID 文件 |
python3 webctl.py stop |
停止(SIGTERM → 5s → SIGKILL → pkill 兜底) |
python3 webctl.py status [-p 8088] |
查看运行状态(PID、端口监听) |
python3 webctl.py restart [-c ...] [-H ...] [-p ...] |
重启(stop + start) |
三、支持环境
3.1 操作系统
| 平台 | 支持情况 |
|---|---|
| Linux(x86_64 / ARM64) | 完全支持,推荐生产环境部署 |
| macOS(Intel / Apple Silicon) | 完全支持,开发与测试环境 |
| Windows 10/11 + WSL2 | 完全支持,原生 Windows 需 psycopg2 编译环境 |
| Docker 容器 | 完全支持,推荐基于 python:3.9-slim 镜像 |
3.2 Python 环境
- Python 版本:3.8 / 3.9 / 3.10 / 3.11 / 3.12(推荐 3.9+)
- 关键依赖:
PyMySQL>=1.1.0(MySQL 驱动)psycopg2-binary>=2.9.9(PostgreSQL 驱动)PyYAML>=6.0(配置文件解析)Flask>=3.0.0(Web 控制台)python-docx>=1.0(仅生成 docx 报告时需要)
3.3 数据库版本
| 数据库 | 支持版本 |
|---|---|
| MySQL | 5.6 / 5.7 / 8.0 / 8.1+(推荐 5.7+,完整支持 utf8mb4 与 JSON 类型) |
| MariaDB | 10.3 / 10.5 / 10.6 / 10.11 / 11.x |
| PostgreSQL | 10 / 11 / 12 / 13 / 14 / 15 / 16(推荐 13+,支持 CREATE ROLE IF NOT EXISTS) |
| Greenplum | 6.x / 7.x(MPP 模式) |
| YugabyteDB | 2.x / 2024.x(MPP 模式) |
| openGauss / GaussDB / HighGo / Kingbase | 兼容 PG 协议,可用 |
3.4 浏览器要求(可视化)
- Chrome / Edge / Firefox / Safari 现代版本(支持 EventSource SSE 与 fetch)
- 屏幕分辨率 ≥ 1366×768(推荐 1920×1080)
3.5 网络与权限
- 迁移执行机需能同时访问 MySQL 与 PostgreSQL 端口;
- MySQL 账户需具备
SELECT、SHOW VIEW、TRIGGER、PROCESS(读取 mysql.user 表)等权限; - PostgreSQL 账户需具备
CREATE、INSERT、INDEX、USAGE等权限,迁移用户时需要CREATEROLE; - 防火墙需放行 MySQL 3306、PostgreSQL 5432 与 Web 控制台端口(默认 8088)。
四、程序使用
4.1 安装
# 1. 解压源码
cd FGMySQL2PG
# 2. 安装依赖
pip install -r requirements.txt
# 3.(可选)安装 docx 生成支持
pip install python-docx
4.2 配置文件
复制 config.example.yml 为 config.yml,按实际环境填写:
mysql:
host: 127.0.0.1
port: 3306
username: root
password: your_pwd
database: source_db
connection_params: charset=utf8mb4&interpolateParams=true&readTimeout=60s&writeTimeout=60s&timeout=30s
consistent_snapshot: false # 源库并发写入时建议开启
postgresql:
host: 127.0.0.1
port: 5432
username: postgres
password: your_pwd
database: target_db
pg_connection_params: search_path=public connect_timeout=300 statement_timeout=0
conversion:
options:
tableddl: true
data: true
indexes: true
view: true
functions: false
validate_data: true
lowercase_columns: true
skip_existing_tables: true
limits:
concurrency: 10
batch_insert_size: 50000
完整配置项参见源码根目录 config.example.yml。
4.3 命令行操作流程
4.3.1 测试连接
fgmysql2pg test -c config.yml
# 或
python -m fgmysql2pg test -c config.yml
输出 MySQL 与 PostgreSQL 版本号即表示连接正常。
4.3.2 迁移前评估
fgmysql2pg assess -c config.yml -o assess.html
生成 HTML 兼容性报告,列出可转换对象、风险点、函数映射覆盖率。
4.3.3 执行迁移
fgmysql2pg -c config.yml
# 或显式
fgmysql2pg convert -c config.yml
控制台实时打印进度,完成后输出统计汇总。
4.3.4 生成报告
fgmysql2pg report -l conversion.log -e errors.log -o report.html
从已有日志生成 HTML 报告,无需重新迁移。
4.3.5 启动可视化控制台
# 前台运行(Ctrl+C 退出)
fgmysql2pg web -c config.yml -H 0.0.0.0 -p 8088
# 后台运行(推荐用 webctl.py)
python3 webctl.py start -c config.yml -p 8088
python3 webctl.py status -p 8088
python3 webctl.py stop
python3 webctl.py restart -p 9090
4.4 可视化控制台操作流程
- 填写连接:在左侧"MySQL 源库"与"PostgreSQL 目标库"卡片填写主机/端口/用户/密码/库名;
- 测试连接:点击"测试连接"按钮,日志区域显示 MySQL 与 PG 版本,表示连通;
- 配置选项:勾选需要的转换项;如需白/黑名单或自定义批量大小,点击"显示高级选项"展开;
- 迁移评估(推荐):点击"迁移评估",生成兼容性评分报告,识别风险点;
- 开始转换:点击"开始转换"或右侧"开始迁移"按钮,状态徽章变为"运行中";
- 实时监控:进度条、速率 ETA、逐表网格、滚动日志实时刷新;
- 停止迁移(可选):点击"停止迁移",工具在当前批次完成后退出;
- 查看报告:迁移完成后点击"查看报告"打开 HTML 报告页;
- 保存配置:点击"保存配置"将当前界面设置写入 config.yml,下次"载入配置"即可复用。
4.5 REST API
控制台同时提供 REST API,便于集成到运维平台:
| 方法 | 路径 | 功能 |
|---|---|---|
| GET | / |
单页控制台 |
| GET | /api/status |
获取迁移状态快照 |
| GET | /api/progress |
SSE 实时事件流 |
| POST | /api/test |
测试 MySQL/PG 连接 |
| POST | /api/assess |
执行迁移评估 |
| GET | /api/assess/report |
获取评估 HTML 报告 |
| POST | /api/convert |
启动转换任务 |
| POST | /api/stop |
停止当前迁移 |
| GET | /api/report |
获取迁移 HTML 报告 |
| POST | /api/config/save |
保存配置为 YAML |
| GET | /api/config/load |
载入 YAML 配置 |
五、mysql迁移到postgresql案例场景与操作过程
5.1 场景一:mysql迁移到postgresql-中小业务库全量迁移(< 10GB)
背景:某电商系统 MySQL 5.7 业务库(约 8GB,120 张表,含 JSON 字段、视图、存储函数)迁移到 PostgreSQL 14。
命令行操作
# 1. 测试连接
fgmysql2pg test -c config.yml
# 2. 迁移评估
fgmysql2pg assess -c config.yml -o assess.html
# 3. 执行迁移
fgmysql2pg convert -c config.yml
# 4. 查看报告
fgmysql2pg report -l conversion.log -o report.html
可视化操作
- 启动控制台
python3 webctl.py start -p 8088; - 浏览器打开
http://127.0.0.1:8088; - 点击"测试连接"确认 MySQL 5.7 与 PostgreSQL 14 连通;
- 转换选项勾选:表结构、数据、索引、视图、数据校验;高级选项中"字段小写"勾选;
- 点击"迁移评估",确认评分 ≥ 80 分、无致命风险;
- 点击"开始转换",观察进度条与逐表网格;
- 迁移完成后,"不一致表"区域显示"无",点击"查看报告"归档。
预期耗时:8GB 数据约 10-15 分钟(取决于网络与磁盘 IO)。
5.2 场景二:mysql迁移到postgresql-大表无主键迁移(> 5000 万行)
背景:日志表 t_log 无主键,行数 6000 万,约 50GB。
工具自动策略:
- 识别无主键;
- 行数 > 200 万 → 切换"全列排序 OFFSET 分页"策略;
- 每批 50000 行,通过
ORDER BY col1,col2,... LIMIT 50000 OFFSET n稳定分页; - PG 端 COPY FROM STDIN 批量写入,失败自动回退 execute_values;
- 遇死锁自动重试 3 次(1s/2s/4s)。
命令行操作
# 编辑 config.yml,调低并发与批量大小
# conversion.limits.concurrency: 4
# conversion.limits.batch_insert_size: 20000
# conversion.options.consistent_snapshot: true
fgmysql2pg convert -c config.yml
可视化操作
- 高级选项中"批量插入大小"设为 20000;
- "并发数"调低为 4(避免大表 OFFSET 偏移过大造成源库压力);
- 启用"一致性快照"(若源库有持续写入);
- 启动迁移,逐表网格中观察
t_log状态从 pending → syncing(蓝色脉冲)→ done。
优化建议:在源表加自增列做伪主键 ALTER TABLE t_log ADD COLUMN id BIGINT AUTO_INCREMENT PRIMARY KEY,可让工具走键集分页,O(n)。
5.3 场景三:mysql迁移到postgresql-含 emoji 与 4 字节字符的迁移
背景:用户评论表 t_comment 含 emoji、中文生僻字、4 字节 Unicode。
工具保证:
- MySQL 端强制
charset=utf8mb4,即使源库默认 latin1 也会被覆盖; use_unicode=True让 PyMySQL 正确解码字符列;- PostgreSQL 端
client_encoding=UTF8,服务端默认 UTF8 存储; - BLOB/VARBINARY 列直接以 bytes 传输,不被错误 decode。
命令行操作
# config.yml 的 connection_params 中 charset 字段保持 utf8mb4(默认)
fgmysql2pg convert -c config.yml
# 迁移后抽检
psql -c "SELECT count(*) FROM t_comment WHERE content ~ '[^\x00-\xffff]'"
可视化操作
- 连接配置卡片确认 MySQL 端 charset 字段为 utf8mb4(默认值,不要改成 utf8mb3 或 latin1);
- 启动迁移;
- 完成后用 psql 抽检 4 字节字符是否完整。
5.4 场景四:mysql迁移到postgresql-视图与存储过程迁移
背景:业务库含 30 个视图与 5 个存储过程,使用 CONCAT_WS、JSON_EXTRACT、IF(...) 等 MySQL 特有函数。
工具自动转换示例:
| MySQL 原语句 | 转换后 PG 语句 |
|---|---|
SELECT CONCAT_WS(',', a, b, c) |
SELECT ARRAY_TO_STRING(ARRAY[a, b, c], ',') |
SELECT JSON_EXTRACT(doc, '$.user.name') |
SELECT (doc->'user'->'name') |
SELECT JSON_VALUE(doc, '$.age') |
SELECT (doc->>'age') |
SELECT IF(x>0, 'yes', 'no') |
SELECT (CASE WHEN x>0 THEN 'yes' ELSE 'no' END) |
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY) |
SELECT (NOW() + INTERVAL '1 DAY') |
SELECT GROUP_CONCAT(DISTINCT name ORDER BY id SEPARATOR ';') |
SELECT string_agg(DISTINCT (name)::text, ';' ORDER BY id) |
CREATE PROCEDURE p() BEGIN DECLARE i INT DEFAULT 0; WHILE i<10 DO SET i:=i+1; END WHILE; END |
CREATE FUNCTION p() RETURNS void LANGUAGE plpgsql AS $$ BEGIN DECLARE i INT := 0; WHILE i<10 LOOP i := i+1; END LOOP; END $$; |
命令行操作
# config.yml 启用视图与函数
# conversion.options.view: true
# conversion.options.functions: true
fgmysql2pg assess -c config.yml -o assess.html # 先评估风险
fgmysql2pg convert -c config.yml
可视化操作
- 转换选项中勾选"视图"与"函数";
- 点击"迁移评估",报告中列出无法自动转换的语法点,需人工复核;
- 复杂存储过程建议迁移后用 pgAdmin 打开校验语法;
- 启动迁移,完成后在 PG 端执行
\df+查看函数定义。
5.5 场景五:mysql迁移到postgresql-迁移到 Greenplum / YugabyteDB
背景:数据仓库迁移到 Greenplum 7。
命令行操作
# config.yml
conversion:
mpp:
enabled: true
database: greenplum
fgmysql2pg convert -c config.yml
可视化操作
- 高级选项"MPP 模式"选择
greenplum; - Greenplum 不支持
CREATE INDEX CONCURRENTLY,工具会自动降级为普通CREATE INDEX; - YugabyteDB 的
53M00临时不可用错误会被识别为可重试; - 大表建议先在 Greenplum 侧预分布键,再迁移数据。
5.6 场景六:mysql迁移到postgresql-分批次增量迁移
背景:业务不停机迁移,先迁历史数据,再迁增量。
命令行操作
# 第一次:全量迁移
fgmysql2pg convert -c config.yml
# 第二次:迁移增量(启用 truncate_before_sync)
# config.yml: conversion.options.truncate_before_sync: true
fgmysql2pg convert -c config.yml
可视化操作
- 第一次:勾选"表结构"与"数据",执行全量迁移;
- 第二次:勾选"数据"并启用"同步前清空",迁移增量数据;
- 最后切换应用写入 PG,完成迁移。
5.7 场景七:mysql迁移到postgresql-仅迁移部分表(白名单)
背景:业务库 200 张表,仅需迁移 30 张核心表。
命令行操作
# config.yml
conversion:
options:
use_table_list: true
table_list: [t_order, t_user, t_payment]
fgmysql2pg convert -c config.yml
可视化操作
- 高级选项"白名单表"填写
t_order,t_user,t_payment,...(逗号分隔); - 工具自动设置
use_table_list=true; - 评估报告中只显示白名单表;
- 其他表保持不变。
5.8 场景八:排查不一致表
背景:迁移完成后,"不一致表"区域显示 t_order MySQL=10000 PG=9998。
命令行排查
# 1. 查看日志中该表的校验记录
grep "t_order" conversion.log | grep -i "校验\|mismatch\|不一致"
# 2. 检查源表是否有触发器在迁移期间持续写入
mysql -e "SHOW TRIGGERS LIKE 't_order'"
# 3. 检查目标表是否有约束拒绝部分行
psql -c "\d t_order"
# 4. 重新执行该表迁移(白名单 + truncate)
# config.yml: conversion.options.table_list: [t_order], truncate_before_sync: true
fgmysql2pg convert -c config.yml
可视化排查
- 查看"滚动日志"中该表的
校验不一致行; - 检查源表是否有触发器在迁移期间持续写入;
- 检查目标表是否有约束(NOT NULL/CHECK)导致部分行被拒;
- 重新执行该表迁移:在白名单中只填该表,启用
truncate_before_sync; - 若仍不一致,启用
consistent_snapshot: true重试。
5.9 场景九:CI/CD 集成(无人值守)
背景:数据库变更自动化流水线,每日构建后自动同步 schema 到测试 PG。
# CI 脚本片段
pip install -r requirements.txt
cp config.example.yml config.yml
# 用环境变量覆盖连接信息
sed -i "s/root/$MYSQL_USER/" config.yml
sed -i "s/your_pwd/$MYSQL_PWD/" config.yml
# 1. 测试连接(失败则流水线中止)
fgmysql2pg test -c config.yml || exit 1
# 2. 仅迁移表结构(不迁数据)
# config.yml: conversion.options.data: false, tableddl: true
fgmysql2pg convert -c config.yml
# 3. 生成报告归档
fgmysql2pg report -l conversion.log -o report-$(date +%Y%m%d).html
5.10 场景十:可视化迁移报告归档
背景:迁移完成后需向团队归档迁移报告。
命令行
fgmysql2pg report -l conversion.log -e errors.log -o report-$(date +%Y%m%d).html
# 上传到 wiki / OSS / 内网归档
可视化
- 迁移完成后点击"查看报告"按钮,浏览器打开 HTML 报告;
- 报告包含:迁移统计、逐表状态、错误详情、函数映射覆盖率;
- 浏览器
Ctrl+S保存为本地 HTML 文件归档。
5.11 场景十一:mysql迁移到postgresql-100GB 级业务库迁移
背景:电商平台订单库,约 100GB,最大单表 2 亿行(t_order),含 emoji 评价字段,要求 4 小时内完成迁移。
容量评估:
- 总数据量 100GB,最大表 2 亿行 × 500B/行 ≈ 100GB;
- 内存峰值预估:4 表并发 × 4 队列 × 50000 行/批 × 500B ≈ 400MB,远低于 2GB 软限;
- 预估耗时:100GB ÷ 50MB/s(千兆网 + COPY)≈ 35 分钟,加上索引重建约 1.5 小时。
命令行操作
# config.yml(100GB 场景推荐配置)
conversion:
options:
consistent_snapshot: true # 一致性快照,避免并发写入丢行
truncate_before_sync: true # 重跑时清空目标表
lowercase_columns: true
limits:
concurrency: 8 # 8 表并行
batch_insert_size: 50000
streaming_cursor: true # 流式游标
queue_size: 4
memory_limit_mb: 1024 # 1GB 软限
memory_hard_limit_mb: 2048 # 2GB 硬限
large_table_threshold: 1000000
huge_table_threshold: 10000000
checkpoint_dir: "./.checkpoint"
scale_preset: large
# 1. 测试连接
fgmysql2pg test -c config.yml
# 2. 评估(识别大表与无主键表)
fgmysql2pg assess -c config.yml
# 3. 执行迁移(约 1.5 小时)
fgmysql2pg convert -c config.yml
# 4. 若中途断开,重启自动续传
fgmysql2pg convert -c config.yml
# 日志会显示: "检测到 N 张表有未完成检查点"
# 5. 生成报告
fgmysql2pg report -l conversion.log -o report-100g.html
可视化操作
- 浏览器打开控制台,"连接配置"填入 MySQL/PG 信息;
- "高级选项"中设置:并发 8、批大小 50000、内存上限 1024MB;
- 勾选"一致性快照"与"同步前清空";
- 点击"开始评估",识别
t_order为大表(行数 > 阈值); - 点击"开始迁移",进度条显示单表 ETA 与全局进度;
- 若中断重启,进度条会从断点继续,日志显示"断点续传 N 张表";
- 完成后点击"查看报告",确认行数一致。
5.12 场景十二:mysql迁移到postgresql-1TB 级核心库迁移
背景:银行核心交易库,1TB,最大单表 20 亿行(t_transaction),含 JSONB 字段,要求 48 小时内完成。
容量评估:
- 总数据量 1TB,最大表 20 亿行 × 500B/行 ≈ 1TB;
- 内存峰值预估:4 表并发 × 4 队列 × 50000 行/批 × 500B ≈ 400MB,硬限 4GB 足够;
- 预估耗时:1TB ÷ 30MB/s(长距离网络 + PG WAL)≈ 10 小时,加上索引与校验约 24 小时。
命令行操作
# config.yml(1TB 场景推荐配置)
conversion:
options:
consistent_snapshot: true
truncate_before_sync: false # 重跑时不清空(保留断点续传)
lowercase_columns: true
limits:
concurrency: 6 # 适度降并发,避免内存叠加
batch_insert_size: 50000
streaming_cursor: true
queue_size: 4
memory_limit_mb: 2048 # 2GB 软限
memory_hard_limit_mb: 4096 # 4GB 硬限
large_table_threshold: 1000000
huge_table_threshold: 10000000 # 1000 万行启用流式管道
checkpoint_dir: "./.checkpoint"
copy_chunk_size: 100000
retry_max: 5 # 增加重试次数应对长连接抖动
retry_backoff_base: 2.0
per_table_timeout: 86400 # 单表最长 1 天
global_timeout: 432000 # 全局最长 5 天
scale_preset: large
postgresql:
pg_connection_params: "statement_timeout=0 connect_timeout=60 idle_in_transaction_session_timeout=0"
# statement_timeout=0 禁用语句超时,允许大表 COPY 持续数小时
# 1. 测试连接(含 PG 参数验证)
fgmysql2pg test -c config.yml
# 2. 评估(识别 20 亿行大表)
fgmysql2pg assess -c config.yml
# 3. 后台执行迁移(nohup + 日志重定向,防止 SSH 断开)
nohup fgmysql2pg convert -c config.yml > conversion.log 2>&1 &
echo $! > conversion.pid
# 4. 监控进度(实时查看日志)
tail -f conversion.log
# 关键字段:rows_per_sec, eta_sec, rss_mb, pct
# 5. 若进程意外退出,重启自动续传
fgmysql2pg convert -c config.yml
# 日志: "检测到 3 张表有未完成检查点,从断点继续"
# 6. 完成后校验
fgmysql2pg report -l conversion.log -o report-1tb.html
可视化操作
- 用
webctl.py start启动控制台后台运行; - "连接配置"中填入 PG 参数
statement_timeout=0; - "高级选项"中设置:并发 6、批大小 50000、内存硬限 4096MB;
- 启用"断点续传"(检查点目录默认
./.checkpoint); - 点击"开始迁移",进度条显示单表 ETA(基于 5 批滑动均值);
- 中途若浏览器关闭,迁移进程在后台继续;
- 重新打开控制台,自动恢复进度显示;
- 若进程崩溃,重启控制台后点击"继续迁移",从断点恢复。
5.13 场景十三:mysql迁移到postgresql-5TB 级数据仓库迁移
背景:日志分析平台数据仓库,5TB,单表最大 50 亿行(t_event_log),无主键(日志追加表),要求 5 天内完成迁移。
容量评估:
- 总数据量 5TB,最大表 50 亿行 × 1KB/行 ≈ 5TB;
- 无主键表走全列排序 OFFSET 分页,O(n²) 但稳定;
- 内存峰值预估:4 表并发 × 4 队列 × 50000 行/批 × 1KB ≈ 800MB,硬限 4GB 足够;
- 预估耗时:5TB ÷ 15MB/s(无主键 OFFSET 较慢 + 长距离)≈ 100 小时,加上索引约 120 小时(5 天)。
命令行操作
# config.yml(5TB 场景推荐配置)
conversion:
options:
consistent_snapshot: true
truncate_before_sync: false
lowercase_columns: true
limits:
concurrency: 4 # 最低并发,避免内存叠加与源库压力
batch_insert_size: 20000 # 降批大小,降低单批内存峰值
streaming_cursor: true
queue_size: 4
memory_limit_mb: 2048
memory_hard_limit_mb: 4096 # 4GB 硬限
large_table_threshold: 1000000
huge_table_threshold: 10000000
checkpoint_dir: "/data/checkpoint" # 用独立磁盘,避免与迁移数据竞争 IO
copy_chunk_size: 50000
retry_max: 5
retry_backoff_base: 2.0
per_table_timeout: 259200 # 单表最长 3 天
global_timeout: 432000 # 全局最长 5 天
scale_preset: huge
mysql:
connection_params: "readTimeout=86400 writeTimeout=86400 timeout=60"
# readTimeout=86400(1 天)覆盖无主键大表 OFFSET 扫描
postgresql:
pg_connection_params: "statement_timeout=0 connect_timeout=120 idle_in_transaction_session_timeout=0"
# 1. 预创建无主键大表的目标表(可选,加速迁移)
psql -f pre_create_tables.sql
# 2. 评估(识别无主键大表,预估 OFFSET 扫描耗时)
fgmysql2pg assess -c config.yml
# 3. 后台执行迁移(用 screen/tmux 防止 SSH 断开)
screen -S migration
nohup fgmysql2pg convert -c config.yml > conversion.log 2>&1 &
echo $! > conversion.pid
# 4. 监控(关键指标)
tail -f conversion.log
# 关注:rss_mb(应稳定 < 4GB)、eta_sec、rows_per_sec
# 若 rss_mb 持续上涨,降低 concurrency 或 batch_insert_size
# 5. 监控检查点目录大小(应远小于数据量)
du -sh /data/checkpoint/
# 6. 若进程退出,重启续传(5TB 场景可能需多次续传)
fgmysql2pg convert -c config.yml
# 日志: "检测到 5 张表有未完成检查点,从断点继续"
# 已完成的表不会重跑(检查点已删除)
# 7. 完成后校验与报告
fgmysql2pg report -l conversion.log -o report-5tb.html
# 8. 清理检查点目录
rm -rf /data/checkpoint/
可视化操作
- 用
webctl.py start启动控制台; - "连接配置"中填入 MySQL
readTimeout=86400,PGstatement_timeout=0; - "高级选项"中设置:并发 4、批大小 20000、内存硬限 4096MB;
- 检查点目录设为
/data/checkpoint(独立磁盘); - 启用"一致性快照";
- 点击"开始迁移",5TB 场景预计耗时 5 天,进度条缓慢推进属正常;
- 每日检查控制台"内存使用"曲线,应稳定在 2-4GB;
- 若网络抖动导致连接断开,日志显示"重试中...",迁移自动恢复;
- 若进程崩溃,重启控制台后点击"继续迁移",从断点恢复;
- 完成后点击"查看报告",确认所有表行数一致。
5TB 场景注意事项
- 源库压力:
concurrency=4限制并发,避免源库被迁移进程拖垮; - 网络带宽:5TB 数据迁移需确保 MySQL→PG 间带宽 ≥ 100MB/s;
- PG WAL 空间:COPY 大量数据会产生大量 WAL,确保 PG
wal_keep_size足够或启用wal_compression=on; - 磁盘空间:PG 数据目录需预留 6TB+ 空间(5TB 数据 + 索引);
- 检查点目录:用独立磁盘,避免与迁移数据竞争 IO;
- 断点续传:5TB 场景几乎必须启用,避免中断后重头再来;
- 无主键大表:50 亿行 OFFSET 扫描较慢,考虑为源表添加自增列作为临时主键加速分页;
- 监控指标:重点监控
rss_mb(内存)、eta_sec(剩余时间)、rows_per_sec(吞吐速率)。
六、常用问题与排查
6.1 启动问题
| 现象 | 原因 | 解决 |
|---|---|---|
ModuleNotFoundError: No module named 'flask' |
未安装依赖 | pip install -r requirements.txt |
Permission denied: bind 0.0.0.0:8088 |
端口被占用或无权限 | 改用 -p 18088 或非特权端口 |
psycopg2-binary 编译失败 |
系统缺 libpq | apt install libpq-dev 后重装,或用 conda |
| 控制台打开空白 | 浏览器禁用 JS 或 SSE | 启用 JS;轮询兜底会自动接管 |
webctl.py stop 无效 |
PID namespace 隔离 | 真实 Linux 服务器 PID 真实可正常 stop;沙箱环境用 pkill -f "fgmysql2pg web" 兜底 |
6.2 连接问题
| 现象 | 排查 |
|---|---|
MySQL 连接失败: Access denied |
检查用户名密码;MySQL 8.0 默认 caching_sha2,PyMySQL 1.1+ 已支持 |
PostgreSQL 连接失败: password authentication failed |
检查 pg_hba.conf 是否允许 md5/scram-sha-256 |
MySQL 连接失败: Lost connection |
检查 max_open_conns 与 MySQL max_connections;降低 concurrency |
| 连接超时 | 检查防火墙;config.yml 调大 connect_timeout |
FATAL: too many connections |
PG max_connections 不足;降低 max_conns |
6.3 数据迁移问题
| 现象 | 原因 | 解决 |
|---|---|---|
| 中文乱码 | 源库实际编码非 utf8mb4 | 工具已强制 utf8mb4;若仍乱码,检查源表 CHARACTER SET 是否 latin1,需先 ALTER TABLE CONVERT TO CHARACTER SET utf8mb4 |
| emoji 丢失 | 源列是 utf8(3字节) | ALTER TABLE t MODIFY col TEXT CHARACTER SET utf8mb4 |
| 进度卡在 95% | 前端节流丢弃最后状态 | 已修复(合并模式);刷新页面或点击"查看报告" |
| 大表 OFFSET 越来越慢 | 无主键 + OFFSET 天然 O(n²) | 工具已自动切全列排序分页;可加自增列做伪主键 |
COPY failed: invalid byte sequence |
字符列含非法字节 | 工具自动回退 execute_values;如仍失败,检查源列 charset |
deadlock detected |
并发写冲突 | 工具自动重试 3 次;降低 concurrency |
statement_timeout 中止 |
单批次超过 0 或配置值 | config.yml 调大 pg_connection_params 中的 statement_timeout |
lock_timeout 中止 |
等锁超时 | 调大 lock_timeout 或降低并发 |
| 行数不一致 | 源库并发写入 / 目标表约束拒行 | 启用 consistent_snapshot: true;检查目标表 NOT NULL/CHECK |
6.4 对象迁移问题
| 现象 | 解决 |
|---|---|
| 视图转换失败 | 查看日志中具体 SQL;复杂视图建议人工改写 |
| 存储过程语法错误 | PG 与 MySQL 语法差异大;工具处理常见模式,复杂逻辑需人工复核 |
函数 RETURNS int(11) 报错 |
工具自动剥长度,若仍失败检查 native.type_map |
| 索引创建失败 | 检查目标表是否已存在同名索引;启用 truncate_before_sync |
CREATE ROLE 失败:已存在 |
PG 13+ 支持 IF NOT EXISTS;老版本工具用 try/except 自动跳过 |
6.5 性能问题
| 现象 | 优化 |
|---|---|
| 迁移速度慢 | 提高 concurrency;加大 batch_insert_size;确保 PG 端用 COPY |
| 源库 CPU 飙高 | 降低 concurrency;启用 consistent_snapshot 减少锁竞争 |
| PG 端 WAL 暴涨 | 迁移前关闭 synchronous_commit;分批 TRUNCATE + INSERT |
| 大表 OFFSET 慢 | 加伪主键(ALTER TABLE t ADD COLUMN id BIGINT AUTO_INCREMENT PRIMARY KEY) |
pg_connection_params 不生效 |
检查参数名是否在白名单内(statement_timeout/search_path/lock_timeout 等) |
6.5.1 大数据量迁移问题排查(100GB - 5TB)
| 现象 | 原因 | 解决 |
|---|---|---|
| 进程被 OOM Killer 杀死 | memory_hard_limit_mb 设得太低或并发过高 |
升至 4096+;concurrency 降至 4;检查 rss_mb 监控曲线 |
| 迁移中途连接断开 | MySQL wait_timeout 或网络中间设备超时 |
设 readTimeout=86400;启用 TCP keepalive(默认已开) |
| 检查点目录膨胀 | 大量表未完成就退出 | 检查点文件每表仅几 KB,膨胀说明表数极多;正常现象 |
| 重启后未续传 | checkpoint_dir 为空或被删除 |
配置 checkpoint_dir: "./.checkpoint";勿手动删除 |
| 重启后重复迁移已完成的表 | 检查点文件被删除 | 检查点文件在表完成后自动删除,误删会导致重跑 |
queue full timeout |
消费者僵死(PG 卡死或网络断) | 检查 PG 状态与网络;降低 queue_size 减少堆积 |
rows_per_sec 极低 |
无主键大表 OFFSET 扫描慢 | 为源表加临时自增主键;或接受 O(n²) 耗时 |
rss_mb 持续上涨 |
队列堆积或 GC 不及时 | 降 concurrency/batch_insert_size;重启迁移续传 |
单表耗时超 per_table_timeout |
大表数据量预估不足 | 调高 per_table_timeout 或设为 0(无限制) |
| 5TB 场景进度极慢 | 网络带宽不足或源库 IO 瓶颈 | 确保带宽 ≥ 100MB/s;源库用 SSD;降 concurrency 减压 |
PG disk full |
WAL 或数据膨胀 | 启用 wal_compression=on;扩容 PG 数据盘 |
| 迁移后行数不一致 | 中途源库有写入 | 启用 consistent_snapshot;或迁移后二次增量同步 |
| 断点续传位置错误 | 主键非单调(如 UUID) | 用自增主键;UUID 主键无法键集分页,回退 OFFSET |
6.6 日志与报告
- 转换日志:默认
./conversion.log,记录每张表的 DDL 状态、行数、索引数、错误; - 错误日志:默认
./errors.log,仅记录失败事件; - HTML 报告:通过"查看报告"按钮打开,包含统计汇总与错误详情;
- 评估报告:通过"迁移评估"生成,包含兼容性评分、风险等级、风险项列表;
- Web 日志:
fgmysql2pg.web.log,记录 Flask 服务启动与运行时输出; - 检查点文件:
./.checkpoint/{schema}.{table}.json,记录断点续传状态,迁移完成后自动删除。
6.7 调试技巧
- 启动时加
FGDEBUG=1环境变量,Flask 进入调试模式,异常栈完整打印; - 用
fgmysql2pg test -c config.yml单独验证连接; - 用
fgmysql2pg assess -c config.yml单独跑评估; - SSE 流断开时,前端会自动切换为 1 秒轮询,不影响进度;
- 服务异常退出后,
/api/status仍可读取最后一次快照; - 查看
fgmysql2pg.web.log排查 Web 服务异常; - 用
python3 webctl.py status检查后台服务状态。
七、附录
7.1 配置文件完整示例
参见源码根目录 config.example.yml。
7.2 函数映射速查(部分)
| MySQL | PostgreSQL |
|---|---|
IFNULL(a,b) |
COALESCE(a,b) |
NOW() |
CURRENT_TIMESTAMP |
CURDATE() |
CURRENT_DATE |
UNIX_TIMESTAMP() |
extract(epoch from now()) |
DATE_FORMAT(d,fmt) |
TO_CHAR(d,fmt) |
STR_TO_DATE(s,fmt) |
TO_TIMESTAMP(s,fmt) |
FIND_IN_SET |
array_position(string_to_array(...)) |
FIELD |
CASE |
GROUP_CONCAT |
string_agg |
CONCAT_WS |
ARRAY_TO_STRING(ARRAY[...]) |
JSON_OBJECT |
json_build_object |
JSON_ARRAY |
json_build_array |
JSON_EXTRACT(doc,'$.k') |
(doc->'k') |
JSON_VALUE(doc,'$.k') |
(doc->>'k') |
REGEXP_LIKE |
~ |
IF(c,a,b) |
CASE WHEN c THEN a ELSE b END |
INSERT(str,pos,len,new) |
overlay(str placing new from pos for len) |
SUBSTRING_INDEX |
split_part |
QUOTE |
quote_literal |
STD/STDDEV |
stddev_samp |
VARIANCE |
var_samp |
LAST_INSERT_ID() |
lastval() |
SCHEMA() |
current_schema() |
MATCH(col) AGAINST(q) |
to_tsvector(col) @@ to_tsquery(q) |
7.3 数据类型映射速查
| MySQL | PostgreSQL |
|---|---|
TINYINT(1) |
BOOLEAN 或 SMALLINT(配置项 tinyint1_as_boolean) |
TINYINT |
SMALLINT |
SMALLINT |
SMALLINT |
INT / MEDIUMINT |
INTEGER |
BIGINT |
BIGINT |
SMALLINT UNSIGNED |
INTEGER(升档) |
INT UNSIGNED |
BIGINT(升档) |
BIGINT UNSIGNED |
NUMERIC(20,0)(升档) |
DECIMAL(p,s) / NUMERIC |
DECIMAL(p,s) / NUMERIC |
FLOAT |
REAL |
DOUBLE |
DOUBLE PRECISION |
BIT(n) |
BIT(n)(保留长度) |
CHAR(n) |
CHAR(n) |
VARCHAR(n) |
VARCHAR(n) |
TEXT / LONGTEXT / MEDIUMTEXT / TINYTEXT |
TEXT |
BLOB / LONGBLOB / MEDIUMBLOB / TINYBLOB |
BYTEA |
BINARY / VARBINARY |
BYTEA |
DATE |
DATE |
TIME |
TIME |
DATETIME |
TIMESTAMP |
TIMESTAMP |
TIMESTAMPTZ |
YEAR |
SMALLINT |
JSON |
JSONB |
ENUM |
TEXT(PG enum 需手动维护值域) |
SET |
TEXT |
BOOLEAN / BOOL |
BOOLEAN |
UUID |
UUID |
POINT / LINE / POLYGON / GEOMETRY / MULTIPOINT |
同名 PostGIS 类型 |

浙公网安备 33010602011771号