使用Prisma迁移至Vercel Postgres时Seed操作超时问题排查
解决Vercel Postgres与Prisma在GitHub Action及部署时的连接超时/段错误问题
问题背景
- 技术栈:Next.js + Prisma,正在从AWS RDS迁移到Vercel Postgres
- 本地执行
db seed命令完全正常,已按照Vercel文档配置专用环境变量:
datasource db { provider = "postgresql" url = env("POSTGRES_PRISMA_URL") // 使用连接池 directUrl = env("POSTGRES_URL_NON_POOLING") // 使用直连 }
- 异常情况:
- GitHub Action中执行seed命令触发段错误:
No pending migrations to apply. Running seed command `ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts` ... Connecting to database An error occurred while running the seed command: Error: Command was killed with SIGSEGV (Segmentation fault): ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts Error: Command "npm run vercel-build" exited with 1 Error: Process completed with exit code 1.
- 本地直接部署到Vercel时出现超时,Lambda函数和GitHub Action均无法连接新数据库
- 改用
@vercel/postgres库排查后,得到明确的超时提示:
数据库服务器 `xxx.us-east-1.postgres.vercel-storage.com`:5432 可到达但连接超时。 请重试。 请确认数据库服务器正在 `xxx.us-east-1.postgres.vercel-storage.com`:5432 运行。 上下文:尝试获取Postgres Advisory锁超时(执行SELECT pg_advisory_lock(72707369))。耗时:10000ms。
解决方案
1. 调整Prisma连接配置与超时参数
在prisma/schema.prisma中延长连接超时时间,同时确保seed脚本使用直连URL:
datasource db { provider = "postgresql" url = env("POSTGRES_PRISMA_URL") directUrl = env("POSTGRES_URL_NON_POOLING") connectTimeout = 30000 // 把连接超时设为30秒 }
在seed脚本里强制指定用直连URL初始化Prisma Client:
import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient({ datasources: { db: { url: process.env.POSTGRES_URL_NON_POOLING, }, }, }); // 你的seed业务逻辑
2. 修复GitHub Action的Node环境依赖
段错误(SIGSEGV)大多和Node版本不兼容或ts-node版本过低有关,在GitHub Action workflow里指定匹配Vercel的Node版本,并升级相关依赖:
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: 配置Node.js 20.x环境 uses: actions/setup-node@v4 with: node-version: '20.x' cache: 'npm' - run: npm install - run: npm install -g ts-node typescript # 安装最新版ts-node和typescript - run: npx prisma migrate deploy - run: npx prisma db seed
3. 禁用Prisma的Advisory Lock(按需操作)
如果超时是因为Advisory锁竞争导致,可以在执行seed命令时跳过锁:
npx prisma db seed --skip-generate --no-advisory-lock
也可以在初始化Prisma Client时配置事务隔离级别规避锁问题:
const prisma = new PrismaClient({ transactionOptions: { isolationLevel: 'ReadCommitted', }, });
4. 验证Vercel Postgres的网络访问权限
- 确认Vercel Postgres的IP白名单包含GitHub Action的出口IP(可以在Action中执行
curl ifconfig.me获取IP,然后添加到Vercel控制台的数据库白名单) - 检查Vercel项目的环境变量是否同步正确,
POSTGRES_PRISMA_URL和POSTGRES_URL_NON_POOLING必须包含完整且正确的认证信息与连接参数
内容的提问来源于stack exchange,提问作者Dejan Vasic
相关产品推荐
相关产品推荐

