Navicat Premium 16可迁移MySQL至PostgreSQL,但必须手动建表、校验类型映射、处理字符集与时区、禁用autovacuum、分批插入并做哈希比对验证,否则易丢数据或失败。
Navicat Premium 16 能完成 MySQL 到 PostgreSQL 的迁移,但“快速”不等于“点下一步就完事”——跳过类型映射校验、忽略字符集差异、直接全表传输,大概率会在 INSERT 阶段卡住或丢数据。真正省时间的,是提前把坑踩在测试环境。
用数据传输功能前,必须手动建好目标表结构
navicat 的 数据传输 功能默认只传数据,不建表(除非勾选“创建目标表”,但那会生成不可靠的 ddl)。我们遇到过三次因自动建表失败导致中断:一次是 enum 被转成 varchar 却没加 check 约束;另一次是 datetime 自动转成 timestamp without time zone,结果时区偏移全乱了。
- 先在 MySQL 中执行
SHOW CREATE TABLE orders,复制建表语句 - 手动改写为 PostgreSQL 兼容语法:把
AUTO_INCREMENT换成SERIAL,TINYINT(1)改成BOOLEAN,LONGTEXT改成TEXT - 特别注意字段名和表名:PostgreSQL 默认小写,若原 MySQL 表名含大写(如
UserProfile),需写成"UserProfile",否则后续查询必须加引号 - 在 PostgreSQL 中先
CREATE TABLE成功,再进数据传输
导出向导里选“PostgreSQL”格式,别碰 CSV
用 导出向导 从 MySQL 导出时,选 PostgreSQL 格式(不是通用 SQL 或 CSV)——它会自动处理 NULL 值写法、字符串转义、布尔值转换(1/0 → true/false),而 CSV 会把 NULL 写成空字符串、把 \n 当换行切开字段,导入时直接报错 extra data after last expected column。
- 导出时勾选“导出表结构”和“导出表数据”,但取消“导出创建数据库语句”(PostgreSQL 不认
CREATE DATABASE) - 导出路径避免中文或空格,例如
/tmp/mysql_to_pg.sql,否则 Navicat 可能静默失败 - 导出后别直接双击运行 SQL 文件——用 Navicat 的
导入向导导入,并在“字段映射”页确认每列类型是否匹配(尤其JSON字段要手动指定为JSONB)
大表迁移时必须关 autovacuum 和分批插数据
一次性往空表里插几千万行,PostgreSQL 的 autovacuum 会抢资源,导致传输变慢甚至连接超时。我们同步一张 8000 万行的订单表时,没关 autovacuum,耗时从 22 分钟飙升到 3 小时 17 分钟。
- 传输前,在 PostgreSQL 执行:
ALTER TABLE orders SET (autovacuum_enabled = off); - 传输完成后立即打开:
ALTER TABLE orders SET (autovacuum_enabled = on); - 如果表超过 500 万行,建议在
数据传输设置里启用“分批插入”,批次大小设为10000(太大内存溢出,太小事务开销高) - 传输完立刻跑
VACUUM ANALYZE orders;,否则后续查询可能走错执行计划
自动同步作业必须配失败通知,不能只靠日志
用 批处理作业 做每日同步,最常被忽略的是错误兜底——作业失败时 Navicat 默认只写本地日志,服务器凌晨崩了你根本不知道。我们有次连续三天订单同步失败,直到财务对账才发现。
- 在批处理作业设置里,务必勾选“发送邮件通知”,并配置 SMTP(Gmail 或企业邮箱都行)
- 失败通知模板里加上
$(ErrorDescription)和$(StartTime)变量,方便定位哪张表、什么时间挂的 - 作业触发方式选“Windows 任务计划程序”或“cron”,不要选“Navicat 启动时运行”——客户端没开,任务就永远不执行
- 首次部署后,手动右键运行一次作业,看邮件能不能收到成功通知,再改个错误密码测失败通知是否触发
ENUM 值超出预设范围、某个 utf8mb4 emoji 在 PostgreSQL 的 UTF8 排序规则下排序异常、或是某条 ON DELETE CASCADE 触发器在目标库没权限执行。这些细节不会报红字错误,只会让数据“看起来正常,其实少了几千行”。每次迁移,都要拿 SELECT COUNT(*) 和 md5(string_agg(...)) 对关键表做行数+内容哈希比对——这是唯一能让你睡着的办法。


















