Navicat 命令行执行失败时 exit code 不可靠,必须通过外层脚本捕获 stderr 中的错误关键词(如“Lost connection”“Lock wait timeout”“Deadlock found”)来判断失败并实现可控重试,最多3次,每次间隔2秒。
Navicat 命令行执行失败时 exit code 不可靠,无法直接依赖
navicat 自带的 navicat.exe --run-sql(windows)或 navicat_premium --run-sql(macos/linux)不保证失败时返回非零退出码。即使 sql 报错(如主键冲突、锁超时、连接中断),进程仍可能以 0 退出,导致外层脚本误判为“成功”。官方也未定义任何 --retry 或 --max-attempts 参数。
必须用外层脚本封装并基于 stderr 内容做错误识别
真正可控的重试逻辑只能由你写的 shell 或 batch 脚本来实现,关键在于捕获并解析 stderr 中的典型错误关键词:
- 匹配
Lost connection to MySQL server、Lock wait timeout exceeded、Deadlock found等明确失败信号 - 避免仅靠 exit code 判断——macOS 上某些版本甚至始终返回
0 - 重试前加
sleep 2防止雪崩,最多试 3 次(太多可能掩盖真实问题)
macOS 示例(需保存为 retry_navicat.sh 并 chmod +x):
#!/bin/bash
MAX_RETRY=3
for ((i=0; i<MAX_RETRY; i++)); do
if /Applications/Navicat\ Premium.app/Contents/MacOS/navicat_premium --run-sql "/path/to/script.sql" --connection "MyDB" 2>&1 | grep -qE "(Lost connection|Lock wait timeout|Deadlock found)"; then
echo "Attempt $((i+1)) failed, retrying..."
sleep 2
else
echo "Success."
exit 0
fi
done
echo "Failed after $MAX_RETRY attempts."
exit 1
Navicat GUI 里的“自动重连”和脚本重试是两回事
连接设置里勾选的 自动重连 只作用于 GUI 交互过程中的临时断连(比如查询中途掉线),它不会让 --run-sql 命令本身重试失败的 SQL 执行。这个选项对批处理脚本完全无效。
- 它不干预命令行工具的生命周期,也不改变 exit code 行为
- 它只在 Navicat 进程内生效,且不保证事务一致性(重连后可能重复执行部分语句)
- 若脚本中 SQL 本身失败(语法错、约束冲突),自动重连根本不会触发
重试逻辑里最容易被忽略的三个点
实际部署时,以下三点常被跳过,但直接影响重试是否真正生效:
-
navicat_premium的完整路径必须正确——macOS 上路径含空格,要用反斜杠转义或引号包裹 - 脚本运行用户必须有权限读取
script.sql和访问钥匙串(某些版本会因钥匙串弹窗阻塞进程) - 重试不是万能解药:死锁、唯一键冲突这类逻辑错误重试只会反复失败,应优先修复 SQL 或加前置校验


















