数据库迁移工具实战:3 步完成 PostgreSQL 迁移 MySQL 的完整流程

数据库迁移工具实战:3 步完成 PostgreSQL 迁移 MySQL 的完整流程 数据库迁移工具实战3 步完成 PostgreSQL 迁移 MySQL 的完整流程【免费下载链接】pg2mysql项目地址: https://gitcode.com/gh_mirrors/pg2/pg2mysql把数据从 PostgreSQL 搬到 MySQL听起来只是换个数据库真正动手的人却都清楚类型差异、字段长度、时间精度任何一个细节处理不好迁移完成的那一刻就是事故开始的瞬间。本文要介绍的数据库迁移工具 pg2mysql正是为PostgreSQL 迁移 MySQL这条特定路径设计的小型开源工具。它不追求花哨功能只把迁移前检查、迁移执行、迁移后核对三件事做扎实。下面这份 PostgreSQL 迁移 MySQL 完整步骤会带你从零跑通整个流程。先看结果迁移流程被压缩成三个命令在展开细节之前先给结论。pg2mysql 的全部核心能力由三个子命令承载阶段命令作用迁移前体检pg2mysql -c config.yml validate对照目标表结构找出 PostgreSQL 中装不下的数据行数据搬运pg2mysql -c config.yml migrate --truncate逐表读取并写入支持先清空目标表再导入迁移后对账pg2mysql -c config.yml verify逐行比对源库与目标库报告缺失记录三个命令对应三张检查单顺序固定、缺一不可。这种先体检、再搬运、后对账的节奏很像外科手术前的麻醉评估——不做评估就上台风险只能靠运气对冲。为什么 PostgreSQL 的数据会装不进 MySQL理解 pg2mysql 的设计逻辑只需抓住一个核心矛盾text 类型在两个数据库里的含义完全不同。PostgreSQL 的text字段没有长度上限存几 MB 的文本也毫无压力而 MySQL 同名类型text上限是 65535 字符更常用的varchar则必须显式声明长度比如varchar(255)。于是出现典型场景PostgreSQL 里一列text某行数据实际长度 90000 字符MySQL 对应列是varchar(255)上限 255迁移执行后这条记录要么被截断要么直接报错。更隐蔽的是这类问题通常只出现在少数特定行上——99% 的数据都正常偏偏那几行超长的记录会让整个表的迁移静默失败。pg2mysql 的validate命令就是为此设计的它不是笼统地告诉你表结构不兼容而是精确到哪张表、哪几行、主键 ID 是多少让你在动手迁移前就完成数据清理。准备阶段一份 YAML 配置 一个编译好的二进制1. 获取工具pg2mysql 是 Go 项目源码安装只需三步git clone https://gitcode.com/gh_mirrors/pg2/pg2mysql cd pg2mysql go build -o pg2mysql ./cmd/pg2mysql/编译产物是一个单文件二进制拷到服务器上即可运行不依赖运行时环境这一点在跨环境迁移时非常省心。2. 编写配置文件工具通过-c参数读取 YAML 配置内容就是两端数据库的连接信息mysql: database: your-mysql-db username: mysql-user password: mysql-password host: 127.0.0.1 port: 3306 postgresql: database: your-postgres-db username: postgres-user password: postgres-password host: 127.0.0.1 port: 5432 ssl_mode: disable注意两点ssl_mode的取值需参考 PostgreSQL 官方 SSL 模式说明配置里只有连接信息不包含任何表名或字段清单——表结构由工具在运行时自动读取这也是它零配置迁移思路的体现。实战三步走一套可复用的跨数据库数据迁移方案第 1 步validate迁移前的兼容性体检先跑一次检查观察输出$ pg2mysql -c config.yml validate found incompatible rows in apps with IDs [2] found incompatible rows in app_usage_events with IDs [9 10 11 12] found incompatible rows in events with IDs [16 17 18]这段输出的信息量很大兼容的表会输出表名 OK不兼容的表会给出具体行 ID例如apps表第 2 行超长没有主键id的表则只报告不兼容行数。拿到行 ID 后你可以针对性修数据要么在源库扩展该字段内容要么调整 MySQL 目标表的列长度再重新 validate直到全部OK。这一步的严谨程度直接决定后续迁移是否安全。第 2 步migrate正式执行数据搬运体检通过后执行迁移$ pg2mysql -c config.yml migrate --truncate inserted 1 records into spaces_developers inserted 0 records into security_groups_spaces inserted 2 records into droplets inserted 2 records into organizations ...逐表输出插入记录数方便对照源库行数做初步判断。这里有两个值得了解的实现细节约束处理迁移开始前会临时禁用目标表外键约束全部导入完成后重新启用避免插入顺序导致的约束冲突--truncate选项加上后每张表写入前先清空目标表数据适合目标库原本有残留数据的场景不加则保留目标库已有数据仅补充缺失的主键行。第 3 步verify迁移后的逐行对账迁移不是终点对账才是。运行$ pg2mysql -c config.yml verify Verifying table spaces_developers...OK Verifying table droplets... FAILED: 1 row missing Missing IDs: 1,3,5 Verifying table organizations...OKverify 会把 PostgreSQL 的每一行数据在 MySQL 中做精确匹配查找通过空安全比较找不到就报告缺失行的 ID。这意味着你不需要写任何 SQL 对比脚本工具已替你完成了源库逐行 → 目标库逐行的核对。一个需要留意的边界verify 假设 PostgreSQL 的时间戳在迁移时被截断到秒级精度再写入 MySQL。实测中官方 MySQL 会四舍五入时间戳而 MariaDB 则是直接截断两种行为不完全一致。如果你用了 MariaDB 且对时间精度敏感需要自行评估这部分差异。工具内部是如何工作的理解了用法之后简单看一眼它的骨架对排障有帮助。项目模块划分非常清晰对应关系如下源码文件职责config.go配置文件解析与数据结构定义db.go数据库抽象接口与 Schema 构建validator.go兼容性校验产出不兼容行清单migrator.go数据迁移主流程verifier.go迁移后逐行比对watcher.go进度输出与事件回调贯穿始终的是db.go里的DB接口Open、GetSchemaRows、DisableConstraints等方法把 PostgreSQL 与 MySQL 的差异封装在各自实现里对应postgres.go和mysql.go上层逻辑完全面向接口编程。这也是为什么 validate、migrate、verify 三段流程可以复用同一套 Schema 构建代码。判断列是否兼容的核心逻辑在db.go的Compatible方法里当源列与目标列都定义了最大长度时比较两者大小都未定义长度则视为兼容只有一方有长度限制时判定不兼容。这套规则朴素却有效恰当地覆盖了text与varchar的典型冲突。什么时候该用、什么时候不该用诚实地说pg2mysql 不是万能的。它的适用边界需要提前说清适合的场景源库与目标库表结构基本等价只是数据需要搬迁迁移前有充足时间做 validate 检查和数据清洗需要迁移后自动对账、形成书面记录的场景。不适合的场景源表和目标表结构差异很大需要字段映射或转换逻辑需要不停机的增量同步——它是批处理工具不是 CDC 管道完全依赖自动化、不允许人工介入数据修复的流程。换句话说pg2mysql 更像是迁移任务里的执行引擎 质检员而表结构设计与数据清洗仍然需要人来完成。这正是它定位精准的地方把机器擅长的事交给机器把人该做的事留给决策。写在最后数据库迁移的本质不是复制数据而是控制风险。pg2mysql 用三个命令把风险拆解成了三段可控的流程validate 让问题暴露在迁移之前migrate 用约束禁用和批量插入保证执行效率verify 用逐行比对为结果兜底。对需要从 PostgreSQL 迁往 MySQL 的团队来说这套跨数据库数据迁移方案足够轻量也足够透明——每个环节都在输出可读的结果每一条异常都有明确的定位信息。工具已经开源源码位于cmd/pg2mysql/目录核心逻辑分散在migrator.go、validator.go、verifier.go几个文件中。如果你是第一次做这类迁移建议先拿一份测试数据完整跑一遍 validate → migrate → verify 闭环再对生产库动手。迁移的成功率从来不取决于工具的智能程度而取决于你在动手之前对自己的数据了解得有多深。【免费下载链接】pg2mysql项目地址: https://gitcode.com/gh_mirrors/pg2/pg2mysql创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考