Navicat 16 不支持自动重试,需通过脚本捕获 stderr 中的“Lost connection”等错误关键词判断失败,并控制最多3次带间隔的重试,不可依赖退出码。

Navicat 16 本身不支持失败自动重试——你找不到任何界面开关、配置项或命令行参数能启用它。 所有“重试”逻辑必须由外部脚本实现,且不能只依赖 navicat.exe 或 navicat_premium 的退出码。
为什么 Navicat 16 的 exit code 不可靠
官方未定义失败时的退出码行为:即使 SQL 执行报错(如主键冲突、锁超时、连接中断),navicat --run 或 navicat --run-sql 仍可能返回 0;macOS 上某些版本甚至恒定返回 0。这意味着仅靠 $? 或 $LASTEXITCODE 判断成败,大概率漏判失败。
- 必须捕获 stderr 输出,用关键词匹配真实错误
- 关键错误信号包括:
Lost connection、Lock wait timeout、Deadlock found、Connection refused - GUI 中设置的「自动重连」对命令行完全无效,它不干预进程生命周期,也不改变退出行为
Windows 下用 PowerShell 实现可控重试
PowerShell 脚本需显式解析 stderr,并控制重试次数与间隔。任务计划程序(taskschd.msc)里的「失败后重试」选项只对启动失败有效(如路径错、权限不足),对 Navicat 内部执行失败完全无感知。
- 使用
2>&1 | Select-String捕获并匹配错误关键词,而非只看$LASTEXITCODE - 重试前加
Start-Sleep -Seconds 2防止雪崩(尤其多任务并发时) - 最多重试 3 次,避免掩盖根本问题(如磁盘满、表被锁死)
- 完整路径必须正确:
"C:\Program Files\PremiumSoft\Navicat Premium 16\Navicat.exe"含空格,需用引号包裹
# 示例:retry_backup.ps1
$MAX_RETRY = 3
for ($i = 0; $i -lt $MAX_RETRY; $i++) {
$result = & "C:\Program Files\PremiumSoft\Navicat Premium 16\Navicat.exe" --run "backup_orders" 2>&1
if ($result -match "Lost connection|Lock wait timeout|Deadlock found|Connection refused") {
Write-Host "Attempt $($i+1) failed, retrying..."
Start-Sleep -Seconds 2
} else {
Write-Host "Success."
exit 0
}
}
Write-Host "Failed after $MAX_RETRY attempts."
exit 1macOS/Linux 下用 bash 封装并记录日志
shell 脚本比 Windows 批处理更易调试和集成 cron,但要注意:navicat_premium 路径含空格必须转义或引号包裹;脚本运行用户需有钥匙串访问权限(否则弹窗阻塞);cron 环境 PATH 通常不含 Navicat 所需的库路径。
- 用
grep -qE在 stderr 中检测错误关键词,2>&1必须放在命令末尾 - 每次执行写入临时日志(含时间戳和退出码),方便区分是第几次失败
- 避免无限循环:明确设最大重试次数(如
{1..3}),失败后exit 1 - 若使用 SSH 隧道,私钥路径必须绝对且无密码短语,否则脚本卡住
#!/bin/bash LOG="/tmp/navicat_backup_$(date +%Y%m%d).log" echo "$(date): Start backup" >> "$LOG" <p>MAX_RETRY=3 for i in $(seq 1 $MAX_RETRY); do if /Applications/Navicat\ Premium.app/Contents/MacOS/navicat_premium \ --run-sql "/Users/me/backups/backup.sql" --connection "prod_rds" 2>&1 | \ grep -qE "(Lost connection|Lock wait timeout|Deadlock found|Connection refused)"; then echo "$(date): Attempt $i failed" >> "$LOG" sleep 2 else echo "$(date): Success" >> "$LOG" exit 0 fi done</p><p>echo "$(date): Failed after $MAX_RETRY attempts" >> "$LOG" exit 1
真正容易被忽略的是:重试只是兜底手段,不是故障根因解决方案。如果每次重试都失败,说明背后是连接不稳定、RDS 白名单未更新、SSL 配置错误或磁盘空间不足——这些必须单独排查,而不是靠增加重试次数来掩盖。


















