☰
为什么 Codex Provider Sync 同步这么快?揭秘原地字节更新与流式替换两大落盘策略
2026/9/27 9:00:02 网站建设 项目流程

为什么 Codex Provider Sync 同步这么快?揭秘原地字节更新与流式替换两大落盘策略

【免费下载链接】codex-provider-syncSynchronize Codex session provider metadata across rollout files and SQLite state.项目地址: https://gitcode.com/gh_mirrors/co/codex-provider-sync

Codex Provider Sync 是一个本地工具,负责把 Codex 会话的 Provider 元数据在 rollout 会话文件与 SQLite 状态之间保持一致——当你的当前配置切换到新 Provider 后,它会把历史会话文件里的 Provider 信息对齐过来,让旧会话可以继续用。很多用户关心一个问题:会话文件动辄几十 MiB,全量重写一遍不是慢死了?其实它靠的是原地字节更新和流式替换两大落盘策略,核心原则只有一句:只动该动的字节,正文一个字节都不碰。

痛点:为什么"完整重写"是最慢的做法

一次普通的 Provider 同步,真正要改的只有session_meta里的model_provider这一个 JSON 字段,但 rollout 文件里还装着你全部的聊天记录。如果像传统做法那样把整个文件读出来、改一个字段、再完整写回:

  • 几十 MiB 的正文要完整读取一遍
  • 生成一份同样大小的临时副本
  • 再做一次文件系统替换

读、写、替换三个动作的成本,全都花在了一个几乎没变的字段上。Codex Provider Sync 的架构决策文档明确否定了这条路线:ADR-0015 把"等长原地更新"定为性能基线,后续的 ADR-0016 进一步把它固定为 Node Core 的默认行为。

策略一:原地字节更新(PIO-2),只覆写 Provider 那几十字节

这是快同步的核心。当新旧两个 Provider ID 满足条件时,同步器不复制任何文件,而是用文件句柄直接定位到model_provider字面量的字节偏移,只覆写那一段:

  • 新旧 ID 都匹配[A-Za-z0-9._-]+,且JSON.stringify后的UTF-8 字节长度相同(注意是字节,不是字符数)
  • 首行中model_provider位置唯一、原始字面量与预期一致
  • 本次不需要历史模型重写、无多个硬链接目标

这些资格检查由 getInPlaceProviderMutation 完成,成功落盘后,结果里计入inPlaceSessionFiles。效果非常直接:

文件身份不变、文件大小不变、首行以外的正文哈希不变,实际写入的字节数就等于 Provider JSON 字面量的长度。

也就是说,改一个 Provider 的 I/O 量,从"整个文件"降到了"几个字段字节"。Windows 上通过内置的 PowerShell worker 和 windows-provider-bytes.cs 执行同一套句柄协议,POSIX 使用已校验的同一句柄定位写入,两端行为一致。

策略二:流式替换(PIO-3),不等长时正文仍逐字节保持

新旧 ID 长度不同时(比如从openai切到更长的自定义 ID),原地覆写会让后面所有字节错位,此时自动切换到第二条路径:

  1. 在同目录创建临时文件
  2. 只重写首行(更新 Provider 字段,保留 LF/CRLF 分隔符)
  3. 剩余正文以有界流式方式逐块复制,不解析、不重序列化
  4. 校验后原子替换原文件

这条路径允许文件身份变化,结果计入rewrittenSessionFiles,但正文保证逐字节一致——你看到的聊天记录与之前完全相同。关键点是:流式复制只负责"搬砖",绝不做业务解析,所以即使文件再大,也不会因为解析 JSON 而产生额外内存与时间开销。

💡 两种策略的选择完全由 Core 自动完成,你不需要把 Provider 改成固定长度,也没有隐藏的--fast开关——它就是默认行为。

为什么同步器只需要看"第一行"?

两大落盘策略能成立,还有一个前提:业务扫描边界只在首行。普通 Sync 始终取config.toml根级model_provider作为目标(缺失时默认openai),扫描时只解析每个 rollout 的第一行session_meta(见 PIO-1 说明),绝不会为了查模型、cwd 或历史索引去翻几十 MiB 的正文。加密内容只诊断、不修改,其他字段(历史 model、title、SQLiteupdated_at等)一律不碰。

提速不减安全:落盘顺序有严格约束

速度快不代表可以牺牲可靠性。每次写入都遵循固定顺序(PIO-5):

  • 消费一次性 Plan,Home 锁内复核快照与占用状态
  • 无变更目标时直接返回,不创建备份
  • 先做 UndoBackup(默认保留 2 份),再执行首次写入——首次 mutation 前失败意味着零业务写入
  • 中途失败会返回带backupId与阶段信息的partial结果,重新执行即可收敛,也可手动 Restore

一个容易误解的细节:原地写失败时,同步器不会偷偷降级成整文件替换来绕过失败,而是明确报错。宁可失败,不可绕过。

如何确认这次同步真的走了快速路径

同步结果与操作日志会如实报告两种策略各自的实际数量。当一次操作实际重写的会话文件达到 100 个以上时,桌面端结果窗口才会出现默认折叠的"查看提速建议"提示(展示规则见 ADR-0036,它只控制提示展示,不是性能门禁)。你也可以展开概览页的"如何加快同步"说明,了解当前 Provider 是否适合原地更新:

需要手动压测时,可以运行 benchmark-provider-io.mjs 生成参考数据;但项目明确不以 wall-clock 作为门禁——真正的验收由 provider-sync-lite.test.js 这类测试保证:写入字节数精确等于字面量长度、正文尾哈希不变、文件身份与大小不变、每个 rollout 正文至多扫描一次。

快速参考

想深入了解看这里
原地字节更新的原始决策docs/adr/0015-provider-byte-updates-and-fast-sync.md
当前落盘策略与 PIO-1~PIO-6 不变量docs/architecture/NODE_CORE_ARCHITECTURE_ZH.md
原地写与流式替换实现src/session-files.js
Windows 端句柄协议 helpersrc/windows-provider-bytes.cs
存储层四端口设计packages/core/src/infrastructure/codex-storage.js
提速提示与日志布局docs/adr/0036-sync-performance-guidance-and-log-split-view.md

一句话总结:Codex Provider Sync 的快,来自"少干活"而不是"干得快"——能原地覆写几个字节,就绝不复制整个文件;必须复制时,正文也只流过一遍、一个字节都不改。

【免费下载链接】codex-provider-syncSynchronize Codex session provider metadata across rollout files and SQLite state.项目地址: https://gitcode.com/gh_mirrors/co/codex-provider-sync

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询