Navicat 12 可迁移但必须手动配置:①勾选“重置序列”防主键冲突;②JSON字段需手动映射为jsonb并建GIN索引;③连接高级设置中强制SET client_encoding='UTF8'防乱码;④关闭自动分批提交、禁用autovacuum提升速度。
navicat 12 能完成 mysql → postgresql 迁移,但必须手动补全关键配置,否则大概率失败——尤其是自增主键、json 字段和字符集这三处,90% 的中断都发生在这里。
为什么“直接点开始”会卡在 95% 或报错 ERROR: duplicate key value violates unique constraint
Navicat 12 默认不重置 PostgreSQL 的序列(serial 或 bigserial),而 MySQL 的 AUTO_INCREMENT 值直接写入后,PostgreSQL 仍按旧序列值继续生成新 ID,导致下一条插入就冲突。这不是传输中断,是后续插入失败。
- 必须在【数据传输】→【高级】页勾选
重置序列(Reset sequences) - 如果目标表已存在且有数据,先手动执行
SELECT setval('table_id_seq', (SELECT MAX(id) FROM table));再开始传输 - 避免用
INSERT ... ON CONFLICT DO NOTHING替代——Navicat 12 不支持该模式的自动 fallback
JSON 字段迁移后查不到或报 invalid input syntax for type json
MySQL 的 JSON 类型在 Navicat 12 中默认映射为 PostgreSQL 的 text,而非 jsonb。虽然能存进去,但一旦执行 -> 或 @> 操作就会报错。
- 迁移前,在 PostgreSQL 目标库手动建好表,把字段定义为
jsonb(不是json) - 在【数据传输】→【字段映射】里,为每个 JSON 源字段手动指定目标类型为
jsonb - 若已传完且是
text,用ALTER TABLE t ALTER COLUMN j TYPE jsonb USING j::jsonb;转换(需确保内容合法)
中文乱码或特殊符号变 怎么办
根本原因不是 Navicat 编码设置错了,而是它没强制告诉 PostgreSQL 客户端使用 UTF-8——即使连接字符串里写了 client_encoding=UTF8,Navicat 12 也可能忽略。
- 在 PostgreSQL 连接属性 → 【高级】→ 【初始化命令】里填入:
SET client_encoding = 'UTF8'; - MySQL 连接也建议加:
SET NAMES utf8mb4;(尤其含 emoji 时) - 别依赖 Navicat 自动检测字符集——它对
utf8mb4和latin1混合库经常误判
传输速度慢得离谱?检查这三项
百万级表耗时超 2 小时,通常不是网络问题,而是 Navicat 12 的默认事务粒度太小 + 索引干扰。
- 【高级】页关闭
每 X 行提交一次(Commit every X rows),改用整个表完成后提交(Commit entire table) - 迁移前在 PostgreSQL 手动禁用目标表的索引:
ALTER TABLE t SET (autovacuum_enabled = off);;迁移完再重建 - 确认 MySQL 源库未开启
binlog_row_image=MINIMAL(某些旧版 MySQL 会触发 Navicat 额外校验)
最易被忽略的是:Navicat 12 不验证目标库是否有足够磁盘空间和临时表空间,等传到 99% 才因 no space left on device 失败——务必提前用 SELECT pg_size_pretty(pg_database_size('dbname')); 和 df -h 双重确认。


















