navicat定时同步检测不到物理删除,因其设计为快照比对而非日志监听:每次执行时仅通过select全表扫描+主键/唯一键匹配判断差异,不捕获delete语句;常见原因包括key mapping错配、事务未提交、隔离级别影响或同步选项未启用delete records。
navicat 定时同步任务本身不监听 binlog 或事务日志,它只做快照比对。所谓“检测不到物理删除”,不是 bug,而是设计使然——它每次运行都重新查一遍源表和目标表的当前数据,靠主键/唯一键匹配来判断“哪条记录该删”,而不是捕获 delete 语句本身。
为什么「物理删除」在同步预览里显示为「无变化」
常见现象:你在源库执行了 DELETE FROM orders WHERE id = 123,但 Navicat 下次同步预览里没出现 Delete 记录,甚至目标库还留着那行。
- Navicat 同步不订阅数据库变更流(如 MySQL binlog、PostgreSQL logical replication),它不会知道你刚删了一行
- 它只在执行时做一次全表扫描:
SELECT * FROM source.orders和SELECT * FROM target.orders,再按 Key Mapping 做集合差集 - 如果源库那行真被删了,而目标库还有,理论上应该出现在 Delete 列表里;没出现,说明要么 Key Mapping 没对上,要么源查询结果里那行其实还在(比如事务未提交、隔离级别导致不可见)
Key Mapping 错配导致“删了也看不见”
这是最常被忽略的实操坑:Navicat 默认用表名自动映射,但真正决定比对逻辑的是 Key Mapping(主键或唯一键字段)。一旦映射错,比对就失效。
- 检查 Step 2 的 Key Mapping 是否指向真实主键列(比如
id),而不是created_at或其他非唯一字段 - 若源表主键是复合键(
(order_id, item_id)),必须手动勾选全部字段,缺一个就无法匹配 - MySQL 中
TINYINT(1)和BOOLEAN在跨库同步时可能被 Navicat 当作不同类型,导致哈希值不等,误判为“两行都存在”,跳过删除
事务未提交或隔离级别干扰查询结果
Navicat 同步任务走的是普通 SELECT,受事务隔离级别影响。你删了数据但没 COMMIT,或者用了 REPEATABLE READ,它就查不到最新状态。
- 确认源库删除操作已
COMMIT;Navicat 不会帮你 commit,也不会等你 commit - 避免在同步前刚执行完长事务——某些 ORM 或客户端可能默认开启事务且未显式关闭
- 可在同步前手动跑一句
SELECT COUNT(*) FROM source_table WHERE key_col = ?验证源端是否真为空
同步模式选错:用了「仅结构同步」或「忽略目标差异」
很多人保存 .nsx 文件时没注意 Options 设置,导致同步动作被阉割。
- 打开已保存的同步配置 → Step 1 →
Options→ 确认勾选了Delete records(不是只勾了 Insert 和 Update) - 检查是否误选了
Compare only primary keys模式:它只比主键值,不比数据内容,但删除仍应触发——除非主键本身被删了 - 别用
Structure only模式跑数据同步,它根本不动数据行
真正要捕获物理删除并实时同步,得换方案:MySQL 用 mysqldump --where + binlog 解析,PostgreSQL 用 pg_logical_slot_get_changes,或者上 Debezium。Navicat 的定位是“可控的一次性比对”,不是 CDC 工具——这点不看清,后续所有排查都是徒劳。











