# U7 独立重放规格(未执行) 状态:规格。本文件不记录一次已经完成的重放,也不改变 [放行检查单](release-multi-instance.md) 的证据等级。第二实例写流量保持关闭。 2026-10-12 已决定不做容量重放。本规格只覆盖 C5、C4 和 A6,以及对象存储回落。 ## 固定对象 从干净检出开始,物化子模块后再跑命令。默认对象是 Dev `3fb8210f6495a78e70a67af3661bdfe9c00fb9de`,其 gitlink 为: | 组件 | SHA | |---|---| | Backend | `dc736e339d01c59e658abc63c81909059bd6ea02` | | Documents | `05c13a42b14d70f878cc8a51c543e018a7f7a663` | 合入提交与对应 PR head 在本地 `git rev-parse ^{tree}` 上同树。核验输出在任务卡 `.task/feature-u7-release-roadmap.md` 的证据表,来源 SELF。若重放日 main 已前进, 重放者改用新的完整 SHA,并重新读出 backend 与 documents 的 gitlink,写进重放记录。 ## 重放者 重放者是另一个人,或另一台由该人操作的机器。先跑完命令并写出结论,再打开作者收据。 作者保全目录 `u7-k4-retest-preserved-20261013` 与其中的 `task-finish.txt` 属于作者证据。 同一账号下另开一个 agent 会话、或切换角色,不能记成 REPLAY。 `policy/platform-admission.md` 已写明不能把切换 Agent 角色当独立账号。 重放者身份未指定前,本规格不启动。 ## 环境 - 只使用名称前缀 `u7drill` 或 `u7bk` 的实例,端口落在 18980–18999。 - 启动前确认环境里没有 `BLOBSTORE_S3_ENDPOINT`。演练脚本本身不设置该变量。 应用把 `NewS3FromEnv` 返回的空 `*S3` 放进 `blobstore.Store` 接口, `blobstore.IsNil` 把它当成未配置,工件写入 `--artifacts` 目录。 - 已构造的对象存储由 `TestFinishOpenKeepsConfiguredBlobStore` 覆盖,重放时一并跑该测试。 本次不要求另起一台对象存储。 - `tests/ops/lib.sh` 的资源门禁要求数据目录所在盘可用空间至少 100GiB,且 1 分钟负载不超过 16。 不满足时脚本会停,不能改门禁来换一次通过。 ## 最小重放集 按这个顺序执行。每条用 `CMD="<命令>" make evidence` 写入重放者自己的任务卡。 工具写入的来源标签仍是 SELF;审阅记录里另行声明 REPLAY,并写明重放者、主机、命令和对象 SHA。 1. `tests/ops/self_check.sh` 2. `tests/ops/run_backup_drill.sh` 3. `tests/ops/run_fault_drill.sh --fault all` 4. 用隔离的 PostgreSQL 跑 `make test-multi-instance`(见 `tests/integration/multi-instance/README.md`)。这套库使用文档中的示例端口时, 不要占用演练的 18980–18999。 5. 在 `modules/backend` 执行: ```bash go test -count=1 -timeout 15m ./internal/blobstore/ ./internal/store/ \ -run 'TestIsNil|TestNewS3FromEnvFallback|TestFinishOpenTypedNilS3UsesLocalArtifacts|TestFinishOpenKeepsConfiguredBlobStore|TestOpenPostgresTypedNilS3UsesLocalArtifacts' ``` `TestOpenPostgresTypedNilS3UsesLocalArtifacts` 需要真实 PostgreSQL。没有 DSN 时该项记 NOT_RUN,其余四项仍要跑。 ## 判据 C5 以 `tests/ops/run_backup_drill.sh` 写出的 `verdict.json` 为准: | 项 | 通过条件 | |---|---| | K1 | 归档成功且 `failed_count` 为 0,基础备份与逻辑备份清单校验通过 | | K2 | RPO 在 0 到 300 秒之间 | | K3 | 恢复后登录、项目、会话均为 200,且 RTO 不超过 3600 秒 | | K4 | 工件 `checked > 0`、`missing = 0`、`mismatch = 0`,跨用户访问项目和工件均为拒绝 | | K5 | `dup_seq = 0`、`seq_gap_convs = 0`,恢复后的行数落在备份点与故障点之间 | | K6 | 逻辑恢复的行数与备份点一致 | | K7 | 备份文件权限收紧,结果目录无凭据泄漏 | C4 以故障脚本的 F1–F5 与 Redis 轨 G1–G3 为准。G4 降级不可见、G5 启动时 Redis 不通则拒绝, 沿用检查单里的「发现」,不把它们改成产品失败。 A6 以 `make test-multi-instance` 退出码 0 为准。 K4 还要看应用日志里没有 `blobstore.(*S3).Put` 的空指针 panic,并且工件文件出现在该次 `--artifacts` 目录。脚本只在拿不到工件 id 时才写 `finding-upload.txt`;那个文件里的 panic 句子是脚本自带的说明,重放时以应用日志和 `artifacts-verify.json` 为准。 与 2026-10-13 SELF 目录 `backup-20261013-013354` 对照时,比较的是上述判据。 RPO、RTO 的秒数可以不同。判据不一致则阻塞,并按失实登记。 ## 重放记录模板 重放完成后把记录放到 Documents 的 `docs/records/`,并回写检查单的 C4、C5、A6 证据等级。 那一步另需授权。记录至少包含: - 重放者与主机(人,或人操作的另一台机器) - 开始前读取的 Dev、Backend、Documents 完整 SHA - 每条命令、退出码、结果目录名 - `verdict.json` 里的 K1–K7、`rpo_s`、`rto_s` - C4 的 F1–F5 与 G1–G5 - A6 退出码 - 五项单测的通过或 NOT_RUN - 来源声明:审阅记录为 REPLAY;`make evidence` 行仍为 SELF