数据库重启或网络闪断之后,应用要重启吗?会有几个请求失败?pool_pre_ping 和 pool_recycle 各管什么?这篇真的把 PostgreSQL 重启、停机、杀连接,把每种情况的结果量出来。
[默认(无 pre_ping)] 重启前池状态: Pool size: 5 Connections in pool: 5 Current Overflow: 0 Current Checked out connections: 0 [默认(无 pre_ping)] 重启后 8 个串行请求的状态码: [503, 200, 200, 200, 200, 200, 200, 200] | 失败个数 1 [pool_pre_ping=True] 重启前池状态: Pool size: 5 Connections in pool: 5 Current Overflow: 0 Current Checked out connections: 0 [pool_pre_ping=True] 重启后 8 个串行请求的状态码: [200, 200, 200, 200, 200, 200, 200, 200] | 失败个数 0
第一个请求:HTTP 503 {"error":"db unavailable","invalidated":true} 数据库停机时:HTTP 503 {"error":"db unavailable","invalidated":false},用时 7 ms
启动数据库之后,第 1 次请求就恢复了(自 pg_ctl start 返回起 8 ms),无需重启应用这一节我自己对 pg_ctl 的调用也踩过坑:不带 -o 启动会去用默认端口,所以所有重启命令都显式带了端口与 socket 目录。
默认配置、数据库刚重启: 200 ok after 2 attempt(s)
正在执行的请求: (503, '{"error":"db unavailable","invalidated":true}')
紧接着的下一个请求: 200没有 pool_recycle 第一次后端进程号 86569,隔 1.3 秒再查 86569 → 还是同一个连接 pool_recycle=1 第一次后端进程号 86590,隔 1.3 秒再查 86594 → 换了新连接 (recycle 只在借出连接时按年龄换掉旧连接,不会探测连接是否还活着——那是 pre_ping 的事)