1Panel-dev / 1Panel-dev/1Panel

[Feature] Stop Dependent Application Containers When Restoring Database Backups to Avoid Migration Race Conditions

Open
#13,790 1 comment 0 reactions 1 assignee View on GitHub

@wanghe-fit2cloud is already working on this.

Since Sep 14, 2026.

type: optimization
Dominant language
Go
Stars
37k
Forks
3.4k
Avg merge
9h 16m
Merged PRs (30d)
105

Description

环境

  • 1Panel:v2.2.5(stable)
  • 应用:sub2api(weishaw/sub2api:0.2.3
  • 数据库:PostgreSQL 18.6(1Panel 内建 postgresql 应用)
  • 应用容器策略:restart: always

问题描述

对应用执行「回退」时,1Panel 会连带还原升级前备份里的数据库 dump(sub2api.sql.gz)。但整个还原过程中,restart: always 的应用容器始终在运行、每秒重启,而该应用在启动时会自动执行数据库迁移。两者竞态,导致应用陷入无限重启循环,服务完全不可用。

复现步骤

  1. 安装一个「启动时自动执行数据库迁移」的应用(如 sub2api),关联 1Panel 内建数据库
  2. 升级该应用到一个新版本,再在面板执行「回退」
  3. 回退时 1Panel 还原数据库备份,但不停止应用容器
  4. 观察容器状态:持续 Restarting (1)

实际现象(竞态证据)

还原流程与应用启动迁移相互抢同一张 schema_migrations 表:

# PostgreSQL 日志(还原侧)
CREATE TABLE public.schema_migrations ( ... )      → ERROR: relation "schema_migrations" already exists
COPY public.schema_migrations ... FROM stdin;      → ERROR: duplicate key ... (001_init.sql) already exists
ALTER TABLE ONLY public.schema_migrations ADD CONSTRAINT ... PRIMARY KEY → ERROR: multiple primary keys

关键竞态循环:

  1. 还原流程 DROPschema_migrations
  2. 应用容器恰好在这一秒重启,migrations_runner 立刻 CREATE TABLE IF NOT EXISTS schema_migrations 建回一张空表
  3. 空表 → 应用从 001 开始按文件名重放全部迁移
  4. 还原流程再想 COPY 数据进去时,主键已被应用写入的记录占用 → 报错
  5. 最终 schema_migrations 内容不完整,应用迁移记录与真实 schema 脱节

根因

1Panel 的应用回退把「换镜像」和「还原数据库」绑定执行,却没有先把依赖该数据库的应用容器停掉。而 1Panel 其实持有「应用 ↔ 数据库」的关联信息(应用的 docker-compose.yml / 环境变量里 DATABASE_HOSTPANEL_DB_* 等字段就是证据),只是在还原前没有用它来做停容器/加锁的保护。

期望行为

在「应用回退」或「还原数据库备份」流程中:

  • 若目标数据库被某个 restart: always 的应用依赖,应先 stop 该应用容器,还原完成后再 start;
  • 或者,至少在确认弹窗中明确警告「还原将影响正在运行的应用 X,建议先停止该应用」。

影响面

任何「1Panel 部署 + 启动时自动迁移 + restart: always」的应用(sub2api 只是一例)都会踩中;一旦触发即无限重启,且用户很难从现象直接定位到「回退流程不停容器」这个根因。

补充说明

上游 sub2api 的迁移非幂等是本次「无限重启」的直接卡点,我已单独提 issue:https://github.com/Wei-Shaw/sub2api/issues/7030 。但即便上游修复了非幂等,1Panel 这边「还原数据库前不停依赖应用」的竞态依然存在,属于独立的流程改进点,故单独提此 feature request。

期望:还原流程把「停止依赖应用」纳入标准步骤(或至少给出警告),从面板层面规避这类竞态。

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.