CODEX · 日志Bug · SSD寿命
一个 TRACE 级日志配置,让 Codex 一年写入 640 TB。你的 1TB SSD 终身质保才 600 TBW。不到一年,硬盘报废。
一个开发者随手看了下自己 Mac 的磁盘写入量,然后整个人都不好了。
21 天,37 TB。
他用的是 OpenAI 的 Codex CLI——就是那个帮你写代码的 AI 助手。没有跑什么疯狂任务,就是日常用用。
换算一下:一年 640 TB 写入量。一块 1TB 消费级 SSD 的终身写入寿命大概 600 TBW。也就是说,不到一年,一块全新的固态硬盘就能被写到质保报废。
不是什么复杂的系统漏洞。是一个无聊到离谱的日志配置错误。
01
一个 Level::TRACE,毁掉你的硬盘
Codex 内部用了一个 SQLite 数据库来存反馈日志,文件就藏在你的电脑里:
~/.codex/logs_2.sqlite
加上它的两个伴生文件 -wal 和 -shm。
问题出在哪?日志等级被设成了 TRACE——所有等级里最吵、最详细、最暴力的那档。
TRACE 是什么概念?就是你写个 console.log 都嫌不够细,它要把每一次 WebSocket 收包、每一次文件系统事件(包括你打开 /etc/passwd)全记下来。而且它完全绕过了 RUST_LOG=warn 环境变量——你设了也没用。
TRACE 日志占了 70.7% 的存储量,再加上两个 OpenTelemetry 类别(codex_otel.log_only 和 codex_otel.trace_safe),96% 的日志数据是普通用户永远不会去看的垃圾。
02
为什么文件没变大,硬盘却在疯狂写?
这里有个特别阴险的地方。你用 du -sh 看一眼 ~/.codex/,可能觉得不大啊,才一百多 MB?
被骗了。

SQLite 用了一种叫 WAL(Write-Ahead Logging)的机制。它的运作方式是:先写入 → 再删除 → 再写入 → 再删除……数据库文件大小几乎不变,但实际写入量是文件大小的几百倍。
GitHub 上有人做了一个 15 秒的采样:
保留行数:681,774(没变)。MAX(row id):从 5,003,347,015 跳到 5,003,383,226。15 秒,36,211 次插入。保留行数纹丝不动。
每秒钟超过 2,400 次"写入-删除"循环。AUTOINCREMENT 计数器跑到了 55 亿,但实际保留的行只有 50 多万——差距整整一万倍。
你以为 du 看到的就是真相。但在 WAL 模式下,文件大小是个谎言。真正的写入量藏在 WAL 文件的反复冲刷里。
03
不只是 Codex 的问题
这个 bug 从 2026 年 4 月就有人报告了。相关 issue 一抓一大把:
#17320:流式输出时 WAL 疯狂写入,5~16 MB/s。#22444:WAL 文件无限增长,僵尸进程还持有文件句柄。#27911:另一个数据库 goals_1.sqlite 也在疯狂写,11 MB/s。#28997:WAL 文件涨到几十 GB。#29237:数据库超 200MB 后直接崩溃,macOS 报 zsh: trace trap。
桌面版、CLI 版、VS Code 扩展版全部中招。
一个用户在 OpenAI 社区论坛的原话:"为什么这个 bug 被无视了这么久?它严重影响了我的工作流程。" 他甚至专门写了一个 Bash 脚本来自动清理 WAL 文件、杀掉 Codex 进程。
04
怎么确认你中招了?
三步检查,花不了一分钟。
第一步:看文件存不存在
ls -lh ~/.codex/logs_2.sqlite*
第二步:查日志等级分布
sqlite3 ~/.codex/logs_2.sqlite "SELECT level, COUNT(*) FROM logs GROUP BY level ORDER BY COUNT(*) DESC"
如果 TRACE 占比超过 70%,恭喜,中招了。
第三步:观察 WAL 增长
sqlite3 ~/.codex/logs_2.sqlite "SELECT MAX(id) FROM logs;"
等 15 秒再查一次。如果两次差值超过几千,你的硬盘正在被悄悄消耗。
05
最省事的办法:让 Codex 自己修自己
上面那些命令你要一条一条敲?太累了。
直接把下面这段话丢给 Codex,让它自己诊断、自己修。
打开一个新的 Codex 会话,粘贴这段 prompt:
帮我检查 ~/.codex/logs_2.sqlite 是否因 TRACE 日志持续高频写盘。步骤:1. 用 sqlite3 查 logs 表的日志等级分布,确认 TRACE 是否占比超过 50%2. 记录当前 MAX(id),等 15 秒再查一次,看差值是否超过 10003. 如果中招,先备份:cp ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite.bak4. 用 SQLite trigger 拦截写入5. 执行 PRAGMA wal_checkpoint(TRUNCATE) 清理 WAL 文件6. 再次采样 MAX(id),等 15 秒对比,确认不再增长7. 检查 ~/.codex/logs_2.sqlite-wal 文件大小是否归零
对,你没看错。让 Codex 用 sqlite3 去查自己写出来的日志数据库,然后亲手把自己的写入通道堵上。
就像让一个话痨去做自我反省,然后给自己贴上胶带。
它会乖乖执行每一步:查日志分布、采样 MAX(id)、备份、建 trigger、checkpoint WAL、再验证。全程你只需要粘贴一句话,然后看着它输出结果。
这个方案的精髓在于:你不需要懂 SQLite,不需要记命令,不需要手动操作。你只需要告诉 Codex "去查一下你自己的日志是不是有问题"——而它恰好有权限、有工具、有能完成这一切。
如果你更喜欢手动操作,下面章节有完整的分步指南。
06
手动止血:三步搞定
OpenAI 在 6 月 22 日终于合并了修复 PR(#29432 和 #29457),但你可能还没更新到修复版本。在等正式更新之前,你可以自己动手止血。
第一步:备份
cp ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite.bak
这个文件只存内部诊断日志,不存对话内容,丢了不影响你的工作。但备份总是没错的。
第二步:用 SQLite Trigger 拦截写入
社区用户 @synap5e 提出的方案——一行 SQL,直接在数据库层面拦截所有新日志插入:
sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"
这个 trigger 的意思是:每次有新数据想插入 logs 表,直接静默忽略。Codex 不会报错,但什么也写不进去。写入瞬间归零。
第三步:Checkpoint 并清理 WAL
sqlite3 ~/.codex/logs_2.sqlite "PRAGMA wal_checkpoint(TRUNCATE);"
这一条命令会:把 WAL 文件里还没合并的数据写回主 .sqlite 文件,直接把 WAL 文件截断到 0 字节。执行完你会发现 -wal 文件从几百 MB 变成了 0 字节。
验证:确认修复生效
sqlite3 ~/.codex/logs_2.sqlite "SELECT MAX(id) FROM logs;"
等 15 秒再查一次。如果 MAX(id) 不变了,WAL 也不涨了——恭喜,你的硬盘安全了。
想恢复的时候:
sqlite3 ~/.codex/logs_2.sqlite "DROP TRIGGER IF EXISTS block_log_inserts;"
07
更简单粗暴的办法
如果你不想折腾 SQL,还有一个社区方案:把日志文件软链接到内存里。
rm ~/.codex/logs_2.sqlite && ln -s /tmp/logs_2.sqlite ~/.codex/logs_2.sqlite
日志全部写进内存,重启就消失。反正那些日志你也不会看。
08
最让人不安的是什么?
不是 bug 本身。是这个 bug 从 2026 年 4 月就被报告了,拖了将近 3 个月才有人修。
中间有十几个相关 issue,无数社区帖子,甚至有人专门写了 Bash 脚本来自动清理 WAL 文件、杀掉 Codex 进程。OpenAI 的 codex doctor 命令会告诉你"数据库健康",但对几十 GB 的 WAL 文件视而不见。

数以万计的开发者不知道自己的 SSD 正在被一个日志配置慢慢磨损。你花几千块买的 SSD,本来能用五年。现在因为一个 Level::TRACE,可能只能撑一年。而你甚至不知道。
修复速查表
备份:cp ~/.codex/logs_2.sqlite* ~/.codex/*.bak — 防手滑
拦截写入:CREATE TRIGGER block_log_inserts ... — 从源头掐断
清理 WAL:PRAGMA wal_checkpoint(TRUNCATE) — 把几百 MB 的 WAL 清零
验证:SELECT MAX(id) FROM logs 两次对比 — 确认不再增长
软链接(可选):ln -s /tmp/logs_2.sqlite ... — 直接写内存
如果你身边也有人在用 Codex,把这篇文章转给他。这不是危言耸听——37 TB 的写入量是实测数据,640 TB/年的推算基于 21 天的连续监测。
你的硬盘不会喊疼。但 NAND 闪存的写入寿命是有限的。
参考资料GitHub Issue #28224: Codex SQLite feedback logs can write ~640 TB/yearGitHub Issue #17320: Excessive SQLite WAL writes during streamingGitHub Issue #29237: CLI crashes with SIGTRAP when logs_2.sqlite growsGitHub Issue #28997: logs_2.sqlite-wal grows without boundNotebookCheck: OpenAI Codex has a bug that could kill your SSD in under a yearPR #29432 & #29457: Stop logging every Responses WebSocket event / Filter noisy targets
关注「硅基新智讯」,看懂 AI 不迷路
同步更新于知乎「硅基新智讯」
夜雨聆风