目标库只读导致同步失败需先执行select @@read_only和select @@super_read_only确认状态,均为0才可写;云数据库须通过控制台操作,自建库有super权限可用set global解除,否则需修改配置文件并重启,同时检查navicat连接设置中是否误勾“read only”选项。
目标库只读导致同步失败怎么确认和解除
navicat 数据同步失败,如果错误里没明说 read_only,但你怀疑是只读问题,别猜,直接查。在 navicat 连接的目标库中执行:select @@read_only; 和 select @@super_read_only;。两个都返回 0 才算真正可写。
云数据库(如阿里云 RDS、腾讯云 CDB)禁用 SET GLOBAL,不能连上去就执行 SET GLOBAL read_only = OFF;——必须进控制台开关「只读实例」状态。本地或自建库有 SUPER 权限才能用 SET 命令;没有权限就得改配置文件(my.cnf 里删掉 read_only = 1),然后重启 MySQL。
容易踩的坑:
- Navicat 连接设置页底部勾了
Read Only(MySQL 连接属性里),这是客户端侧强制加/*+ READ_ONLY */hint,即使库本身可写也会报错 - 解除只读后没重连 Navicat,或者没手动验证写入能力(比如执行
INSERT INTO test_table VALUES (1);),就直接点同步,结果还是失败 - 误信 Navicat 界面右下角连接图标显示“已连接”,它不检测
read_only变量,完全不可靠
外键约束报错不是勾选了 Disable 就完事
Disable foreign key checks 选项只在生成 SQL 脚本时往开头加一句 SET FOREIGN_KEY_CHECKS = 0;,但它极易被覆盖:源库导出的 SQL 文件自带 SET FOREIGN_KEY_CHECKS = 1;,MySQL 5.6 及更早版本在某些上下文里不支持动态修改,结构同步阶段这个选项压根不生效。
同步失败后立刻执行 SELECT @@FOREIGN_KEY_CHECKS;,结果必须是 0 才算真正关掉。结构同步时 Navicat 不自动解析全库依赖树,遇到 orders → users 这种引用关系,可能先建 orders 再建 users,直接报 ERROR 1215。
实操建议:
- 手动查依赖:
SELECT TABLE_NAME, REFERENCED_TABLE_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME IS NOT NULL; - 在 Navicat 「对象选择」面板里,把被引用表(如
users)拖到引用表(如orders)上方,强制调整顺序 - 纯结构同步阶段先取消勾选
Synchronize data,避免数据插入干扰建表顺序
同步中途断连大概率是空闲超时没配对
报错 Lost connection to MySQL server during query 或 Connection timed out,但数据库日志无异常、SHOW PROCESSLIST 也看不到残留连接,基本就是 TCP 空闲连接被中间设备(NAT、防火墙、SSH 跳板机)掐断。
必须同步调三处心跳:Navicat 客户端、SSH 隧道(如有)、数据库服务端。只调其中一处无效。
关键配置:
- Navicat 连接 → 「高级」→ 勾选
保持连接活跃,值设为60;务必取消勾选仅当有查询时发送 ping(同步解析阶段无 query,不取消等于没开) - 走 SSH 隧道时,跳板机需设
ClientAliveInterval 30,本地 SSH 客户端需设ServerAliveInterval 30 - 源库调高
wait_timeout和interactive_timeout(建议设为86400),并确认 Navicat 连接设置里已取消勾选自动断开空闲连接
视图同步后无法查询多数因 DEFINER 和 SQL SECURITY 丢失
Navicat 结构同步视图后,SHOW FULL TABLES WHERE TABLE_TYPE = 'VIEW' 能查到视图,但执行 SELECT * FROM vw_name 报错,大概率是 DEFINER、SQL SECURITY 或隐式 schema 上下文没适配目标环境。
Navicat 同步时默认跳过 DEFINER='user'@'host' 和 SQL SECURITY DEFINER 子句,导致目标库按当前用户权限运行,而该用户可能无底层表 SELECT 权限;或者视图 SQL 中写了 SELECT * FROM users(没带库名),执行时若连接默认库不同就查不到表。
修复方法唯一可靠:在源库执行 SHOW CREATE VIEW `vw_name`,复制整行 Create View 字段内容(含所有换行和注释),手动替换 DEFINER 为目标库存在用户,并显式加上 SQL SECURITY INVOKER,再在目标库执行。
注意:DEFINER=CURRENT_USER 比硬写用户名更稳妥;Navicat 界面双击编辑再保存会丢元数据,不能替代完整语句重跑。











