feat: 引入版本化数据库迁移与 Schema 启动门禁

This commit is contained in:
weijuesen
2026-08-13 22:51:45 +08:00
parent 20bea001ac
commit 8b977e4164
15 changed files with 779 additions and 45 deletions
+32
View File
@@ -804,3 +804,35 @@ MVP 沿用 IoTDB(现状);TDengine 作为生产规模化候选(先基准
### 回滚点
- 删除 `docs/decisions/2026-08-13-remediation-decisions.md`,移除 `后续工作计划.md` Wave 0-4 表和本节即可;无运行时影响。
---
## 2026-08-13 整改 Task 2:版本化数据库迁移与 Schema 启动门禁
### 做了什么
- 采用 `golang-migrate/migrate/v4 v4.18.2`,新增 `server-go/migrations/` 嵌入式迁移包;
- 新增 `000001_baseline.up.sql` / `000001_baseline.down.sql`,覆盖当前 26 张业务表、索引和唯一约束;
- 新增 `internal/database/migrate.go``RunMigrations``CheckSchemaVersion``CurrentSchemaVersion`
- `database.Init` 改为先执行版本化迁移并校验 `schema_migrations`,生产环境忽略 `ALLOW_DEV_AUTOMIGRATE`;开发环境仅显式开启时允许 AutoMigrate
- `config.Config` 增加 `APP_ENV``ALLOW_DEV_AUTOMIGRATE`;README 与物理机部署指南补充迁移说明和环境变量;
- 新增 sqlmock 测试,覆盖版本匹配、版本不匹配、空版本、dirty 状态和嵌入式迁移文件解析。
### 设计思路与决策依据
- SQL 迁移文件作为唯一 schema 事实来源,不使用旧 `silk-db-backup.dump` 中的 app_runtime/public 结构(两套均为旧版);
- 基线 SQL 由当前 GORM 模型 dry-run 生成后人工核对,保留当前模型的 UUID、bigserial、jsonb、varchar 长度、默认值和索引;
- 选择 v4.18.2 而不是 v4.19.1,是因为 v4.19.1 要求 Go 1.24,项目基线为 Go 1.23
- 启动阶段任何 schema 版本缺失、落后或 dirty 都直接失败,避免代码与数据库不一致时继续提供 API。
### 验证结果
- `go test ./...``go vet ./...``go build ./...` 全部通过;
- `internal/database` 迁移版本检查与嵌入式迁移解析单测通过;
- 本机无 Docker/PostgreSQL,未执行真实空库建库、旧库升级和 down 回滚演练;需在开发服务器或本地 PostgreSQL 环境完成,并严格按 AGENTS.md 先备份。
### 回滚点
- 本任务前基线提交为 `20bea00`;回滚可还原 Task 2 提交并恢复 go.mod/go.sum
- 若迁移已应用到数据库,必须先恢复迁移前数据库备份,不能只回滚代码而保留不兼容 schema;
- 本次未连接开发服务器、未执行生产部署。