Prisma's pgbouncer=true on Supabase made every query 4 round-trips (postmortem)
18 hours ago
- 每个数据库查询在六个月内因Prisma与pgbouncer的配置错误导致四次往返,给多个端点增加了显著延迟。
- 预订页面的崩溃是由于加载原始相机图像造成的,但修复后揭示了一个更严重的性能问题:可用性检查耗时8-10秒。
- 根本原因在于使用了pgbouncer=true的事务模式,迫使Prisma将每个查询包装成四条语句(BEGIN、PREPARE、EXECUTE、DEALLOCATE),每条语句都需要经过网络传输。
- 修复方法是将端口5432切换为会话模式并设置connection_limit=5,从而消除了额外的往返开销,使大多数页面的性能提升了3-4倍。
- 问题最初被误诊为地理延迟,但实际测量显示这是由于每次调用的开销而非缓慢的工作导致,导致在缓存和其他层上浪费了精力。
- 修复验证涉及检查pg_stat_statements以确认DEALLOCATE ALL调用已停止,并使用ss -tnp确保所有连接都使用了正确的端口。
- 关键教训:不随负载扩展的成本属于每次调用的开销,针对同一症状的重复修补表明需要重新测量,承载负载的配置应有文档记录。
- 一个实用的诊断方法:测量本地主机上简单健康检查的时间,测量到数据库的TCP往返时间,如果前者远高于后者,则需检查数据库驱动的行为。