上周和一个做 DBA 的朋友吃饭,他正为数据库迁移头疼得不行。公司要从 Oracle 换到 PostgreSQL,几千张表、上百个存储过程,光靠手工写脚本,估计要干到明年。他试了市面上几款工具,要么报错,要么性能拉胯,问我有没有靠谱的推荐。我给他列了几个,并顺便整理了一下自己的经验。

其实数据库迁移这事儿,说简单也简单,说复杂就真能把人折腾疯。尤其是从 Oracle、MySQL 这些商业或开源数据库迁往 PostgreSQL 的场景,已经越来越常见。PostgreSQL 这几年火得不行,原因无非是开源免费、扩展性强、支持复杂查询和地理空间数据,很多企业为了降本增效,选择从 Oracle 这种“贵族”数据库迁移过来。但迁移不是复制粘贴,数据类型、函数、存储过程、权限管理都有差异。比如 Oracle 的 NUMBER 类型和 PostgreSQL 的 NUMERIC 类型看似一样,实际处理细节不同;Oracle 的序列和 PostgreSQL 的序列机制也不一样;更别提那些自定义函数,Oracle 里写的存储过程搬过来可能直接报错。
市面上主流的 PostgreSQL 迁移工具大致可以分为几类。一类是商业工具,比如 AWS 的 DMS(Database Migration Service)和阿里云的 DTS,这些工具功能强大,支持在线迁移、增量同步,还能自动转换部分数据类型。但问题是,它们往往和自家云平台深度绑定,如果你用的是本地部署或私有云,使用起来就不太顺手。而且商业工具收费不菲,小公司或个人开发者可能承受不起。另一类是开源工具,如 pgloader、ora2pg、pgdump/pgrestore 等,免费但需要一定的技术功底去配置和调试。还有一类是社区维护的脚本集合,比如 mysql2pgsql,适合简单场景。
我重点说说 pgloader,这是我最常用的一个。它支持从 MySQL、SQLite、MS SQL Server 等数据库迁移到 PostgreSQL,语法简单,一行命令就能跑起来。比如想把整个 MySQL 数据库迁过去,只需要写一个 .load 文件,指定源库和目标库的连接信息,然后执行 pgloader 命令。它会自动处理数据类型映射、索引、外键、序列等。我曾迁移一个 100 GB 的 MySQL 库,约 3 小时就完成了,中间只报了几个小错误,基本都是因为 MySQL 使用了 PostgreSQL 不支持的字符集,改一下配置文件就解决了。pgloader 的缺点是不支持 Oracle,如果要从 Oracle 迁移,只能考虑其他工具。
说到 Oracle 到 PostgreSQL 的迁移,ora2pg 是绕不开的选择。它是用 Perl 编写的开源工具,功能非常全面。它能分析 Oracle 数据库的结构,生成迁移报告,告诉你哪些对象可以自动转换,哪些需要手动处理。比如它会列出所有表、索引、视图、存储过程、触发器等,然后逐个检查兼容性。我有个客户从 Oracle 11g 迁移到 PostgreSQL 12,使用 ora2pg 处理了约 200 张表,自动转换率超过 90%。剩下的 10% 主要是存储过程里的 PL/SQL 代码,Oracle 的 PL/SQL 与 PostgreSQL 的 PL/pgSQL 语法差异较大,需要手动改写。但 ora2pg 会给出详细的错误日志和改写建议,比自己对着文档逐行修改要快得多。
如果追求零停机迁移,就要考虑在线迁移工具。AWS DMS 在这方面做得不错,支持全量+增量迁移,源库可以一直写,目标库同步更新。比如从 MySQL 迁到 PostgreSQL,先做一次全量快照,然后持续捕获 binlog 的变化,直到两边数据完全一致,再切换应用。整个过程业务基本无感知。但 DMS 的配置比较复杂,需要设置源端点、目标端点、任务类型、映射规则,还要处理网络和权限问题。我见过一个团队为配置 DMS 折腾了整整一周,最后发现是防火墙策略没有放开。另外,DMS 在数据校验和异常处理上也有短板,某些数据类型转换错误它不会主动报错,而是默默跳过,导致数据丢失。
社区里还有一些小众但好用的工具,比如 pgdump/pgrestore 这对组合。它们不是专门的迁移工具,而是 PostgreSQL 自带的备份恢复工具。如果要从其他数据库迁到 PostgreSQL,可以先在源库导出成通用格式(如 CSV),再用 pgdump 导入。这种方法适合数据量不大、结构简单的场景。比如有个 MySQL 库只有十几张表,数据量几 GB,先用 mysqldump 导出 SQL 文件,手动调整语法后,用 psql 导入 PostgreSQL。虽然有点笨,但可控,不会出现工具自作聪明导致的奇怪问题。我有个朋友就用这种方式,把公司的一个旧系统从 SQLite 迁到了 PostgreSQL,两天就搞定了。
选工具还得看团队的技术栈。如果团队对 Python 熟悉,可以试试 pgcopydb,这是一个用 Python 编写的迁移工具,支持并行迁移、增量复制。它的设计理念是“像 cp 命令一样简单”,但实际使用时仍有一定门槛,需要安装 PostgreSQL 的扩展插件并配置源库的复制槽。如果你对 Docker 熟悉,可以用 docker‑compose 搭建迁移环境,把源库和目标库都跑在容器里,然后用工具迁移。这样环境隔离,不会污染生产环境。我有个项目就是先在 Docker 中跑了一个 Oracle 测试实例,再用 ora2pg 迁移到 PostgreSQL 的容器里,验证通过后再上线生产。
说几句实在的。数据库迁移不是一次性买卖,要把它当成一个持续优化的过程。迁移完成后一定要做数据校验。可以写脚本,对比源库和目标库的行数、校验和、关键字段的值。比如用 pgAdmin 自带的查询功能,或者写个 Python 脚本,用 pymysql 和 psycopg2 分别连接两个库,逐表检查。另外,迁移后的性能调优也很重要。PostgreSQL 的索引策略、查询计划器、配置参数与 Oracle、MySQL 都不同,可能需要调整 workmem、shared_buffers 等参数。我见过一个案例,迁移后查询慢得像蜗牛,后来发现是没有创建合适的索引,补上后速度提升了十倍。所以别以为迁移完就万事大吉,后续的监控和优化才是真正的考验。


