> For the complete documentation index, see [llms.txt](https://summerain-1.gitbook.io/summerain/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://summerain-1.gitbook.io/summerain/zh-cn/fa-bu-shuo-ming/v2.0.3.md).

# V2.0.3

> 开发预发布版本。此版本从 `dev` 分支发布，后续修改可能较为频繁， 并且不会被默认的 `latest` 镜像选中。

## 概述

v2.0.3 将服务器启动期间的所有 MySQL 结构和配置变更，统一放到一条物理连接所持有的 advisory lock 中串行执行。迁移账本损坏、已记录结构对象缺失、旧版清理失败、基线迁移失败、 版本化迁移失败或默认配置写入失败时，服务器都会在接受流量前停止启动。

此版本没有新增带校验和的数据库版本、图片处理配方或上传 API；变更集中在既有数据库 引导任务的协调、校验和错误报告方式。

## 首次升级的强制步骤

启动第一个 v2.0.3 实例之前，必须停止所有运行 v2.0.2 或更旧版本的后端实例。 不得进行新旧二进制重叠运行的滚动部署。旧版会在 v2.0.3 现在统一持有的 advisory lock 之外执行旧版清理、基线 `AutoMigrate` 和默认配置写入。

一个 v2.0.3 实例成功完成数据库引导后，其他 v2.0.3 实例即可正常启动；它们会通过同一把 数据库范围的锁串行执行引导。

## 变更

### 串行化启动引导

* 用单一的 `BootstrapDatabase(ctx, db)` 入口替换四个相互独立的启动调用。
* 独占一条物理 SQL 连接并在该连接上获取 MySQL advisory lock，在账本校验、旧 token 清理、基线迁移、版本化迁移和默认配置写入全部完成前持续持有连接与锁。
* 基线迁移和配置写入使用干净的 GORM session，同时继续复用已锁定的物理连接。
* 等锁和执行数据库工作时传递调用方 context；释放锁时使用有时间上限的清理 context。
* 所有阶段错误都会返回给 `main`；部分引导失败后不再继续启动 HTTP 服务。

### 迁移完整性与恢复

* 在任何破坏性旧版处理前，校验已知版本、版本连续性、迁移名称和不可变的 SHA-256 校验和。
* 确认已应用账本项所代表的列、索引、表和容量锁种子行仍然存在。
* MySQL 已提交部分 DDL、但对应账本项尚未写入时，缺失操作仍可安全重试并收敛。
* 明确记录 MySQL DDL 会隐式提交；恢复依赖串行化、对象探测、幂等操作和重试， 不承诺事务回滚已经提交的 DDL。

### 旧 token 与配置兼容

* 一次检查全部四个旧版访问 token 列，并通过一条 `ALTER TABLE` 删除实际残留的所有旧列。
* 仅在 `token_hash` 仍存在时删除不兼容的旧 token 行。已经部分迁移且没有该 hash 的表会 保留现代 token 行，只清除剩余旧列。
* 使用冲突安全的插入写入必要默认配置，绝不覆盖管理员已有值，并向上报告查询和插入错误。
* 需要时把旧管理键 `image_token_default_ttl` 复制到规范键 `private_token_ttl_default_ms`，但不会覆盖已经存在的规范值。
* 修正管理网页，使其读写后端实际使用的规范私密 token TTL 键。

### 持续集成

* 后端 CI 任务新增固定版本的 MySQL 8.4.10 服务。
* 新增必须执行的真实 MySQL 引导测试；DSN 缺失时 CI 会失败，而不是静默跳过。
* 覆盖单连接池、重复引导、完整与部分旧 token 状态、无效和不一致账本、context 取消、 并发启动、部分 DDL 已提交后的重试、配置键兼容、seed 错误传播和 advisory lock 释放。
* 在不改变依赖版本的前提下，规范化 Go 直接依赖声明。

## 验证

* MySQL 8.4.10 引导集成测试：9 个场景通过。
* 后端 `go test ./... -count=1`：通过。
* 后端 `go vet ./...`：通过。
* 后端 `go build ./...`：通过。
* 前端 ESLint：通过。
* 前端 Vitest：17 个测试文件，共 131 项测试通过。
* TypeScript 项目与 Vite 生产构建：通过。
* Python requirements 锁文件与发布镜像策略测试：通过。
* GitBook 文档和翻译源哈希校验：通过。
* 现有 wasm-vips 依赖的 direct-eval 警告保持不变，不会导致构建失败。

## 安装

开发镜像必须显式拉取：

```bash
docker pull jaykserks/summerain:dev-v2.0.3
```

等效的精确开发标签：

```
jaykserks/summerain:dev-2.0.3
```

滚动更新的 `dev` 标签也会指向最新一次成功的开发构建。 此版本不会修改 `latest`、`main` 以及稳定的语义化版本别名。

## 已知限制

* 已应用对象校验只能证明账本记录的对象存在，并不会逐项比较列类型、默认值、索引列顺序、 约束或表选项是否与迁移定义完全一致。
* 此引导无法通过事务回滚 MySQL DDL。应修正报告的问题并重新启动，让幂等探测继续收敛结构。
* advisory lock 最长等待 60 秒；历史大表 DDL 可能需要预留更长启动时间的维护窗口。
* 旧 `image_token_default_ttl` 行在复制后仍会保留以兼容旧数据；运行时读取和新的管理写入 只使用规范键。
* 动图支持仍计划在后续版本中提供。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://summerain-1.gitbook.io/summerain/zh-cn/fa-bu-shuo-ming/v2.0.3.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
