Navicat结构同步默认不比对PARTITION定义,因未读取INFORMATION_SCHEMA.PARTITIONS视图,仅依赖TABLES和COLUMNS元数据,导致RANGE与HASH分区差异被忽略;必须手动执行SHOW CREATE TABLE或查询PARTITIONS视图验证并人工处理分区变更。
分区表结构比对会漏掉PARTITION定义
navicat 的结构同步默认不比对分区定义(partition by、partitions、具体分区规则等),只比表名、字段、索引这些常规结构。哪怕源库是 range 分区、目标库是 hash 分区,只要字段和索引一致,navicat 就会显示“无差异”。
原因在于 Navicat 读取 INFORMATION_SCHEMA.TABLES 和 COLUMNS,但分区元数据存在 INFORMATION_SCHEMA.PARTITIONS 中,而结构同步逻辑未主动拉取并对比该视图。
- 手动验证是否分区:执行
SHOW CREATE TABLE table_name,检查输出里是否有PARTITION BY子句 - 比对前必须先确认:两个库中同名表是否都启用了分区(或都未启用)——否则同步后表结构看似一致,实际查询性能和数据分布可能完全错乱
- 若发现一方有分区、另一方没有,不能依赖 Navicat 自动生成 ALTER;必须人工补上
ALTER TABLE ... PARTITION BY ...或REMOVE PARTITIONING
“对象选择”页勾选表后,仍需手动检查分区状态
Navicat 在结构同步的“对象选择”页只控制是否比对某张表,不区分该表是否为分区表。即使你勾选了 users 表,它也不会自动检测该表在源/目标库中是否以相同方式分区。
常见误操作:看到“0 difference”就直接点运行,结果目标库的分区表变成普通表,后续 INSERT 或查询按分区键路由时失败,报错 ERROR 1708 (HY000): Cannot add or drop partition when sql_mode=NO_ENGINE_SUBSTITUTION 或更隐蔽的性能下降。
- 务必在比对前,对每张待同步的表分别执行
SELECT PARTITION_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'table_name' - 如果任一库返回空结果,说明该表未分区;若两边行数不同、或
PARTITION_METHOD不一致,就必须中断同步,先人工统一分区策略 - Navicat 不支持子分区(SUBPARTITION)的可视化比对,这类结构差异只能靠
SHOW CREATE TABLE文本比对
SQL预览里看不到分区变更语句
即使你手动改过分区定义,Navicat 在 SQL 预览页也几乎从不生成 ALTER TABLE ... REORGANIZE PARTITION、ADD PARTITION 或 DROP PARTITION 这类语句。它最多生成 ALTER TABLE ... ENGINE=InnoDB 这种无关操作,或者干脆跳过。
这是设计限制,不是 bug。Navicat 把分区视为“高级 DDL”,不在其结构同步的默认覆盖范围内。
- 不要指望 Navicat 自动修复分区不一致——所有分区级操作都得手写 SQL
- 若需新增分区(如 RANGE 按月追加),必须用
ALTER TABLE t ADD PARTITION (PARTITION p202607 VALUES LESS THAN (738735))形式,数值需根据TO_DAYS()或UNIX_TIMESTAMP()计算 - 执行前确认目标库 MySQL 版本支持对应语法:MySQL 5.7 支持 HASH/RANGE/LIST,但不支持
EXCHANGE PARTITION;MySQL 8.0+ 才完整支持REORGANIZE PARTITION与子分区管理
大表分区比对卡住时,别硬等
含几十个分区的表(尤其每个分区都有大量索引),Navicat 在“Comparing columns…”阶段容易卡死或超时。这不是连接问题,而是它试图对每个分区单独查询 INFORMATION_SCHEMA.STATISTICS,触发 MySQL 的 max_allowed_packet 限制或锁等待。
这时强行刷新或重试只会重复失败。最有效的方式是绕过 GUI,直查元数据。
- 在源库和目标库分别执行:
SELECT TABLE_NAME, PARTITION_NAME, PARTITION_METHOD, PARTITION_EXPRESSION FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'your_table' ORDER BY PARTITION_ORDINAL_POSITION - 把两段结果导出为 CSV,用 Beyond Compare 或
diff命令逐行比对,重点关注PARTITION_METHOD和PARTITION_EXPRESSION - 若只是分区数量不同(比如源有 12 个 RANGE 分区、目标只有 6 个),说明历史分区被删过,必须人工重建,不能靠结构同步“补全”


















