diff --git a/CHANGELOG.md b/CHANGELOG.md index a902d7abc..67ace08c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## v1.2.2-preview.2 + +- 在线更新页明确提示每次升级都会重新备份数据库,并校验镜像摘要、数据库迁移与服务健康状态。 +- 数据库结构升级到 schema v2,为迁移记录时间增加索引,用于真实验证在线升级中的事务迁移与版本一致性检查。 + ## v1.2.2-preview.1 - 管理后台新增“系统配置 → 系统更新”,自动检查 GitHub Release、比较当前运行版本并展示发布时间、更新日志、前置检查、持久化进度、备份和回退状态。 diff --git a/VERSION b/VERSION index 012c0f6d9..3864d38eb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.2.2-preview.1 +v1.2.2-preview.2 diff --git a/backend/internal/database/migrations.go b/backend/internal/database/migrations.go index 937ec3bf6..83e119dee 100644 --- a/backend/internal/database/migrations.go +++ b/backend/internal/database/migrations.go @@ -8,9 +8,10 @@ import ( "gorm.io/gorm" ) -const CurrentSchemaVersion int64 = 1 +const CurrentSchemaVersion int64 = 2 const baselineSchemaChecksum = "sha256:open-ai-canvas-schema-v1-20260830" +const schemaMigrationAppliedAtIndexChecksum = "sha256:schema-migrations-applied-at-index-v2-20260830" const postgresSchemaMigrationLockID int64 = 73123910420260830 @@ -38,6 +39,11 @@ type migration struct { var schemaMigrations = []migration{ {version: 1, name: "baseline_gorm_schema", checksum: baselineSchemaChecksum, apply: migrateSchemaV1}, + {version: 2, name: "schema_migrations_applied_at_index", checksum: schemaMigrationAppliedAtIndexChecksum, apply: migrateSchemaV2}, +} + +func migrateSchemaV2(tx *gorm.DB) error { + return tx.Exec("CREATE INDEX IF NOT EXISTS idx_schema_migrations_applied_at ON schema_migrations (applied_at)").Error } func MigrateSchema(db *gorm.DB) error { diff --git a/backend/internal/database/migrations_test.go b/backend/internal/database/migrations_test.go index 8b8fcd82d..3843ccc6f 100644 --- a/backend/internal/database/migrations_test.go +++ b/backend/internal/database/migrations_test.go @@ -23,6 +23,9 @@ func TestMigrateSchemaRecordsAndValidatesVersion(t *testing.T) { if !status.Ready || status.Current != CurrentSchemaVersion { t.Fatalf("unexpected schema status: %#v", status) } + if !db.Migrator().HasIndex(&schemaMigration{}, "idx_schema_migrations_applied_at") { + t.Fatal("schema migration v2 did not create the applied_at index") + } if err := MigrateSchema(db); err != nil { t.Fatalf("migration should be idempotent: %v", err) } diff --git a/docs/content/docs/backend/backend-database.mdx b/docs/content/docs/backend/backend-database.mdx index e73f12ee3..cf370d2c3 100644 --- a/docs/content/docs/backend/backend-database.mdx +++ b/docs/content/docs/backend/backend-database.mdx @@ -15,6 +15,8 @@ description: 影策后端核心持久化表与状态边界 容器内命令 `migrate-schema up` 应用缺失迁移,`migrate-schema status` 输出当前和期望版本,`migrate-schema verify` 只检查兼容性。`CANVAS_AUTO_MIGRATE=true` 仅用于开发和旧部署兼容;受管生产部署设置为 `false`,并由 Compose 的一次性 `migrate` 服务先完成迁移。后续迁移必须新增版本,不得修改已经发布迁移的实现或校验和。 +当前结构版本为 2。版本 2 为 `schema_migrations.applied_at` 增加 `idx_schema_migrations_applied_at` 索引,用于验证在线更新中的顺序迁移、事务提交和版本健康检查。 + ## 技能包与版本 | 表 | 用途 | 关键边界 | diff --git a/web/src/pages/admin/settings/system-update-page.tsx b/web/src/pages/admin/settings/system-update-page.tsx index e3d2e3e21..6dd4b5644 100644 --- a/web/src/pages/admin/settings/system-update-page.tsx +++ b/web/src/pages/admin/settings/system-update-page.tsx @@ -178,7 +178,7 @@ export default function SystemUpdatePage() { status={} footer={ <> - 更新按钮不会跳过备份、镜像摘要、迁移或健康检查。 + 每次在线更新都会重新备份数据库,并校验镜像摘要、迁移结果和服务健康状态。