Prisma+PgBouncer+Supabase生产环境数据库连接超时排查求助
问题描述
我使用Prisma ORM、Supabase上的Postgres(启用PgBouncer),通过Google Cloud Run部署Node/Express API。生产环境日志反复出现如下错误:
Timed out fetching a new connection from the connection pool. More info: http://pris.ly/d/connection-pool (Current connection pool timeout: 10, connection limit: 1)
已查阅Prisma连接池相关文档,当前10秒的连接池超时为默认值,连接限制1是通过连接字符串的connection_limit=1参数设置,目的是避免多API实例占用过多PgBouncer连接。
已尝试的操作:
- 移除
connection_limit参数,但无明显效果; - 在Supabase的数据库角色页面中看到PgBouncer有连接,推测其已正常运行;
- 查看
pg_stat_activity,发现多个idle进程,推测由PgBouncer管理; - 考虑增加连接池超时时间,但并不希望这么做。
我的疑问:
- 我的PgBouncer配置是否正确?若不正确,如何进行正确配置?
- 使用PgBouncer时,设置
connection_limit是否无意义?是否应移除该参数? - 如何解决这类连接超时问题?
解决方案与答疑
1. PgBouncer配置正确性排查与修正
你的核心问题出在Prisma连接池和PgBouncer的配合逻辑上,当前connection_limit=1的设置方向没错,但需要结合PgBouncer模式和Supabase默认配置调整:
- Supabase默认PgBouncer为
transaction模式(最常用的连接池模式),这种模式下,Prisma每个实例的连接池需要设置合理上限,而非硬设为1。 - 正确配置逻辑:
- 确认Supabase的PgBouncer总连接上限:Supabase默认给每个项目的PgBouncer连接数为50,可在控制台数据库设置中查看;
- 计算单个Prisma实例的
connection_limit:假设你有N个Cloud Run实例,每个实例的connection_limit应设为floor(50 / N),比如10个实例时每个设为5,避免总连接数超出PgBouncer上限; - 确认连接字符串指向PgBouncer端口(Supabase默认是6543,而非Postgres默认的5432),你已看到PgBouncer有连接,这一步大概率没问题,但建议再核对端口。
2. connection_limit在PgBouncer场景下的意义
并非无意义,反而必须设置,但要合理取值:
- 若移除
connection_limit,Prisma会使用默认连接池上限(通常为10),当Cloud Run实例数量较多时,总连接数会快速超出PgBouncer上限,导致所有实例都无法获取连接,反而加重超时问题; - 你之前移除参数后无效果,是因为未配合调整实例数量或PgBouncer总连接数,而非参数本身无用;
- 结论:不能移除该参数,需根据实例数和PgBouncer总连接数计算合理值。
3. 连接超时问题的具体解决步骤
按优先级执行以下操作:
步骤1:调整Prisma连接池参数
- 修改连接字符串中的
connection_limit为计算后的值,也可在Prisma Schema中显式配置(更直观):datasource db { provider = "postgresql" url = env("DATABASE_URL") pool_size = 5 // 对应connection_limit,与计算值一致 pool_timeout = 10 }
步骤2:优化PgBouncer连接回收
- 在Supabase控制台调整PgBouncer的
idle_timeout(默认300秒),缩短闲置连接回收时间,比如设为60秒,让PgBouncer更快释放闲置连接给新请求; - 确保API请求结束后Prisma连接正确释放:Express中避免长时间持有未关闭的查询,不要在全局请求外保留未完成的数据库操作。
步骤3:优化Cloud Run实例配置
- 设置Cloud Run实例数的最大限制:根据PgBouncer总连接数和单个实例的
connection_limit计算,比如PgBouncer上限50、单个实例connection_limit=5,则最大实例数设为10,避免自动扩缩容导致连接数超限; - 确认Cloud Run的连接复用功能开启(默认开启),减少实例创建频率。
步骤4:排查连接泄漏
- 用
SELECT * FROM pg_stat_activity WHERE application_name = 'Prisma Client'查看Prisma连接状态,若存在大量idle in transaction进程,说明存在连接泄漏(比如未提交/回滚事务、异步查询未正确处理); - 修复代码中的泄漏点:确保所有事务通过
await prisma.$transaction(...)正确处理,避免未完成的异步操作持有连接。
内容的提问来源于stack exchange,提问作者truthordare
相关产品推荐
相关产品推荐

