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={
<>
- 更新按钮不会跳过备份、镜像摘要、迁移或健康检查。
+ 每次在线更新都会重新备份数据库,并校验镜像摘要、迁移结果和服务健康状态。