SuperSync 服务器 migrate deploy 停在 P3009 错误时怎么处理?

发布时间:2026/9/14 7:11:03
SuperSync 服务器 migrate deploy 停在 P3009 错误时怎么处理? SuperSync 服务器 migrate deploy 停在 P3009 错误时怎么处理【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity如果你用 Super Productivity 的 SuperSync Server 做自托管同步执行./scripts/deploy.sh时数据库迁移阶段反复报P3009deploy 就会一直停在“应用迁移”这一步后面的容器替换和健康检查都走不到。P3009的含义在 README 中很明确上一次 deploy 在 Prisma 把一个迁移记录为 failed 之后被中断了此后每次prisma migrate deploy看到这条 failed 记录都会拒绝继续migrate found failed migrations in the target database。也就是说P3009本身不是新的错误而是“有一个迁移卡在 failed 状态”——处理目标是清掉这条记录并把该迁移正确地应用掉。处理前的前提在部署机上有一份 super-productivity 仓库的 checkout进入packages/super-sync-server目录.env已配置好JWT_SECRET、DOMAIN、POSTGRES_PASSWORD等因为恢复操作依赖其中的DATABASE_URL。确认 PostgreSQL 版本。受支持版本是PostgreSQL 16 或更新bundled compose 镜像是postgres:16-alpine。PostgreSQL 14/15 仍能应用所有迁移scripts/migrate-deploy.sh只会警告后继续但不被测试套件覆盖。注意硬性下限Linux 主机上的 PostgreSQL 14。迁移管线会在连接上设置client_connection_check_interval更老或非 Linux 的服务器会以 FATALunrecognized configuration parameter拒绝每个迁移连接什么都不会应用。一个容易混淆的场景如果迁移在20260828000003上因老服务器拒绝22023存储参数而 failed之后每次 deploy 都会死在P3009上。这种情况升级数据库才是正解迁移脚本不会替你自动恢复这种形态。主路径重新执行 deploy.sh让脚本自动恢复SuperSync 的部署流程把“应用迁移 失败恢复”都收在镜像内的 scripts/migrate-deploy.sh 中它与prisma/migrations在同一个镜像构建里版本天然对齐deploy.sh、镜像启动 CMD、Helm 的migrate-dbinitContainer 三个调用点走的都是它。这个脚本对P3009的处理逻辑是从 Prisma 的报错输出中解析出卡住的具体迁移名根据该迁移 SQL 的形态不是名字决定走哪条恢复路径drop-then-create 的CONCURRENTLY索引迁移SQL 里同时含DROP INDEX CONCURRENTLY和CREATE INDEX CONCURRENTLY例如部分operations表索引脚本会先结束上一次中断 deploy 遗留的孤儿CONCURRENTLY构建它仍持有表锁会让 DROP 卡死然后把这个 failed 记录migrate resolve --rolled-back在 Prisma migrate 之外逐句执行该迁移自己的migration.sql最后migrate resolve --applied标记已应用并重试migrate deploy。这条路径是幂等的先 DROP 再 CREATE正好清掉半构建的INVALID索引。lock-bounded 迁移恰好两条语句SET LOCAL lock_timeout 1s~5s 一条ALTER INDEX ... SET (...)如 fastupdate 回滚命令对应的operations_entity_ids_ginreloption 迁移这类迁移必须留在 Prisma 事务里执行SET LOCAL不能拆分脚本会把 failed 记录标为 rolled back 后原生重试migrate deploy每个迁移最多MAX_LOCK_ATTEMPTS10次预算按迁移计换一个失败迁移名会重置计数。两条路径都走不通的形态包括故意不自动恢复的裸CREATE INDEX CONCURRENTLY脚本会 fail loudly并打印可直接复制的手工恢复命令绝不会替你盲目标记 applied。所以P3009的第一处理动作就是清掉阻塞源见上一节的阻塞说明后重新运行 deploycd super-productivity/packages/super-sync-server ./scripts/deploy.sh恢复成功时你会看到类似这样的输出脚本实际文案 Recovering migration_name outside Prisma migrate (CONCURRENTLY cannot run in a transaction)... Clearing any orphaned CONCURRENTLY index build left running by an interrupted prior deploy... migration_name applied out-of-band and marked applied. Retrying prisma migrate deploy after recovering migration_name...lock-bounded 路径则是 Rolling back failed migration record for bounded native retry: migration_name Retrying prisma migrate deploy after bounded native recovery for migration_name (attempt N of 10)...自动恢复不覆盖时按脚本打印的手工步骤恢复对于不属于上面两种形态的迁移普通 DDL 迁移、裸CREATE INDEX CONCURRENTLY等migrate-deploy.sh退出非零并打印 copy-paste 形式的手工恢复命令形如sh scripts/migrate-deploy.sh --prisma migrate resolve --rolled-back migration_name printf %s\n 该迁移的第一句 SQL | sh scripts/migrate-deploy.sh --prisma db execute --schema prisma/schema.prisma --stdin # …逐句执行该迁移的全部 SQL且每句都成功后… sh scripts/migrate-deploy.sh --prisma migrate resolve --applied migration_namemigration_name就是 Prisma 报错里那个反引号包裹的迁移目录名--prisma是脚本自己的窄封装等价于加超时地执行npx prisma …不打印数据库凭据。在 compose 环境下脚本会把等价命令打印成docker compose run --rm --no-deps -T supersync sh scripts/migrate-deploy.sh --prisma …形式直接照抄即可。脚本同时给出明确警告先调查迁移本身不要盲目--appliedNot auto-recovered. Investigate the migration; do not blindly mark it applied.。如果同一迁移在 out-of-band 恢复后又失败脚本会再次打印手工步骤并退出此时需要人工核对prisma/migrations/name/migration.sql与数据库实际状态。另外两个相邻边界文档里与P3009区分得很清楚避免误诊P1002迁移 advisory lock 被占这不是迁移失败什么都没应用只是另一个数据库会话通常是上一次中断 deploy 遗留的一次性 migrator 容器持有 Prisma 的迁移锁。脚本会打印清理步骤docker ps -aq --filter namesupersync-migrator | xargs -r docker rm -f清掉孤儿容器必要时用pg_locks/pg_stat_activity找到持锁会话确认它是 idle 且不在跑CREATE INDEX CONCURRENTLY后再pg_terminate_backend(pid)然后重跑 deploy。迁移超时exit 124长事务阻塞CONCURRENTLY构建时发生。处理方式是等阻塞事务结束或在.env中调大MIGRATION_TIMEOUT默认 900 秒deploy.sh会把MIGRATION_TIMEOUT - 30转发为容器内的MIGRATE_STEP_TIMEOUT后重跑。超时中断的CONCURRENTLY构建会留下INVALID索引普通重跑建不回来——drop-then-create 形态重跑 deploy 即可自愈它先 DROP 再建裸 CREATE 形态按打印的步骤先DROP INDEX CONCURRENTLY IF EXISTS。验证处理是否完成migrate-deploy.sh正常退出 0deploy.sh继续完成“启动容器 → 等健康检查”。deploy 成功标志是 Deployment successful!以及Service is healthy at health URLhealth URL 取自.env的DOMAIN即https://DOMAIN/health未设置DOMAIN时用http://localhost:1900/health。之后再次运行./scripts/deploy.sh迁移阶段应直接通过而不再出现P3009——failed 记录已被清理这是“卡住状态已解除”的直接判据也可对照数据库里的_prisma_migrations表确认该迁移状态不再是 failed。注意docker compose pull docker compose up -d不是部署替代RUN_MIGRATIONS_ON_STARTUP默认false容器启动迁移是禁用的生产更新必须走./scripts/deploy.sh否则应用会跑在未应用的迁移上。限制提醒如果阻塞性长事务仍在比如业务高峰期的慢查询lock-bounded 迁移 10 次原生重试耗尽后会保持 rolled back 状态——文档的建议是在低峰期off-hours执行带 schema 变更的 deploy然后重跑。rolled back 状态下重跑 deploy 始终是安全的。参考文档SuperSync Server README部署、P3009/P3018、PostgreSQL 版本下限migrate-deploy.sh恢复逻辑与手工步骤生成规范说明以脚本内注释为准deploy.sh迁移超时、容器清理、健康检查prisma/migrations/README.md迁移编写规则哪些形态可自动恢复、为何裸 CREATE 故意 fail-loudHelm 模板中的 migrate-db initContainer【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考