prisma db push卡住并报P1017错误的原因及解决方法
问题
执行prisma db push时出现卡住现象,随后返回错误:
Error: P1017 Server has closed the connection.
通过查询pg_stat_activity查看当前操作,得到以下SQL语句及状态:
SELECT query FROM pg_stat_activity WHERE usename='...'; query ------------------------------------------------------------------------------------ SELECT t.typname as name, e.enumlabel as value, n.nspname as namespace FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = ANY ( $1 ) ORDER BY e.enumsortorder
该查询对应的wait_event_type为Client、wait_event为ClientRead、state为idle。
使用的是fly.io上的Postgres 14.4数据库,请问该查询为何会卡住?如何解决?
原因分析
从状态参数可以明确:这个查询并没有在数据库端执行时卡住,而是数据库处于等待客户端发送指令的状态,最终因为客户端(Prisma)与数据库的连接被中断,才抛出P1017错误。
具体细节:
ClientRead+idle表示数据库进程已经完成了枚举查询的执行,正在等待客户端(Prisma)读取结果或发送下一个指令,但客户端这边因为某种原因断开了连接- 常见触发场景包括:网络波动导致的连接中断、fly.io Postgres的连接超时限制、Prisma侧的连接配置不合理(超时时间过短、连接池耗尽)等。
解决方法
针对fly.io的Postgres 14.4环境,可按以下步骤排查解决:
1. 调整Prisma连接与超时配置
在schema.prisma中修改数据源配置,延长连接超时时间并合理设置连接池大小:
datasource db { provider = "postgresql" url = env("DATABASE_URL") connectTimeout = 30 // 延长连接超时至30秒,按需调整 poolSize = 5 // 根据Postgres实例的连接配额设置,避免超上限 }
2. 检查fly.io Postgres的连接限制
- 通过
fly pg connections命令或fly.io控制台查看当前连接数,确认是否超过实例的连接配额 - 如果连接数不足,可升级Postgres实例规格,或减少应用端的并发连接请求
3. 优化网络稳定性
- 确保应用部署在与Postgres实例相同的fly.io区域,降低跨区域网络延迟
- 重启应用和Postgres实例,清除异常的挂起连接
4. 验证枚举查询本身的性能
直接通过psql或fly.io控制台执行该枚举查询,确认是否能快速返回结果:
如果查询执行缓慢,可更新系统表的统计信息,帮助Postgres优化查询计划:
ANALYZE pg_type; ANALYZE pg_enum;
内容的提问来源于stack exchange,提问作者Jeffrey Yasskin
相关产品推荐
相关产品推荐

