【无标题】
Codex大bug随时准备烧穿硬盘
Codex 大 bug:为什么说它可能“烧穿硬盘”,以及怎么处理
最近看到一篇文章在说 Codex 有一个“史诗级大 bug”,标题很吓人:随时准备烧穿你的硬盘。
我一开始也觉得这个说法有点夸张,但排查之后发现,它背后的核心问题确实存在:某些版本或运行状态下,Codex 会把大量内部诊断日志写进本地 SQLite 数据库,尤其是 TRACE 级别日志。文件本身看起来可能只有几百 MB,但底层可能在持续写入,长期运行会增加 SSD 的写入量。
这篇文章整理一下整个事情的原因、排查方式和处理方法。
一、这个 bug 到底是什么
Codex 会在本机目录下维护一些状态文件和日志文件,其中一个比较关键的文件是:
~/.codex/logs_2.sqlite
这是一个 SQLite 数据库,主要用来存 Codex 自己的内部诊断日志。
问题出在:里面可能会写入大量非常细的 TRACE 日志,比如:
- 网络连接状态
- websocket 收发状态
- SSE/HTTP 客户端内部事件
- MCP 连接管理
- Codex 内部调试信息
这些日志对普通用户基本没用,但如果持续高频写入,就会带来额外磁盘写入。
更麻烦的是,SQLite 通常还会配合 WAL 文件写入:
~/.codex/logs_2.sqlite-wal
所以你看到 logs_2.sqlite 文件大小没怎么变,不代表硬盘没被写。因为它可能一直在插入、删除、刷 WAL,实际 SSD 写入量比文件大小变化更高。
二、为什么这会影响硬盘
SSD 有一个指标叫 TBW,大概可以理解为“这块硬盘一生可以承受多少写入量”。
普通使用下,这个指标很难被用完。但如果某个程序长期持续写日志,尤其是每秒几 MB 这种级别,就可能明显消耗 SSD 寿命。
这件事的危险点在于:
文件大小不一定持续变大,但底层写入可能一直发生。
所以只看 Finder 里的文件大小,可能会低估问题。
三、可能出现什么现象
如果中招比较严重,可能会出现:
- Codex 越用越卡
- 切换会话变慢
- 电脑磁盘 IO 增加
- 风扇、发热、耗电增加
~/.codex/logs_2.sqlite或logs_2.sqlite-wal持续变化TRACE日志占比很高
如果只是轻度情况,可能暂时感觉不到明显卡顿,但日志仍然在持续写。
四、怎么排查自己有没有中招
可以先看文件大小:
ls -lh ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite-wal
再看日志级别分布:
sqlite3 ~/.codex/logs_2.sqlite "SELECT level, COUNT(*) FROM logs GROUP BY level ORDER BY COUNT(*) DESC;"
如果看到类似:
TRACE|很多很多
INFO|一些
DEBUG|一些
WARN|少量
ERROR|少量
并且 TRACE 占大头,就说明确实有这个问题的特征。
还可以看估算写入量:
sqlite3 ~/.codex/logs_2.sqlite "SELECT level, COUNT(*), SUM(estimated_bytes) FROM logs GROUP BY level ORDER BY SUM(estimated_bytes) DESC;"
如果 TRACE 的 SUM(estimated_bytes) 明显高于其他级别,就更能说明问题。
再观察一分钟,看它是否还在增长:
sqlite3 ~/.codex/logs_2.sqlite "SELECT COUNT(*), SUM(estimated_bytes) FROM logs;"
sleep 60
sqlite3 ~/.codex/logs_2.sqlite "SELECT COUNT(*), SUM(estimated_bytes) FROM logs;"
如果一分钟后行数和 estimated_bytes 还在明显增加,就说明日志仍在写入。
五、解决思路有哪些
常见处理方式有三种。
方案一:加 SQLite trigger 阻止日志继续插入
这是我最推荐普通用户使用的方式。
思路是:给 logs 表加一个触发器。以后 Codex 想往日志表里写内容时,SQLite 直接忽略这次插入。
命令如下:
sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"
这个方案的效果是:
- 不让 Codex 继续写这张日志表
- 减少无意义的磁盘写入
- 不影响项目代码
- 不影响 Git
- 不影响日常让 Codex 写代码、读文件、跑命令
主要代价是:以后本机少了 Codex 内部诊断日志。如果 Codex 自己出问题,官方或开发者可能少一份本地日志用来分析。
对普通用户来说,这个影响通常很小。
方案二:把日志文件软链到内存盘或临时目录
这个方式的思路是:日志照样写,但不写到主 SSD 上,而是写到内存盘或临时目录。
好处是不用改数据库逻辑。
缺点是操作更复杂,重启后可能要重新处理,对不熟悉命令行的人不太友好。
所以我不太推荐普通用户优先选这个。
方案三:删除或清空日志文件
这个只能释放空间,不能解决继续写的问题。
也就是说,你删掉之后,Codex 可能还会继续写回来。
所以这个方案只能作为辅助,不是根本解决。
六、推荐处理流程
更稳妥的做法是:先备份,再加 trigger。
备份命令:
sqlite3 ~/.codex/logs_2.sqlite ".backup '$HOME/.codex/logs_2.sqlite.bak-before-block-log-inserts'"
创建 trigger:
sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"
确认 trigger 是否存在:
sqlite3 ~/.codex/logs_2.sqlite "SELECT type, name, tbl_name, sql FROM sqlite_master WHERE type='trigger';"
如果看到:
trigger|block_log_inserts|logs|CREATE TRIGGER ...
说明已经生效。
再观察一分钟:
sqlite3 ~/.codex/logs_2.sqlite "SELECT COUNT(*), SUM(estimated_bytes) FROM logs;"
sleep 60
sqlite3 ~/.codex/logs_2.sqlite "SELECT COUNT(*), SUM(estimated_bytes) FROM logs;"
如果两次结果一样,说明日志插入已经被挡住了。
七、为什么建议先备份
严格说,logs_2.sqlite 主要是 Codex 的内部诊断日志,不是项目代码,也不是 Git 仓库内容。
但它毕竟是 Codex 自己维护的数据库。改数据库前备份,是一个比较稳妥的习惯。
备份的好处是:
- 如果以后 Codex 官方修复了这个问题,可以恢复原状
- 如果发现 Codex 某个功能异常,可以撤回修改
- 如果误操作了,也有回退点
备份会多占一点空间。比如原文件 268 MB,备份也大概 268 MB。一般来说这点空间不算什么,确认几天没问题后也可以删除备份。
八、如何恢复原状
如果只是想移除 trigger,可以执行:
sqlite3 ~/.codex/logs_2.sqlite "DROP TRIGGER IF EXISTS block_log_inserts;"
如果想恢复备份文件,可以先退出 Codex,然后执行类似:
cp ~/.codex/logs_2.sqlite.bak-before-block-log-inserts ~/.codex/logs_2.sqlite
恢复前最好先确认 Codex 没在运行,避免数据库正在被使用。
九、这件事要不要恐慌
不需要恐慌,但值得处理。
如果你的日志每分钟只是小幅增加,那还不是最严重的情况。但从长期来看,让一个没有实际价值的内部 TRACE 日志持续写 SSD,没有必要。
尤其是新电脑、新 SSD,更适合提前止损。
我的判断是:
这不是会立刻毁掉电脑的 bug。
但它是一个不该长期放着不管的无意义写盘问题。
普通用户最实用的处理方式就是:
备份 logs_2.sqlite
加 trigger 阻止 logs 表继续插入
观察确认不再增长
正常使用 Codex
这样成本很低,也能避免日志继续磨盘。
更多推荐




所有评论(0)