☰
Codex 史诗级bug在后台疯狂写盘,我的 SSD 差点被它磨穿:用 TaoToken 统一通道排查 SQLite TRACE/WAL 写盘风暴
2026/9/26 9:18:57 网站建设 项目流程

1. 从一次系统卡顿说起:Codex 后台写盘风暴是怎么被发现的

Codex 是 OpenAI 推出的本地编码代理工具,能在终端里读写项目文件、跑命令、开流式会话,适合高频跑自动化任务和长时间 coding 的开发者。但我在连续用了几天之后,发现一个很不对劲的现象:切会话变慢、命令响应拖沓,连平时很稳的系统盘都出现了持续写入。打开活动监视器一看,磁盘写入曲线几乎是一条平线,没有波峰波谷,就是一直在写。

一开始我以为是项目太大、会话历史太多,清理了一轮缓存也没用。后来把范围缩小到 Codex 的本地状态目录,才定位到真正的元凶:~/.codex/logs_2.sqlite。这个 SQLite 日志库在 TRACE 日志级别下会持续高频写入,而且不是简单追加,它带着 WAL 模式一起刷盘。你盯着主库文件大小可能觉得没怎么涨,但 WAL 文件在后台一直写,SSD 的 TBW 就在悄悄消耗。

我实际采样了一次:短短 15 秒内,MAX(id)增加了 2,978 条记录,TRACE 级别占了绝大多数日志量,处理前 WAL 文件已经涨到 46,601,352 字节。这不是偶发写一下,是持续高频写盘。如果你也是高频跑 Codex、开流式输出、跑自动化任务,这个问题值得第一时间检查。下面我把完整的排查思路、可复制的配置骨架、以及用 TaoToken 统一通道接入的步骤整理出来,你可以直接跟着做。

2. 前置准备:用 TaoToken 统一 Key 和 API 通道

在动手改配置之前,先把模型接入通道理顺。我这次用 TaoToken 作为统一入口,原因是它把模型对话、Coding Plan、API Keys 管理放在同一个控制台里,排查问题时不用在多个平台之间切换。官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 端点是 https://taotoken.net/api 。

你需要先拿到一个可用的 Key。进入控制台后,在 API Keys 页面创建一个新 Key,复制出来备用。如果你主要跑长期编码任务或 Agent 流程,可以看一下 Coding Plan 的额度说明;如果只是验证模型连通性,用模型对话页面就能快速测试。接入文档在 doc 页面有完整的参数说明,ClaudeCodeAnthropic 相关的配置也有单独示例。

拿到 Key 之后,把它写进环境变量,避免硬编码到配置文件里:

export TAOTOKEN_API_KEY="sk-你的实际Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"

这两行可以放进~/.zshrc或~/.bashrc,后面 Codex 的 config.toml 会引用这两个变量。这样做的好处是,后面排查写盘问题时,你可以随时切换 Key 或端点,不用改 Codex 本身的配置。

3. 可复制配置:config.toml 与 settings.json 骨架

Codex 的配置分两层:~/.codex/config.toml管模型接入和运行参数,~/.codex/settings.json管日志级别和本地行为。下面是我实测可用的骨架,你可以直接复制后按需改。

先看config.toml:

# ~/.codex/config.toml model = "claude-sonnet-4-20250514" provider = "taotoken" [providers.taotoken] base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" wire_api = "chat" [history] persistence = "sqlite" max_entries = 5000 [logging] level = "WARN" trace_enabled = false

这里有几个关键点。logging.level从默认的 TRACE 改成 WARN,直接砍掉绝大部分内部细节日志。trace_enabled = false是第二道闸,防止某些子模块绕过全局级别继续写 TRACE。history.max_entries限制会话历史条数,避免历史表无限膨胀。

再看settings.json:

{ "log_level": "warn", "trace": { "enabled": false, "sqlite": { "wal_autocheckpoint": 1000, "journal_mode": "WAL" } }, "telemetry": { "enabled": false } }

wal_autocheckpoint设成 1000 页,意思是 WAL 累积到约 4MB 就触发 checkpoint,把数据合并回主库并截断 WAL。默认值可能偏大,导致 WAL 长时间不回收。telemetry.enabled = false关掉非必要的遥测写入,减少额外 I/O。

改完这两个文件后,重启 Codex 让配置生效。如果你不确定当前配置是否被正确加载,可以在 Codex 启动时加--verbose看它打印的配置路径和日志级别。

4. 验证请求:观测写入量并确认修复效果

配置改完只是第一步,关键是用系统工具验证写入量真的降下来了。我分三个动作来做:采样数据库增长、观测 WAL 文件、用系统级工具看磁盘写入速率。

第一个动作,采样 SQLite 记录增长。在 Codex 运行期间,每隔几秒查一次MAX(id)和行数:

sqlite3 ~/.codex/logs_2.sqlite \ "SELECT MAX(id) AS max_id, COUNT(*) AS row_count FROM logs;"

修复前我测到 15 秒内MAX(id)涨了 2,978。修复后同样 18 秒的窗口,MAX(id)固定在 20,494,551,row_count固定在 97,318,没有再增长。这说明 TRACE 写入已经被拦住了。

第二个动作,看 WAL 文件大小:

ls -l ~/.codex/logs_2.sqlite-wal

修复前 WAL 是 46,601,352 字节,修复后持续保持 0 字节。WAL 不再增长,意味着 checkpoint 正常工作,写放大被控制住了。

第三个动作,用系统工具看真实磁盘写入。macOS 下可以用iostat:

iostat -d disk0 2

Linux 下用iotop或/proc/diskstats:

cat /proc/diskstats | grep nvme0n1

重点看kB_written或wr_ios这一列。修复前 Codex 空闲时磁盘写入也有持续底噪,修复后底噪明显下降。如果你看到写入速率在 Codex 空闲时仍然很高,说明还有别的写入源没堵住,需要回到第 5 节继续排查。

5. 本篇常见错排查:TRACE 残留、WAL 不回收、误判文件大小

排查过程中我踩了几个坑,这里列出来帮你省时间。

第一个坑是只看主库文件大小。logs_2.sqlite本身可能没怎么涨,但-wal文件在疯涨。SQLite 的 WAL 模式下,写入先落到 WAL,主库文件不会立即变大。所以你用du -sh看目录,很容易低估真实写盘量。正确做法是同时看主库和 WAL 两个文件。

第二个坑是改了logging.level但 TRACE 还在写。原因是某些子模块有自己的日志开关,不继承全局级别。这时候要检查settings.json里的trace.enabled是否也关掉了。两个地方都改,才能彻底拦住。

第三个坑是 WAL 不回收。如果你看到 WAL 文件一直很大,不缩回去,检查wal_autocheckpoint是否生效。可以手动触发一次 checkpoint:

sqlite3 ~/.codex/logs_2.sqlite "PRAGMA wal_checkpoint(TRUNCATE);"

执行后 WAL 应该被截断到 0 字节。如果还是不行,可能是 Codex 进程持有连接没释放,需要先停掉 Codex 再执行。

第四个坑是误判写入源。我一开始怀疑是别的会话或插件导致的,后来用采样法排除:在 Codex 完全空闲时采样,如果MAX(id)还在涨,那就是 Codex 自身在写;如果不涨,再开一个会话观察,逐步缩小范围。

如果你在接入 TaoToken 时遇到 401 或 403,先检查TAOTOKEN_API_KEY环境变量是否在当前 shell 生效,可以用echo $TAOTOKEN_API_KEY确认。如果 Key 没问题但请求失败,去 API Keys 页面确认 Key 状态和额度,接入文档里有完整的错误码对照表。

6. 长期编码场景:用 Coding Plan 和统一通道收尾

把写盘问题压下去之后,我重新跑了一轮长时间编码任务,连续开了几个流式会话,同时用iostat盯着磁盘。这次写入曲线恢复了正常的波峰波谷,不再是一条平线。Codex 的响应速度也回来了,切会话不再拖沓。

如果你也是高频跑 Codex、跑 Agent 自动化,建议把日志级别和 WAL 参数作为标准配置固化下来。模型接入这边,用 TaoToken 的统一 Key 和 API 通道,配合 Coding Plan 的额度,可以在一个控制台里管理多个模型的调用,排查问题时不用来回切换平台。需要验证模型连通性时,模型对话页面可以直接测;需要管理 Key 时,API Keys 页面和接入文档能覆盖大部分场景。

最后留一个实用技巧:把第 4 节的采样命令写成一个 shell 脚本,每次 Codex 升级后跑一次,确认写入行为没有回归。SSD 的 TBW 是消耗品,提前拦住比事后换盘划算得多。

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

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

立即咨询