找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4002

积分

0

好友

524

主题
发表于 3 小时前 | 查看: 3| 回复: 0

根据目前公开的 GitHub issue、修复 PR、release note,以及 Notebookcheck、WindowsForum、Developers Digest、Reddit 等社区讨论来看,这次事件更准确的描述应该是:

Codex 在本地 SQLite 诊断日志 上产生了异常高频写入。问题主要出现在 ~/.codex/logs_2.sqlite 及其 WAL 文件上。在长时间运行、流式响应较多、IDE/桌面端常驻等场景下,会造成明显的磁盘 I/O 和 SSD 写入放大。

它不是恶意行为,也不是“运行一次就损坏硬盘”。但它确实是一个真实的工程缺陷,尤其值得重度使用 Codex CLI、Codex Desktop、IDE extension 的用户检查。

一键检查PoC:

帮我检测 ~/.codex/logs_2.sqlite 是否因 TRACE 日志持续高频写盘?

检测结论:~/.codex/logs_2.sqlite 正在被 TRACE 日志高频写入,且是膨胀的主要来源之一。主库约 1.05GiB,WAL 文件 48MiB,最近 5 分钟 TRACE 条数达 2463,估算日志体量约 11.1MB,实时采样显示仍在持续写入。建议将 TRACE 级别降至 INFO 或 WARN。

事件概况

最集中的公开讨论来自 openai/codex 仓库的 issue #28224。报告者称,在约 21 天系统 uptime 后,主 SSD 累计写入约 37 TB;结合进程和文件级别排查,主要持续写入源指向 Codex 的本地 SQLite feedback log。

按这个写入速率粗略外推,年化写入量约为 640 TB。对于一块常见 1 TB 消费级 SSD 来说,这个数字已经接近一些型号的保修 TBW 指标。

需要强调两点:

第一,TBW 不是硬盘寿命的“断崖线”。SSD 超过标称 TBW 后并不会立刻失效。

第二,年化数字是基于特定机器、特定使用方式和特定版本的外推,不代表所有 Codex 用户都会遇到同样写入量。

但这不影响问题本身的严重性。一个开发工具在正常使用中持续写入数 MB/s 级别的诊断日志,不应该被视为正常行为。

问题集中在哪些文件?

公开报告里反复出现的是这几个文件:

~/.codex/logs_2.sqlite
~/.codex/logs_2.sqlite-wal
~/.codex/logs_2.sqlite-shm

其中:

  • logs_2.sqlite 是 SQLite 数据库文件;
  • logs_2.sqlite-wal 是 SQLite 的 write-ahead log;
  • logs_2.sqlite-shm 是 WAL 模式下配套使用的共享内存文件。

真正需要关注的不只是数据库文件本身有多大,而是 WAL 文件是否持续增长,以及 Codex 相关进程是否持续写入这个 WAL。

用户可以先用下面的命令查看大小:

du -sh ~/.codex/logs_2.sqlite*

如果怀疑文件已经被删除但空间没有释放,可以检查是否还有进程持有它:

lsof | grep logs_2.sqlite

这也是很多人容易误判的地方:删除文件名不等于释放空间。如果进程仍然打开着这个文件,系统要等文件描述符关闭后才会真正回收空间。

技术原因:不是“日志大”,而是“日志 churn”

这次问题的核心不只是“生成了一个很大的日志文件”,而是 Codex 的本地持久化日志出现了持续的写入、裁剪和 WAL 重写。

公开 issue 中有一个很有代表性的现象:数据库中实际保留的日志行数大约是几十万级,但 SQLite 的自增 id 已经推进到几十亿级。也就是说,数据库看起来只保存了一部分日志,但历史上曾经插入过海量记录。

这个现象对应的流程大致是:

写入日志记录
写入 WAL
触发分区/保留上限
裁剪旧记录
继续写入新记录
继续裁剪

如果输入日志本身非常高频,这个循环就会造成典型的写放大。

SQLite 的 WAL 模式本身没有问题。问题在于,本来应该较少落盘的 TRACE/debug 级别事件,被持久化到了本地数据库里。对于一个流式交互频繁的 coding agent 来说,这会很快变成高频小写入。

哪些日志来源比较吵?

#28224 的样本看,保留下来的日志里,TRACE 级别占了相当高的比例。高频来源包括:

codex_api::endpoint::responses_websocket
codex_api::sse::responses
codex_client::transport
codex_otel.log_only
codex_otel.trace_safe
log

其中 WebSocket streaming 是重点。

Codex 与模型服务交互时会不断接收流式事件。修复 PR #29432 中提到,在修复前,每个成功的 Responses WebSocket event 会产生多条本地日志记录,包括 payload、OpenTelemetry log event 和 trace event。对于长对话、长任务、工具调用密集的线程来说,这类事件量并不小。

另一个相关 PR #29457 指出,本地 SQLite log sink 曾经对所有 target 启用 TRACE 级别,导致通过 target=log 桥接过来的依赖库日志,以及 codex_otel.log_onlycodex_otel.trace_safe 这类重复 telemetry mirror event 也进入了持久化日志。

这解释了为什么一些用户看到的不是普通日志增长,而是持续磁盘写入。

早期报告里还有一个细节:RUST_LOG 不一定能控制 SQLite 日志

早在 2026 年 4 月,issue #17320 就报告过类似问题:IDE extension 启动的 app-server 进程虽然设置了 RUST_LOG=warn,但 logs_2.sqlite-wal 仍然能看到 TRACE 级写入。

报告者通过 strace 观察到持续的 pwrite64,并用 SQLite 查询确认日志表在 streaming 过程中快速插入和裁剪。这个细节说明,用户在环境变量里降低 Rust 日志等级,并不一定会影响 Codex 内部的 SQLite persistent log sink。

换句话说,问题不是简单的“用户没有关 debug log”。至少在这些报告对应的版本里,持久化日志路径有自己的过滤逻辑,和终端输出日志级别并不完全一致。

官方修复进展

截至 2026 年 6 月 23 日,关键修复已经合并,并进入 Codex 0.142.0 release。

相关变更主要有两项。

第一项是 PR #29432

Stop logging every Responses WebSocket event

修复内容是停止为每个成功的 Responses WebSocket payload 写 TRACE 日志,同时不再为这类 event 额外生成 OpenTelemetry log/trace event。保留的是计数器、耗时指标、响应 timing、解析和错误处理等更适合长期保留的信息。

第二项是 PR #29457

Filter noisy targets from persistent logs

这项变更过滤了 target=log 以及两个重复的 codex_otel mirror target,并让 app-server 和 TUI 共享同一套过滤逻辑。远端 OpenTelemetry export 和 metrics 不受影响。

0.142.0 release note 中也明确写到:减少 persistent-log churn,移除 per-event WebSocket payload logging,并过滤重复 telemetry records。

因此,如果你正在使用较旧版本的 Codex,优先建议升级,而不是只做临时绕过。

用户应该怎么检查?

可以按下面的顺序做一次低风险检查。

第一步,确认版本:

codex --version

如果是 npm 安装,可以升级:

npm install -g @openai/codex@latest
codex --version

第二步,检查本地日志大小:

du -sh ~/.codex/logs_2.sqlite*

第三步,如果怀疑仍在持续写入,可以观察进程和文件:

lsof | grep logs_2.sqlite

Linux 用户也可以用 iotoppidstat -dstrace -e trace=pwrite64 等方式确认写入来源。macOS 用户可以用 Activity Monitor、fs_usagelsof 等工具辅助排查。

这里只看最终文件大小并不够。更有意义的是观察 Codex 相关进程是否在空闲或 streaming 时持续写入。

已经产生大文件怎么办?

建议先退出 Codex CLI、Codex Desktop、IDE extension,以及可能仍在后台运行的 app-server。

然后备份旧日志:

mkdir -p ~/.codex-log-backup
mv ~/.codex/logs_2.sqlite* ~/.codex-log-backup/

重新启动 Codex 后,它会按需要重新创建日志数据库。

确认新版本运行正常、旧日志不再需要后,再删除备份:

rm -rf ~/.codex-log-backup

如果此前已经手动删除过文件,但磁盘空间没有回来,可以优先检查是否还有进程持有 deleted file。最稳妥的处理方式是退出相关进程,必要时重启系统。

不建议在不了解影响的情况下直接修改 SQLite schema、加 trigger 或长期把日志文件软链接到临时目录。这些做法在 issue 里有人作为 workaround 使用过,但它们本质上是在绕过本地诊断日志,不是根因修复。现在既然官方版本已经合并修复,普通用户更应该优先升级。

参考资料

  • GitHub Issue #28224:Codex SQLite feedback logs can write ~640 TB/year and rapidly consume SSD endurance
  • GitHub Issue #17320:Excessive SQLite WAL writes during streaming due to TRACE logs ignoring RUST_LOG
  • GitHub Issue #24275:Codex Desktop rapidly grows logs_2.sqlite / WAL during normal active use
  • GitHub PR #29432:Stop logging every Responses WebSocket event
  • GitHub PR #29457:Filter noisy targets from persistent logs
  • Codex 0.142.0 Release
  • Notebookcheck:OpenAI Codex has a bug that could kill your SSD in under a year
  • WindowsForum:Codex TRACE Logging Bug: SSD Write Explosion Reported in SQLite
  • Developers Digest:Codex Logging Bug Can Write Terabytes to Your SSD
  • Developers Digest:Codex CLI Needs Resource Budgets, Not Just Token Budgets
  • Reddit:Codex almost made me worry about my SSD, so I actually measured it

本文相关信息由云栈社区整理,更多排查经验与讨论欢迎前往 云栈社区 分享交流。




上一篇:45℃液冷技术解析:英伟达Rubin如何打造零水耗AI数据中心
下一篇:Blackwell Ultra B300与GB300深度解读:推理算力时代的新架构体系
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-6-24 23:11 , Processed in 0.594539 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表