Smail/docs/配置事务崩溃恢复补充验收.md
smail b4edc6f7c2
Some checks are pending
Security Checks / security (push) Waiting to run
修复配置事务准备残留阻塞启动并完成崩溃恢复实机回归
2026-09-22 00:09:13 +08:00

130 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 配置事务崩溃恢复补充验收
## 范围与结论
本项接续双 SQL 未提交复制中断验收,验证配置事务落盘、根配置切换与启动恢复。**本项不等于整个项目生产验收通过。**
- [✓] 真实终止测试子进程,而非仅在阶段钩子返回错误。
- [✓] 验证三种数据库配置选择下的回滚、保留新配置、重复启动与损坏拒绝启动。
- [✓] 修复新事务准备阶段崩溃残留导致下次启动被阻塞的问题。
- [✓] 云端重复终止测试、完整配置包回归与本地全量后端回归。
- [✓] 最新后端候选的隔离应用级 SQLite 迁移、邮件和重启回归。
- [ ] 完整应用的 SQL 提交与配置切换联合故障点、恢复过程再次被终止。
- [ ] 同一最终完整发行候选的统一生产验收与正式部署。
用户提供的管理员、域名和部署入口仍仅为测试参数,不转为产品验收标准。没有修改或暂存用户原来的 `云端全项目测试报告.md`,没有停止正式实例或其他项目。
## 修复的问题
旧实现先在 `data/transaction/<id>` 创建原始和候选目录,再写配置归档及首份事务清单。若在清单发布前突然退出,恢复扫描会遇到没有清单的活动目录,保留现场并拒绝启动。原配置虽然未变,但无法自动恢复可用。
新实现先写入 `data/transaction-staging/<id>`,完成归档、清单与目录同步后,再把整个目录原子重命名到活动事务区。发布之后才允许修改活动配置文件。
- 发布前突然退出:活动配置保持原样,残留暂存不参与启动恢复,也不阻塞下一次提交。
- 发布后发生错误:保留完整活动事务,由既有恢复算法决定回滚还是保留新配置。
- 暂存路径拒绝符号链接,避免配置归档写出预期目录。
- 旧版活动区中的无清单、损坏或不可信记录继续失败关闭,不自动删除或当作正常事务接受。
- 崩溃暂存保留为证据;这是文件归档目录,不是新增数据库。清理策略不在本次修复范围内。
没有向 HTTP、环境变量或正式运行配置增加故障注入开关。新增准备阶段钩子由测试直接设置,等待和强制终止逻辑均位于测试二进制。
## 故障矩阵与证据边界
每种 SQLite、MySQL、PostgreSQL 配置分别覆盖:
| 故障位置或状态 | 恢复结果 | 注入方式 |
| --- | --- | --- |
| 准备目录已创建、尚未写归档 | 保持旧配置,后续提交正常 | 正式提交路径钩子处终止子进程 |
| 归档与清单完整、尚未发布活动事务 | 保持旧配置,后续提交正常 | 正式提交路径钩子处终止子进程 |
| 已发布 prepared 清单 | 恢复旧配置 | 正式阶段钩子处终止子进程 |
| 仅一个分区被替换 | 恢复旧配置 | 使用正式原子替换函数构造落盘状态后终止 |
| 所有分区已替换、根配置未切换 | 恢复旧配置 | 正式阶段钩子处终止子进程 |
| 根配置已切换,清单仍是 sections_committed | 保留新配置 | 使用正式原子替换函数构造落盘状态后终止 |
| root_committed 清单已写入 | 保留新配置 | 正式阶段钩子处终止子进程 |
| verified 清单已写入 | 保留新配置 | 正式阶段钩子处终止子进程 |
另有两个强制终止后损坏归档的用例:分别改坏 original、candidate,启动必须拒绝,活动配置及损坏现场保留。独立测试保留旧版无清单活动目录的失败关闭行为,并验证暂存符号链接拒绝。
父进程确认到达目标点后强制终止子进程并等待退出;Linux 日志记录 `signal: killed`。随后两次调用正式 `NewConfigManager` 启动路径,检查代次、数据库选择、配置文件逐字节一致、锁释放及恢复幂等。
**上述三种数据库是配置选择矩阵,不是三种真实数据库的提交联合测试。** SQL 配置故意使用不可用的本地端口,证明文件恢复不依赖连接 SQL,也不会回退创建额外 SQLite。分区部分写入和根清单滞后是明确构造的磁盘状态,不声称在真实应用中捕获了对应指令间隙。再次成功启动不等于恢复途中再次被杀;进程强制终止不等于整机断电或物理存储耐久性验证。
## 验证记录
证据目录:`test-log/production-remediation-20260921/`。时间均为北京时间;本轮从 2026 年 9 月 21 日晚间开始。
### 修复前专项
云端目录:`/var/tmp/smail-review-transaction-20260921-234828/`。
- 原阶段专项重复三次:81 个测试及子测试通过,60 次强制终止,零失败、零跳过。
- 配置包:406 项通过,1 项跳过。
- 该结果不包含后续暂存发布修复,不能替代最终修复版本。
### 修复后专项
云端目录:`/var/tmp/smail-review-transaction-20260921-235343/`。
| 范围 | 通过 | 失败 | 跳过 | 说明 |
| --- | ---: | ---: | ---: | --- |
| Linux 崩溃专项重复三次 | 114 | 0 | 0 | 78 次确认的 SIGKILL |
| Linux 完整配置包 | 417 | 0 | 1 | 内含 26 次 SIGKILL;真实数据库集成测试未配置 |
| Windows 完整配置包 | 401 | 0 | 15 | 权限、符号链接及真实 SQL 等平台条件分别保留跳过 |
| Windows 全量后端 | 1945 | 0 | 42 | 62 个包通过,另有 22 个无测试文件包 |
测试及子测试计数包含父级条目,不是独立业务用例数;不同范围有重叠,不相加当作全量生产验收。
最终 Linux 配置测试二进制 SHA256:
```text
5f36f1cd0c5f5f182b3ea96fb9dcf599ee6db0773cc93d3368406e8b4ac46d76
```
对应构建输入:`transaction-build-20260921-235343.json`。其中 revision 是修改前源码基线,实际工作区改动以逐文件源码摘要为准,并非该提交的干净构建。
关键日志及结果:
- `transaction-linux-20260921-235343-result.json`
- `transaction-linux-20260921-235343-crash.log`
- `transaction-linux-20260921-235343-config.log`
- `transaction-staging-windows.jsonl`
- `transaction-full-backend-windows.jsonl`
首次编写专项时,预期配置没有包含加载后的规范化结果,导致断言失败;改为读取归档原始字节并单独核对数据库选择。扩大 Windows 回归时发现就绪文件读取与文件操作之间的短暂共享冲突,改用目录标记。两次失败日志均保留,不覆盖为成功结果。
### 隔离应用级回归
使用最新后端重新编译的 Linux amd64 候选,隔离实例为 `/var/tmp/smail-review-runtime-20260921-235814/`,构建基线为 `b8dbd3b` 加本轮未提交修复;逐文件摘要在最终复核时确认未漂移。程序 SHA256:
```text
89e115d94ef2f12fd2ab082888f22517460e87cbe9e1b5a98d32f55ae38426b8
```
以下应用级项目通过:
- 全新隔离初始化及邮件协议探针。
- 占用目标拒绝覆盖,失败后释放维护状态;正常迁移完成配置切换。
- 切换后待重启期间拒绝写入;内部重启保持进程,进程级重启使用新进程。
- 原登录会话、历史邮件与新增邮件的正文、附件通过 IMAP、POP3 验证。
- 目标库不可用时失败关闭;源库和配置未被改写;恢复访问后邮件闭环继续正常。
- 配置历史随业务迁入目标库;新增邮件只进入目标,源库不再写入。
- 最终活动数据库为 `migrated.db`,完整性检查为 `ok`。`smail.db` 与 `occupied.db` 为离线源库及占用目标证据,不是第二个活动数据库。
应用级证据 13 份位于 `transaction-runtime-evidence/smail-review-runtime-20260921-235814/`,汇总为 `transaction-runtime-result-20260921-235758.json`,构建输入为 `transaction-runtime-build-20260921-235758.json`。
**该应用回归是 SQLite → SQLite,不把它扩展成最新候选的 MySQL/PostgreSQL 实机迁移验证。** 前端与 Linux 插件资源只复用并核对摘要,不宣称完整发行包已重新构建。正式实例未替换。
## 安全与运行保护
云端配置测试使用全新目录及每用例独立临时目录,不连接正式数据库。测试以普通 smail 用户运行,使用私有网络、私有临时目录、只读系统、受保护路径和资源上限:192 MiB 硬内存上限、128 MiB Go 目标、单 Go 调度线程、25% CPU、禁止交换。
修复前后两轮配置测试均确认正式六服务运行标识、PID 和重启次数未变,正式程序摘要未变;测试单元结束后全部停止且 PID 为零。原用户报告摘要保持:
```text
A142FAA660487656124A8BD4A3EF4F58ED80B3DEC0EDA4AAB0F20B8C3297FF08
```
应用回归后的独立复核记录为 `transaction-final-recheck.json`:21 个远端程序、工具及日志文件摘要一致,710 份构建输入未漂移,六个已核查测试单元停止且 PID 为零。隔离应用的活动事务与暂存区均为空;正式六服务和程序、用户原报告保持不变。验证只读查询摘要,不再次下载大程序或重复执行已完成测试。
历史凭据轮换、剩余静态安全告警、真实浏览器闭环、Windows 提权恢复通道、真实自动续期与全协议换证、外部最终投递、长时容量、告警、异机灾备及最终统一发行候选等门禁仍未关闭。