30 秒自检
错误堆栈出现以下任一:
prepared statement "s0" does not existPostgresError: prepared statement "..." does not exist- 错误码
26000 - 偶发性出现(不是每次请求都报,约 10-30% 概率)
如果错误是连接超时 / SSL 失败,看其他文章。
最短处理路径
1:判断走 6543 还是 5432
Supabase 提供两个连接端口:
| 端口 | 用途 | Mode | 是否支持 prepared |
|---|---|---|---|
| 5432 | Direct Connection | session | 支持 |
| 6543 | Pooled Connection (Supavisor) | transaction | 不支持 |
Serverless 部署(Vercel / Netlify / Cloudflare Workers)必须用 6543,否则连接数瞬间打满。传统 EC2 / Render 长期连接可用 5432。
2:Prisma 修复
DATABASE_URL 加参数:
DATABASE_URL="postgresql://postgres.[ref]:[pwd]@aws-0-[region].pooler.supabase.com:6543/postgres?pgbouncer=true&connection_limit=1"
DIRECT_URL="postgresql://postgres.[ref]:[pwd]@aws-0-[region].pooler.supabase.com:5432/postgres"
schema.prisma 同时配置:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
DIRECT_URL 用于 migrations(必须用 session mode)。DATABASE_URL 用于运行时(pooled)。
3:Drizzle ORM 修复
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
const client = postgres(process.env.DATABASE_URL!, {
prepare: false, // 关键
max: 1, // serverless 限制
});
export const db = drizzle(client);
4:node-postgres (pg) 修复
import { Pool } from 'pg';
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
// pg 不直接支持,需要换连接每次
max: 1,
});
// 用 simple query 而不是 prepared
await pool.query({ text: 'SELECT * FROM users WHERE id = $1', values: [1] });
pg 库默认就是 simple query,但如果上层 ORM(Sequelize)用 prepared 包装就会出问题。
5:Supabase JavaScript Client
如果用 @supabase/supabase-js 直接调用,不会有这个问题(它走 PostgREST 而不是直连)。
根因
PgBouncer transaction mode 的工作机制:
- 客户端 A 发起事务 1,PgBouncer 分配后端连接 X。
- 客户端 A 在事务 1 内 prepare 一个 statement “s1”,存在连接 X。
- 事务 1 结束,PgBouncer 回收连接 X 给池。
- 客户端 A 发起事务 2,PgBouncer 分配后端连接 Y(不一定是 X)。
- 客户端 A 想用 “s1”,但连接 Y 没有这个 prepared statement,直接报错。
session mode 则保证客户端始终用同一个连接。
继续排查
偶尔报错,不是每次
正常。因为 transaction mode 下每个事务有独立连接分配。第一个事务 prepare 成功 → 后续如果分到不同连接就失败。
local 测试没问题,线上才报
Local 通常直连 5432,线上 serverless 走 6543。
Prisma migrations 失败
确保 DIRECT_URL 设置正确,走 5432。Prisma migrate 必须用 session mode。
如果还没恢复
试 Supavisor v2(2026 年 Q1 上线)的「prepared statement transparent forwarding」:
DATABASE_URL="...:6543/postgres?pgbouncer=true&supavisor_prepared=true"
注意:仍在 beta,不一定所有 ORM 都兼容。
跨地区访问 Supabase Dashboard
国内排查 Supabase 错误时,Dashboard 的 Logs / Database Indicators 加载缓慢,Real-time Inspector 可能断连。一条海外服务跑 GitHub Actions / Cloudflare 的稳定线路能让 Supabase Dashboard 顺畅,排查更快。