Skip to content

driver 没有任何重连:数据库抖一下,进程就永久失效,只能靠外部重启 #3759

Description

@os-zhuang

一句话说明

driver-sql / driver-mongodb 里没有任何重连实现。连接一旦断开(数据库重启、failover、网络抖动、连接池被服务端掐掉),这个进程就永久性地服务不了那个 datasource,直到有人从外部重启它。

#3751 处理这件事的方式是删掉那句声称有重连的话(它是假的),而不是实现它。删得对 —— 但缺失的能力本身还在,值得单独定夺要不要补。

事实核实

#3741 之前,ObjectQLEngine.init() 在连接失败时打印:

Operations may recover via lazy reconnection or fail at query time.

全仓 grep reconnect,除了这条 warning 字符串本身,driver-sql / driver-mongodb 里没有任何重连实现 —— 命中的全是 WebSocket(spec/src/api/websocket.zod.tsreconnectInterval 等)、metadata HMR 的 SSE、以及 automation 的 MCP connector 重连,都跟 data driver 无关。

#3751 已经把这句话删掉了(并把启动期连接失败改成拒绝启动)。所以现在的状态是诚实但缺能力,而不是之前的declared ≠ enforced

驱动层现状:

  • SqlDriver.checkHealth()sql-driver.ts:697)是 SELECT 1,只报告状态,不做任何恢复。
  • MongoDBDriver.checkHealth()mongodb-driver.ts:170)是 db.command({ping:1}),同样只报告。
  • 两者都没有重试/重建连接池的路径。

影响

以下都属于"数据库短暂不可用、之后自己恢复了"的常见情形:

  • 托管数据库的计划内维护窗口 / 版本升级。
  • Postgres 主备 failover(秒级到数十秒)。
  • 网络分区、安全组/网络策略短暂变更。
  • 服务端主动掐掉空闲连接(idle_in_transaction_session_timeout、云厂商的连接回收)。

数据库恢复之后,进程不会恢复 —— 它会一直用一个死掉的连接池服务 500,直到外部重启。

严重程度取决于部署形态:

  • k8s / 有编排器:可接受 —— 前提是探针能发现(目前不能,见本批第一个 issue)。摘流量 + 重启是标准做法,进程内重连只是优化。
  • 单机自托管 / 长驻进程os serve 直接跑、systemd、Docker 单容器无健康检查):没有编排器兜底,一次 30 秒的 failover 变成永久宕机,直到人工介入。这才是真正的痛点。

建议处置

先定性再动手 —— 这是要不要新增一个能力的决定,不是修 bug:

选项 A:不做,明确声明由编排器负责。 把"driver 不重连,恢复依赖编排器重启"写进 data-modeling/drivers.mdx 和生产就绪清单,并要求配 liveness/readiness 探针。前提是探针得先能发现(本批第一个 issue)。成本最低,且对 k8s 部署是正确答案。

选项 B:在 driver 层做有界重连。 knex 自带连接池,SELECT 1 失败后重建 pool 是可行的;mongodb 官方 driver 其实自带 auto-reconnect,需要先核实我们的用法有没有把它关掉或绕过。要点:指数退避 + 上限、不能让重连风暴打垮刚恢复的数据库、必须可观测(重连中/已恢复要有明确信号,不能又变成一个"声称能恢复"的黑盒)。

倾向 A + 把 B 限定在自托管形态:k8s 场景下重连是重复造轮子,而单机场景才是没有兜底的那个。但这需要先确认单机自托管是不是我们要支持的一等形态。

无论选哪个,不要重新引入那句"may recover via lazy reconnection",除非它真的成立。

关联

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions