1. 为什么选择Pgloader进行MySQL到PostgreSQL迁移
第一次接触数据库迁移时,我试过手动导出SQL再导入的方式,结果遇到各种数据类型不兼容的问题,光是处理日期字段的差异就花了整整两天。后来发现了Pgloader这个神器,才发现原来数据库迁移可以这么轻松。
Pgloader最让我惊艳的是它的"智能容错"特性。记得有次迁移一个包含200张表的电商数据库,其中有几张表存在非法日期数据(比如MySQL里常见的0000-00-00)。传统方式会直接报错中断,而Pgloader不仅自动将这些值转为PostgreSQL的NULL,还贴心地生成了错误报告文件。实测下来,百万级数据的迁移成功率能达到99.9%以上。
它的并行处理能力更是提升效率的关键。通过设置worker_count参数,我让8个CPU核心同时工作,原本需要6小时的迁移任务缩短到45分钟。对于需要停机维护的生产环境,这个时间优势太重要了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与安装指南
2.1 硬件资源配置建议
根据我处理过的十几个迁移项目,建议准备:
- 内存:源数据库大小的1.2倍(例如50GB的MySQL至少需要60GB内存)
- CPU:4核起步,8核能获得最佳性价比
- 磁盘:SSD存储,IOPS建议在5000以上
最近一个客户案例中,我们用AWS的r5.2xlarge实例(8vCPU/64GB内存)迁移380GB的数据库,整个过程只用了2小时17分钟。
2.2 多平台安装方案
Ubuntu/Debian用户最方便:
bash复制sudo apt update
sudo apt install -y pgloader postgresql-client
CentOS/RHEL需要先添加EPEL源:
bash复制sudo yum install -y epel-release
sudo yum install -y pgloader
Docker方式适合快速测试:
bash复制docker run --rm -v /path/to/config:/config dimitri/pgloader \
pgloader /config/mysql_to_pg.load
注意:生产环境建议使用3.6.8以上版本,修复了多个内存泄漏问题
3. 迁移配置文件深度解析
3.1 基础配置模板
这是我经过多次优化后的标准模板:
lisp复制LOAD DATABASE
FROM mysql://user:pass@mysql-host:3306/source_db
INTO postgresql://user:pass@pg-host:5432/target_db
WITH
concurrency = 8,
batch size = 50000,
prefetch rows = 100000
CAST
type datetime when (<> "0000-00-00") to timestamptz,
type date when (<> "0000-00-00") to date drop not null
MATERIALIZE VIEWS ALL
INCLUDING ONLY TABLE NAMES MATCHING ~/orders/, ~/users/
BEFORE LOAD DO
$$ CREATE SCHEMA IF NOT EXISTS legacy; $$,
$$ SET search_path TO legacy,public; $$
3.2 高级参数调优
性能关键参数:
| 参数名 | 推荐值 | 作用 |
|---|---|---|
| maintenance_work_mem | 1GB | 提升索引创建速度 |
| work_mem | 64MB | 每个操作的内存配额 |
| max_parallel_workers | 4 | 并行工作进程数 |
避坑经验:
- 遇到大文本字段时添加
SET text_search_path TO pg_catalog - JSON类型转换需要明确指定
type jsonb using convert-json-to-jsonb - 自增ID处理要加上
reset sequences参数
4. 实战迁移全流程演示
4.1 预迁移检查清单
- 版本兼容性验证:
sql复制-- MySQL端执行
SELECT version();
SHOW VARIABLES LIKE 'character_set%';
-- PostgreSQL端执行
SHOW server_version;
- 数据量评估:
bash复制# 估算MySQL数据库大小
SELECT
table_schema "Database",
SUM(data_length + index_length) / 1024 / 1024 "Size (MB)"
FROM information_schema.TABLES
GROUP BY table_schema;
4.2 分阶段迁移策略
阶段一:结构迁移
lisp复制WITH
create tables no indexes,
no foreign keys
阶段二:数据迁移
lisp复制WITH
disable triggers,
no truncate
阶段三:建立关系
lisp复制AFTER LOAD DO
$$ CREATE INDEX ... $$,
$$ ALTER TABLE ... ADD CONSTRAINT ... $$
5. 性能优化与问题排查
5.1 监控迁移进度
推荐使用pgloader的实时监控功能:
bash复制pgloader --client-min-messages debug mysql.load 2>&1 | tee migration.log
关键指标解析:
Bytes read:已迁移数据量import done:表完成百分比errors:需要重点关注的数字
5.2 常见错误解决方案
问题1:字符集不匹配
lisp复制SET PostgreSQL PARAMETERS
client_encoding to 'utf8'
问题2:外键冲突
lisp复制WITH
defer constraints,
batch rows = 1000
问题3:网络中断恢复
bash复制# 使用--resume参数继续中断的迁移
pgloader --resume /path/to/state.file mysql.load
6. 迁移后验证策略
6.1 数据一致性检查
我常用的验证SQL:
sql复制-- 行数比对
SELECT
(SELECT COUNT(*) FROM mysql_table) as mysql_count,
(SELECT COUNT(*) FROM pg_table) as pg_count;
-- 抽样校验
SELECT * FROM mysql_table ORDER BY RAND() LIMIT 100
EXCEPT
SELECT * FROM pg_table ORDER BY RANDOM() LIMIT 100;
6.2 性能基准测试
使用pgbench进行迁移前后对比:
bash复制# MySQL基准
sysbench oltp_read_write --db-driver=mysql prepare
sysbench oltp_read_write --db-driver=mysql run
# PostgreSQL基准
pgbench -i -s 100 target_db
pgbench -c 20 -j 4 -T 300 target_db
7. 高级技巧与最佳实践
7.1 增量迁移方案
对于TB级数据库,我推荐这样操作:
lisp复制-- 首次全量迁移
WITH truncate, create indexes
-- 后续增量
WITH
no truncate,
no create indexes,
include drop
7.2 云环境特别优化
在AWS RDS环境中,这些调整很有效:
lisp复制SET
rds.extensions to 'pg_stat_statements,btree_gin',
synchronous_commit to off
8. 真实案例:电商系统迁移实录
去年帮某跨境电商迁移时遇到个典型问题:他们的商品表有2.4亿条记录,包含大量JSON格式的规格参数。最终采用的方案是:
- 分片迁移:
lisp复制INCLUDING ONLY TABLE NAMES MATCHING ~/products_202[0-3]/
- JSON优化:
lisp复制CAST
type json to jsonb using convert-json-to-jsonb
- 最终验证:
bash复制pg_comparator --verbose mysql://src pg://dst
整个迁移过程历时6小时18分钟,停机窗口控制在15分钟内,客户非常满意。关键是把batch size从默认的25000调整到50000,同时增加了maintenance_work_mem到2GB。
