8.8
深览指数
科技腾讯新闻·浮之静··AI 生成

Codex 日志正在燃烧你的 SSD

本文揭示 OpenAI Codex 因持久化 SQLite 日志 sink 默认接收过宽 TRACE 来源,导致高频写入 SSD、消耗寿命的严重工程缺陷。作者梳理了五个层面:日志的角色、SQLite 写放大机制、关键 GitHub issue 证据链、用户偏方(trigger、tmpfs 软链、迁移介质)的有效性边界,以及上游应做的真正修复。适合重度 Codex 用户、AI 工具开发者及关注本地持久化工程边界的读者阅读。原文 ↗

核心观点
  • Codex 的持久化 SQLite 日志 sink 默认接收过宽 TRACE 级日志,且与用户可见的 `RUST_LOG=warn` 过滤器不同步,导致高频 SSD 写入,问题核心是持久化边界错误而非单纯的日志文件增长。
  • 真正的修复应在上游实施:收窄 SQLite log sink 的默认过滤级别、websocket/SSE payload 不该默认落盘、提供明确的配置开关(如 `sqlite_log_level = "warn"`),而非让用户依赖 trigger、RAM disk 或迁移介质等权宜之计。
  1. 01Issue #17320 确认,即使设置 `RUST_LOG=warn`,`logs_2.sqlite` 仍持续写入 TRACE 日志,流式回复时 `app-server` 进程向 WAL 的写入速率可达 5 MiB/s,峰值约 16 MiB/s。
  2. 02Issue #28224 报告者外推,Codex 日志写入可能达 640 TB/年,但保留日志量仅约 1 GiB,说明'保留数据很小但写入 churn 很大',净增长不能代表 SSD 实际写入。
  3. 03作者核对源码 `c03742ca` 确认,`app-server` 和 TUI 中 SQLite log DB layer 使用 `Targets::new().with_default(Level::TRACE)`,与用户设置的 `RUST_LOG` 环境变量构成独立过滤边界。
  4. 04`logs_2.sqlite` 的 `logs` 表包含 4 个索引(`idx_logs_ts`、`idx_logs_thread_id` 等),每插入一行日志会更新多个 B-tree 索引,后续 prune 删除又会更新这些结构,产生大量物理写入。
  5. 05当前保留策略(10 天、per-thread 约 10 MiB/1000 行)控制的是'最终留下多少日志',而非'为了留下这些日志,磁盘被写了多少次'。
  6. 06`logs_2.sqlite` 可能包含 websocket/SSE 原始 payload,带来隐私风险:低层对话或请求内容可能被持久化落盘。
反方 / 局限
  • 本文主动挖出了'用了 Codex 你的 SSD 一年必死'这个说法的局限:TBW 是保修阈值而非硬死亡线;SSD 的 FTL 和磨损均衡通常防止'烧同一小块';真正危险组合是'高频写入 + 盘接近写满 + 长时间运行'。
  • 网上流传的触发器(`RAISE(IGNORE)`)虽能阻断新行添加,但并非源码修复,会导致反馈日志缺失,且后续版本迁移 schema 时可能被无声删除,需要用户升级后复查。
  • macOS 上软链 `logs_2.sqlite` 到 `/tmp` 基本无效,因为 macOS 的 `/tmp` 是 APFS 路径而非 tmpfs,日志仍在同一块内置 SSD 上,不会减少写入。
36 分钟 · 5 卡片 · 14 资料
读原文 →

概念锚点

前置背景

平行视角

未来推演

延伸追问