如何使用pgloader将MySQL数据迁移到PostgreSQL?

来源:3D模型作者:南京GEO公司头衔:草根站长
导读:本期聚焦于南京GEO公司创作的《如何使用pgloader将MySQL数据迁移到PostgreSQL?》,敬请观看详情。想把线上运行的MySQL数据库整体迁到PostgreSQL,又不想手动导出导入、逐个调整字段类型和重写建表语句,pgloader是一个非常实用的命令行工具。它内置了MySQL到PostgreSQL的类型映射和转换规则,能自动处理整数类型、布尔标记、自增主键以及日期时间等常见差异,并支持在迁移时重建索引、外键和约束。本文以实际项目迁移为背景,介绍pgloader的安装方式、配置文件编写、批量迁移命令以及性能调优方法,同时分析迁移过程中容易遇到的权限、字符集和数据结构冲突,帮助读者用一条命令完成从MySQL到PostgreSQL的平滑切换。即使迁移对象数据量较大,也可以通过调整并发参数和批次大小来控制迁移速度与稳定性。

数据库迁移中,从MySQL切换到PostgreSQL往往需要处理字段类型映射、自增主键转换、默认值差异以及索引命名保留等细节。pgloader是一个开源的数据迁移工具,它把这些重复劳动抽象成配置和命令,能够从一个连接读取MySQL表结构,自动在PostgreSQL侧创建对应的表、序列、约束和索引,并按照一定批次写入数据。

如何使用pgloader将MySQL数据迁移到PostgreSQL?

本文将从安装部署、配置语法、类型转换、性能调优和排障几个方面展开,帮助你快速完成MySQL到PostgreSQL的迁移。

一、pgloader的安装与基础能力

pgloader最初是Python写的,后来用Common Lisp重写,支持从MySQL、SQLite、CSV、SQL Server等数据源向PostgreSQL迁移。它内置针对MySQL的类型映射,例如tinyint(1)自动识别为boolean,int auto_increment转为serial或identity,datetime保持时间精度等。安装方式比较简单,在Debian或Ubuntu上可以使用apt安装,macOS可以通过Homebrew安装,也可以下载官方编译好的二进制文件。需要说明的是,pgloader是一个命令行工具,迁移过程的配置通过一个专门的DSL文件来描述,不使用SQL转储脚本。

# Debian / Ubuntu
sudo apt update
sudo apt install pgloader

# macOS
brew install pgloader

# 检查版本
pgloader --version

安装完成后,建议先检查pgloader能不能同时连通MySQL和PostgreSQL。MySQL用户需要SELECT、SHOW VIEW、TRIGGER等权限,PostgreSQL用户需要建库建表权限。如果两个数据库不在同一台机器,注意网络策略和防火墙。pgloader在命令行执行时会显示迁移进度和每个表的处理情况,初次使用时可以先在一个小库上验证流程。

二、编写迁移配置文件

pgloader使用.load文件描述迁移规则,核心命令是load database from源连接into目标连接,并使用with子句控制迁移行为。下面给出一个最小配置示例:

LOAD DATABASE
     FROM mysql://migrator:mysql密码@127.0.0.1:3306/source_db
     INTO postgresql://migrator:pg密码@127.0.0.1:5432/target_db
WITH
     batch size = 25000,
     batch concurrency = 4,
     prefetch rows = 10000,
     create tables = true,
     create indexes = true,
     drop tables = true,
     truncate = true,
     reset sequences = true,
     only tables = ('users', 'orders', 'products');

这段配置中,batch size控制每个事务插入的行数;batch concurrency指定并发写入连接数;prefetch rows表示从MySQL读取时预取的行数;create tables为true时自动在PostgreSQL中建表;drop tables会在迁移前删除目标库同名表;truncate用于清空已有数据;reset sequences则会在导入完成后将自增序列更新到当前最大值。only tables可以限定只迁移指定的表,避免全库处理。

执行时运行pgloader 配置.load即可,也可以加--dry-run做试运行,只打印计划而不真正写数据。想要观察详细日志,可以使用--verbose参数。

pgloader migration.load
# 仅检查不执行
pgloader --dry-run migration.load
# 输出详细日志
pgloader --verbose migration.load

配置文件中的连接串如果包含特殊字符,建议使用URL编码。MySQL连接串格式为mysql://user:password@host:port/dbname,PostgreSQL为postgresql://user:password@host:port/dbname。实际项目里建议使用专用迁移账号,不要把生产数据库的超级用户直接写在配置文件中,尤其是配置文件需要提交到版本库时更要注意安全。

三、类型映射与数据转换

pgloader默认的MySQL类型转换规则比较实用。常见的映射包括:tinyint(1)转为boolean,smallint转为smallint,int转为integer,bigint转为bigint,varchar转为text或varchar,datetime转为timestamptz,text转为text,blob转为bytea。auto_increment列会转为PostgreSQL的serial或identity,并自动创建序列。如果不想完全依靠默认规则,可以在配置中使用CAST子句自定义列类型转换。

LOAD DATABASE
     FROM mysql://migrator:mysql密码@127.0.0.1:3306/source_db
     INTO postgresql://migrator:pg密码@127.0.0.1:5432/target_db
WITH
     keep not null = true,
     cast type datetime to timestamptz drop default drop not null using zero-dates-to-null,
     cast type tinyint to boolean using tinyint-to-boolean;

上面的配置里,cast type datetime to timestamptz使用了zero-dates-to-null,把MySQL中的0000-00-00 00:00:00转换为NULL,避免PostgreSQL无法存储这样的日期值。tinyint转boolean可以避免所有tinyint列都被当作smallint处理。keep not null表示保留原字段的非空约束,这类细节在迁移后直接影响应用写入逻辑。

对于字段名大小写和保留字问题,pgloader会自动在PostgreSQL中使用小写表名和列名,并对与PostgreSQL关键字冲突的列名加双引号。也可以在配置中设置preserve index names保留索引名称,或者使用materialize views将视图物化。如果迁移后发现某些列类型不符合预期,完全可以修改CAST规则后重新执行pgloader,目标表会被重新创建并导入数据。

CAST type date to date drop default drop not null using zero-dates-to-null

自定义类型转换是pgloader很灵活的地方,通过组合drop default、drop not null和using转换函数,能够处理大多数MySQL历史数据中的脏值。对于更复杂的清洗需求,也可以先在MySQL侧通过临时表整理数据,再让pgloader负责传输和建结构。

四、性能调优与迁移实战

迁移大表时,默认参数可能不是最优。pgloader的写入性能受batch size、batch concurrency和prefetch rows影响。batch size过大可能导致单个事务时间过长,过小则提交频繁;batch concurrency过高会占用数据库连接和内存。一般建议从batch size=25000、concurrency=4开始,根据服务器配置调整。如果PostgreSQL使用了高性能磁盘,可以适当提高concurrency到8;如果MySQL从库压力大,则降低prefetch rows。

WITH
     batch size = 50000,
     batch concurrency = 8,
     prefetch rows = 20000,
     workers = 8

实战迁移建议先在测试库完整跑一遍,观察数据量和迁移时间。正式迁移前备份目标库,确认应用已经停止写入MySQL,或者使用只读账号避免迁移过程中数据变化。pgloader迁移过程默认先建表,再并行读取和写入数据,最后创建索引和外键。如果迁移完成后再建索引,可以减少插入过程中索引维护开销,可以设置create indexes = false,迁移完成后手动建索引:

-- 迁移完成后手动创建索引
CREATE INDEX idx_orders_user_id ON orders(user_id);
ALTER TABLE orders ADD CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users(id);

如果数据量非常大,还可以拆分多张表迁移,或者使用pgloader的parallel能力同时处理不同表。pgloader会自行调度不同表的读取和写入,但不同表之间不会相互锁等待,只有外键依赖需要在同一批次中处理。对于超大表,建议先迁基础数据,再单独处理大字段或历史归档表。

五、常见问题与排障

迁移过程中最常见的问题是权限不足。MySQL账号需要至少SELECT、SHOW VIEW、TRIGGER,PostgreSQL账号需要对目标数据库有CREATE、TEMP权限。如果出现连接超时,检查防火墙和数据库监听地址。MySQL的lower_case_table_names设置可能导致表名大小写不一致,pgloader会以MySQL返回的表名为准,需要提前确认。

字符集问题也可能导致迁移失败,尤其是表中有utf8mb4内容和旧版本MySQL默认latin1时。建议在MySQL连接串中明确指定字符集,或者在MySQL配置文件里统一设置default-character-set = utf8mb4。PostgreSQL侧一般使用UTF8编码,如果目标库不是UTF8,需要先重建目标库。

# 排查迁移日志中的具体错误
pgloader --verbose --logfile /tmp/pgloader.log migration.load
tail -f /tmp/pgloader.log

如果迁移失败在某个表,可以查看日志中Table name等信息,定位到具体类型的转换错误。常见的还有MySQL自增主键已经手动插入0值导致PostgreSQL主键冲突,这类数据需要在迁移前清理或修正。pgloader不会自动修复业务数据中的逻辑错误,它只负责结构和数据搬运。

对于视图、存储过程、触发器等数据库对象,pgloader默认不会迁移存储过程和触发器,主要迁移表和视图。存储过程语法差异较大,需要人工改写为PL/pgSQL。触发器也需要重新创建。这一点在迁移规划时要提前考虑到,避免切换后才发现核心业务逻辑缺失。

pgloader让MySQL到PostgreSQL的迁移不再是手工脚本堆叠,通过一个配置文件即可完成结构转换、数据复制和约束重建。对于大多数中小型应用,掌握上述配置和调优方法已经足够顺利切换。大型系统还需要配合增量同步和双写方案,但pgloader仍然是全量迁移阶段的高效起点。

pgloaderMySQL迁移PostgreSQL修改时间:2026-08-27 19:08:10

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。