跳转到主要内容

事务与恢复

恢复中断的 Managed 操作,了解本地构建顺序与锁行为。

Managed 模式先记录变更,再应用变更。中断后,SOW 根据记录完成或回滚操作。 应使用哪个命令恢复,取决于中断的操作。

恢复中断操作

先查看记录的状态:

sow status -r demo
sow log -r demo
状态 下一步
clean 交付前运行 sow check
dirty 运行 sow build,应用待构建的成员或配置变化
recovering 按下表选择与中断操作对应的恢复命令
error 根据诊断与日志检查报错文件或操作
中断操作 恢复命令
add、rm、Dist 修改或构建 sow build -r demo
init、repo new 或 repo rm 重新运行对应的创建、删除命令
发布 sow publish TARGET
本地或目标垃圾回收 sow gc -r demo 或 sow gc TARGET
移除保留构建快照 sow retain rm GENERATION -r demo
Plain 索引生成或 RPM 清理 使用原选项重新运行 sow create 或 sow prune

SOW 按未完成状态(而非记录的时间戳)选择活动的仓库变更操作,因此系统时钟回拨不会把未完成操作隐藏在更早的已完成记录之后。本地或目标 gc 以及 retain rm 在固定执行计划后中断时,SOW 会保留该计划,再次运行同一命令即可完成中断的清理。

恢复过程如果需要重新生成带签名的元数据,就需要再次访问签名密钥与口令。SOW 不在日志中保存口令值。 可用 --passfile PATH、单个密钥配置或 SOW_GPG_PASSFILE 提供来源;支持版本和优先级见 口令文件。工作区生命周期日志尚待恢复时,用命令行或 环境变量覆盖口令来源,保持日志记录的 sow.yml 不变,其摘要属于恢复校验的一部分。

先修正报错中的输入、配置或存储问题。恢复期间,工作区配置、数据库和私有状态应保持配套。 本地恢复完成后,运行 sow check -r demo。常见错误见故障处理, 发布恢复见 publish。

SOW 记录什么

记录 位置 用途
工作区生命周期日志 .sow/workspace-ops/active.json 协调配置与仓库创建、删除
仓库操作日志 .sow/<repo>.db 记录本地成员变更、构建与维护
发布状态 .sow/<repo>.db 记录目标绑定、固定的发布计划和进度

工作区生命周期恢复会比较当前 sow.yml 的摘要与日志中的新旧配置摘要。 配置替换决定该生命周期变更应回滚还是完成。两者都不匹配时,报告完整性错误。

仓库成员变更使用自己的状态转换:

planned → staged → applied → built → done
                       └────────────→ done_dirty
状态 含义
planned SOW 已记录操作及其范围
staged SOW 已为下一阶段准备输入
applied SOW 已提交期望状态,公开目录可能仍使用上一构建快照
built SOW 已安装生成的公开目录
done 操作完成
done_dirty SOW 已提交期望状态,仍需构建

其他终态包括 rolled_back 和 failed。用 sow log OPERATION -r demo 查看转换和时间。

--skip 通常以 done_dirty 结束。已识别的签名策略变化、构建计划固定前的配置变化, 或受支持的内部契约升级,也可能让已提交操作保留为脏状态。日志会记录原因。 需要时修正配置,再次运行 build。

已提交变更后的错误

数据库提交与后续维护是两个步骤。成员关系或构建已经提交后,仍可能发生检查点或清理错误。 SOW 会在命令输出中保留已提交结果,不会把这些项目报告为已回滚。

先查看命令结果与 sow status,再用 sow log 查看对应操作。 按诊断提示继续执行相应命令。确认结果前,保留原始输入文件。

本地构建顺序

SOW 在同一文件系统暂存并检查输出,再按以下顺序应用:

包字节 → 元数据 → 客户端入口 → 过时元数据清理
  1. 把包字节放入规范 pool/ 路径。
  2. 安装按校验和命名的 RPM 元数据,以及 APT 直接索引和 by-hash 索引。
  3. 安装 RPM 的 repomd.xml 和已配置的签名,或适用的 APT Release、InRelease、 Release.gpg。
  4. 替换持久化后,清理过时元数据。

构建保留紧邻前一代的 RPM 不可变元数据和 APT by-hash 对象,供仍持有旧入口的客户端读取。 显式构建快照保留是独立功能,详见 retain。

脏仓库仍服务最近完成的构建快照。多 Dist 操作中的各视图可能在不同时间切换。 远端 HTTP 请求和缓存也有各自的存续时间;在线目标更新应使用 sow publish。 sow changes 只列出本地文件变化,不执行发布或目标清理。

锁与等待

SOW 通过建议锁协调进程。工作区生命周期使用 .sow/workspace.lock, 仓库写操作使用 .sow/repo-locks/<repo>.lock。需要两把锁时,先取工作区锁。

需要一致快照的读命令使用共享锁。status 探测仓库写锁,无需等写者结束即可报告活动状态。 Plain create 与 prune 锁住目标目录及其父目录。

选项 行为
-T 30s 最多等待写锁 30 秒
-T 0 等待到锁可用,默认行为
-N 只尝试一次,其他写者占锁时立即退出

无法取得锁时退出码为 4。-N 与非零 -T 同用时退出码为 2。 只使用命令支持的锁选项;只读命令不接受这些选项。

文件系统要求

使用支持建议锁、fsync 和原子重命名的本地 POSIX 文件系统,macOS 使用 APFS。 公开文件与私有暂存区应位于同一文件系统。SOW 拒绝控制路径中的符号链接、 非预期文件类型和越界路径,并在替换或删除受控对象前检查文件身份。 网络文件系统不适合作为工作区。

仓库与 Dist 名称使用 [a-z0-9][a-z0-9._-]*,保留名称见 仓库布局。脚本如何处理中断、占锁和完整性错误, 见退出码。

表格阅读