一条命令完成 PostgreSQL 数据迁移:pgloader 从零到一的实战指南

发布时间:2026/8/17 19:16:46
一条命令完成 PostgreSQL 数据迁移:pgloader 从零到一的实战指南 一条命令完成 PostgreSQL 数据迁移pgloader 从零到一的实战指南【免费下载链接】pgloaderMigrate to PostgreSQL in a single command!项目地址: https://gitcode.com/gh_mirrors/pg/pgloader你有没有遇到过这样的场景公司决定从 MySQL 迁到 PostgreSQL表结构、索引、外键、几十万行数据全部要手工搬。你打开 psql一条条CREATE TABLE照着抄再用\copy导数据结果第 371 行一条非法日期就让整个导入报废。这是很多 DBA 都经历过的噩梦。pgloader 就是为这个场景而生的 PostgreSQL 数据加载工具。它靠一条命令就能完成从 MySQL、SQLite、SQL Server、CSV、DBF、IXF 等多种数据源到 PostgreSQL 的迁移更关键的是——它自带智能错误隔离机制坏数据会被挑出来单独记进日志好数据继续入库整个迁移不会因为一行脏数据就崩盘。本文会带你从安装开始完整跑通一次真实迁移再讲透配置文件、常见报错和性能调优。第一章 为什么是它被脏数据支配的恐惧先说说最扎心的痛点。PostgreSQL 的COPY命令走的是事务语义只要输入数据里有一行出错整个表的数据全部回滚。设想你导一个 100 万行的 CSV跑到第 80 万行遇到一个格式不对的日期前面 80 万行全部白干。你改完错误再来一遍又卡在下一行脏数据上。pgloader 彻底改写了这个剧本它的设计哲学是有错先记下来别挡住大部队。底层它把数据切成 25000 行一个的批次batch用 COPY 协议流式灌入一旦 PostgreSQL 拒绝某个批次它就从错误消息里解析出问题行号把好行重新发一遍、坏行写进独立的reject.dat文件然后继续往后加载。关注点传统 COPY / \copy用 pgloader 的收获错误处理一行出错全表回滚坏行隔离到 reject 文件好行继续加载数据源只认 CSV 文本MySQL/SQLite/MSSQL/CSV/DBF/IXF/归档/HTTP 全支持库结构迁移手写 DDL逐表抄自动发现表、索引、外键、注释、序列数据类型手工预处理内置 CAST 规则零日期自动转 NULL重复执行每次都要手工清理默认 DROPCREATE可重复跑直到通过别忘了它还有一个杀手锏它可以连数据库本身一起迁。所谓 single command 不是只迁数据而是 schema表结构、索引、外键、注释和数据一锅端。这背后是它先去源库翻目录catalog拿到全部结构定义做类型映射后再开始搬数。第二章 动手前准备环境要求与安装清单pgloader 目前有两个版本线请按你的情况选。版本说明v4推荐基于 Clojure/JVM 的完整重写发布为单个 JAR 文件要求 Java 21 或更高版本。无原生依赖、无共享库大迁移时内存溢出问题通过 JVM 堆参数-Xmx解决。v3Common Lisp 老版本Debian/Ubuntu 自带apt-get install pgloader即可安装。✅ 版本兼容提示v4 完全兼容 v3 的.load命令文件语法和命令行参数旧配置文件可以直接拿来用。安装清单方式一下载 v4 预编译 JAR推荐两步搞定# 1. 下载 JAR官方发布页始终指向最新构建 curl -L -o pgloader.jar https://github.com/dimitri/pgloader/releases/download/v4-dev/pgloader.jar # 2. 验证版本 java -jar pgloader.jar --version如果你想全局使用pgloader命令可以加一个包装脚本sudo install -m 755 pgloader.jar /usr/local/lib/pgloader.jar echo #!/bin/sh\nexec java -jar /usr/local/lib/pgloader.jar $ | sudo tee /usr/local/bin/pgloader sudo chmod 755 /usr/local/bin/pgloader pgloader --version方式二Docker 一行跑起来docker pull ghcr.io/dimitri/pgloader:latest docker run --rm -it ghcr.io/dimitri/pgloader:latest pgloader --version方式三Debian/Ubuntu 用 v3 系统包sudo apt-get install pgloader方式四从源码编译所有发行版通用git clone https://gitcode.com/gh_mirrors/pg/pgloader cd pgloader make ./build/bin/pgloader --help # 产物在这里动手前自查清单✅ 本地能连上目标 PostgreSQLcreatedb、psql可用✅ 源数据所在路径有读权限从数据库迁移时源库账号有读权限⚠️ 确认目标库已创建或确认include drop, create tables等选项生效⚠️ 大文件迁移前先看一眼磁盘剩余空间reject 文件会占额外空间✅ 跑任何命令前先执行pgloader --help看当前版本的参数列表第三章 一次完整的实战把 SQLite 库搬进 PostgreSQL我们选 SQLite 作为第一个实战因为它是零前置配置的最好示范——不需要账号密码一个.db文件就是整个数据库。这也是 pgloader 文档里的官方入门案例。第一步创建目标数据库createdb newdb这一步在做什么pgloader 负责建表、建索引、导数据但数据库本身这个壳得先存在。就像搬家箱子 pgloader 帮你打包但新房子门要先开。第二步一条命令完成全部迁移pgloader ./test/sqlite/sqlite.db postgresql:///newdb是的就这么一行。pgloader 会依次做四件事打开 SQLite 文件通过它的系统目录自动发现所有表定义把 SQLite 的数据类型映射成 PostgreSQL 类型CAST 规则在 PostgreSQL 里建表、建索引、建外键用 COPY 协议批量灌入数据注意目标连接串postgresql:///newdb——三个斜杠代表本地默认端口 默认用户 数据库 newdb这是简写完整写法是postgresql://user:passlocalhost:5432/newdb。第三步MySQL 迁移也一个套路如果源是 MySQL逻辑完全一样只是把连接串换成 MySQL 的createdb pagila pgloader mysql://userlocalhost/sakila postgresql:///pagilapgloader 会自动发现 sakila 库里的表、索引、外键、注释全部翻译成 PostgreSQL 版本然后并行搬数据。第四步看看迁移到底干了啥想确认配置没写错、连接能通、又不真想动数据用干跑模式pgloader --dry-run my-migration.load想把过程记成日志、把结果汇成报告加两个参数pgloader --verbose --logfile migration.log --summary report.txt migration.load--summary支持.csv、.json、.copy后缀机器可读方便接进监控看板。为什么它能自动建表——发现式迁移如果你好奇背后的原理pgloader 迁移数据库时会先连接源库的元数据目录把表清单、字段类型、默认值、非空约束、主键、外键、索引、注释全部读进一个内部 catalog再据此生成 PostgreSQL 的 DDL。所以一条命令不是黑魔法而是它替你干了原本手工抄 DDL 的活。第四章 让它更懂你配置文件与自定义转换命令行适合简单场景但真实世界的数据总是脏的。当你需要指定目标表、做类型转换、迁移前建 schema、迁移后建索引时就该上.load命令文件了。一个足够完整的配置文件模板LOAD DATABASE FROM mysql://rootlocalhost/sakila INTO postgresql://localhost:54393/sakila WITH include drop, create tables, create indexes, reset sequences, workers 8, concurrency 1, multiple readers per thread, rows per range 50000 SET PostgreSQL PARAMETERS maintenance_work_mem to 128MB, work_mem to 12MB SET MySQL PARAMETERS net_read_timeout 120, net_write_timeout 120 CAST type bigint when ( precision 20) to bigserial drop typemod, type date drop not null drop default using zero-dates-to-null, type year to integer ALTER SCHEMA sakila RENAME TO pagila BEFORE LOAD DO $$ create schema if not exists pagila; $$; AFTER LOAD DO $$ analyze pagila.*; $$;逐段拆解这份配置在说什么段落作用本例含义WITH include drop先删后建目标表存在则先 DROP保证可重复执行create tables, create indexes迁移结构自动建表和索引reset sequences重置自增序列从迁移后的最大值续走workers / concurrency并发控制8 个 worker 同时迁移多张表SET ... PARAMETERS会话参数迁移期间调大 work_mem 加速排序CAST ...类型转换见下文详解BEFORE / AFTER LOAD前后钩子迁移前建 schema迁移后收集统计信息CAST 规则把 MySQL 的任性翻译成 PostgreSQLCAST是 pgloader 最值钱的自定义能力。举个经典例子MySQL 的日历里存在公元 0 年0000-00-00而 PostgreSQL 直接拒绝这种非法日期。pgloader 内置了一条规则把这些零日期自动转成NULLCAST type date drop not null drop default using zero-dates-to-null再看几个常用写法-- 把 MySQL 的 unsigned bigint(20) 翻译成自增 bigserial CAST type bigint when ( precision 20) to bigserial drop typemod, -- tinyint 不转布尔默认会转改成整数 -- type tinyint to boolean using tinyint-to-boolean, -- 注释掉即可停用 CAST type year to integer,你还可以针对具体列下规则比如把base64.data列解码成jsonb、把身份证列统一转成uuid。规则粒度从某种类型到某个表的某列都支持够灵活。第五章 避坑锦囊高频报错一次说清迁移踩坑是必经之路这里把我见过的高频问题按症状 → 根因 → 解法整理给你。坑 1一到某行就报错整个导入失败症状加载 CSV 中途报COPY errors, line 3, column b: 2006-13-11然后全部回滚。根因文件类数据源默认on error resume next是开启的理论上不会全挂你会遇到全挂多半是手滑开了on error stop。解法确认WITH on error resume next文件源默认值。数据库源迁移默认是on error stop因为重跑迁移更安全但如果你想坏了就跳过显式加WITH on error resume next。坑 2提示 Java 版本不对JAR 跑不起来症状java -jar pgloader.jar报UnsupportedClassVersionError或类似错误。根因pgloader v4 强制要求Java 21你的机器装的是老 JDK。解法先java -version确认版本升级到 Temurin 或 OpenJDK 21。装好后再java -jar pgloader.jar --version验证。坑 3MySQL 连不上报 SSL 或认证错误症状mysql://root:passdb:3306/mydb连接失败。根因新版 MySQL尤其 8.x默认走 SSL 或要求 RSA 公钥交换常见于本地 Docker 环境。解法连接串加参数显式关掉 SSL。v4 支持原生 URI 和标准 JDBC URL 两种写法pgloader mysql://root:passdb:3306/mydb?useSSLfalse postgresql:///target pgloader jdbc:mysql://root:passdb:3306/mydb?useSSLfalse postgresql:///target坑 4导出乱码中文全变问号症状迁移后中文显示乱码。根因源数据的实际编码和库表元数据里声明的不一致MySQL 常见或目标连接默认字符集不对。解法用DECODING TABLE NAMES MATCHING覆盖声明或迁移前在SET里固定 client_encodingSET client_encoding to latin1坑 5迁移被中断不知道死在哪症状跑到一半报错退出找不到问题行。根因不想让坏行干扰排查。解法排查阶段用--on-error-stop让它在第一条被拒数据处停下配合--logfile看完整上下文修好之后再切回默认继续模式跑全量。第六章 性能与效率心得把大迁移跑出高水位pgloader 底层是读线程 → 队列 → 写线程 → COPY的流水线模型性能参数基本就是围绕这条流水线设置的。下面这些数字都是真实参数可以照抄再按你的机器微调。1. 批量参数别让单批次过小批处理机制默认 25000 行一个批次。批次越小出错重试越精细但吞吐也越低。文件干净的情况下可以调大WITH batch rows 50000, batch size 100MB, prefetch rows 1000002. 并发参数worker 不是越多越好workers控制同时搬几张表数据库源默认 4文件源默认 8。concurrency控制单表内并行度需大于 1且源要支持按主键范围或 ctid 范围分片。WITH workers 8, concurrency 4, chunk size 50MB注意concurrency 4意味着这张表同时跑 4 条独立的读→写流水线各读各的分片写是配对的。机器核数不够时别硬堆。3. 索引策略数据先进来索引后建迁移期间建索引很拖速度。合理做法是WITH create indexes, max parallel create index 2或者干脆数据先导进来用AFTER LOAD DO再建索引AFTER LOAD DO $$ create index idx_orders_created_at on orders (created_at); $$;4. 目标库参数迁移时临时调大内存排序、建索引都吃内存迁移窗口内调大不影响平时SET maintenance_work_mem to 512MB, work_mem to 32MB5. 关于极限速度的实话文档里写得很实在如果数据源本身是 COPY 能直接读的干净文件pgloader 不会比原生 COPY 更快。它卖的不是极限速度而是脏数据也能扛 复杂转换也能做 全程一条命令。想快就保证源数据干净想稳就放心交给它。第七章 从这里继续进阶源码、文档与示例项目源码和文档都在仓库里按下面的索引去读效率最高。官方文档docs/index.rst 是总入口含全部手册docs/quickstart.rst 讲最快上手路径命令语法手册docs/command.rst.load命令 DSL 的完整文法批处理与并行机制看 docs/batches.rst各数据源手册docs/ref/mysql.rst、docs/ref/sqlite.rst、docs/ref/mssql.rst、docs/ref/csv.rst核心加载逻辑源码src/load/ 是入口src/pgsql/ 是 PostgreSQL 端实现转换函数源码src/utils/transforms.lisp想自定义数据清洗可以照这里的写法扩展真实可用示例test/ 目录里全是官方.load文件test/mysql/my.load 是 MySQL 迁移的完整范例test/csv.load 是 CSV 场景带注释的范本测试数据test/data/ 里有可以直接练手的 DBF、CSV 文件结语好的工具让迁移从项目变成例行公事回到开头的那个噩梦手工抄 DDL、逐行排错、一次失败全盘重来。有了 pgloader这些都变成了它替你扛的细节。它不完美——极限吞吐比不上裸 COPY遇到实在无解的数据还是要回到--on-error-stop逐条修——但它把数据迁移从一件让人头皮发麻的大工程压缩成了一条可以写进 CI、每天夜里自动跑一遍的命令。文档里把那套做法叫Continuous Migration天天迁、次次验证直到全绿然后择日切库毫无惊吓。给你的下一步行动建议很具体今晚就createdb newdb拿仓库里test/data/的一个 CSV 或 DBF 文件跑一次pgloader五分钟内你就能亲眼看到一条命令搬完一张表到底是什么感觉。等你能把那张表跑通再翻开 docs/command.rst 写你的第一个.load文件。工具不怕用不熟就怕你还没开始。【免费下载链接】pgloaderMigrate to PostgreSQL in a single command!项目地址: https://gitcode.com/gh_mirrors/pg/pgloader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考