Why: Second-instance writes stay closed until an independent replay or an admitted CI gate, plus a second host. Those remaining steps needed a durable spec. Evidence: Task-card evidence rows read the merged PRs, tree equality, CI runs 2783/2810/2816, and Dev main branch protection. Source SELF. Drills were not run. Impact: Docs and the task card only. Checklist grades stay SELF or not started. The collaboration proposal body stays r2.3. Refs: docs/release-multi-instance.md Co-authored-by: Cursor <cursoragent@cursor.com>
4.9 KiB
U7 独立重放规格(未执行)
状态:规格。本文件不记录一次已经完成的重放,也不改变 放行检查单 的证据等级。第二实例写流量保持关闭。
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。
tests/ops/self_check.shtests/ops/run_backup_drill.shtests/ops/run_fault_drill.sh --fault all- 用隔离的 PostgreSQL 跑
make test-multi-instance(见tests/integration/multi-instance/README.md)。这套库使用文档中的示例端口时, 不要占用演练的 18980–18999。 - 在
modules/backend执行:
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