AI工具

继续排查 Codex logs_2.sqlite:写入速度监控以及官方修复 (二)

发布于 2026-07-12 #Codex#Procmon#SQLite#磁盘I/O#TRACE日志#SSD

概要:

第一次排查时混淆了保留日志量与写入量的概念。在 codex

插入日志 → 写入 WAL → 更新索引 → checkpoint → 合并主文件 → 删除旧记录 → 再插入

的过程中,海量的日志插入导致了高频的写后删循环,配合 SQLiteWAL 预写式日志机制在 SSD 底层产生了极强的写入放大。
也就是说,保留的日志虽然不多,但实际过程中写入+删除的数据量远超正常范围。这才是可能会导致 SSD 损耗的实际因素。

本次排查将聚焦在写入速度监控对SSD的影响检查,以及确认官方修复内容这三点上。



1. Codex日志情况监控

保留行 vs 累计插入行

  • 检查保留行
1
SELECT level, COUNT(*) FROM logs GROUP BY level;

数据库中保留了一共约7000行的日志记录。

检查保留行
  • 检查累计插入行
1
2
3
4
-- 查看历史累计总写入量
SELECT seq FROM sqlite_sequence WHERE name='logs';
--- 或 查看当前表里现存的最大 ID
SELECT MAX(id) FROM logs;

数据库累计插入过579万行记录

检查最大行

由于之前手动清空过一次数据,清除前大约也有7000行的数据量。所以保留的日志量实际约为 1.5万行

1.5万行 vs 579万行
这说明写后删除量可能已经非常庞大。保险起见,需要确认下目前磁盘的I/O和健康情况。


磁盘I/O与健康信息

  • 监控磁盘I/0

win 输入 resmon ,回车打开资源监视器
切换到磁盘选项卡,点击表头的写(字节/秒)使它按降序排列,勾选codex.exe开启独占监控。
可以看到当前总写入才 3,753 字节/秒(大概 3.7 KB/s),属于正常待机状态。

资源监视器
  • 磁盘健康状况

打开 CrystalDiskInfo 软件检查情况。

整体没什么问题。继续监控 codex 单独进程的写入情况。

2. 使用 Procmon 监控

  • 搜索 Process Monitor Microsoft 下载软件
  • 管理员身份运行 Procmon.exe
  • 首先 Ctrl + ECtrl + X 停止并清除捕捉,避免内存消耗

设置过滤器

Filter 菜单中勾选 Drop Filtered Events,避免无关事件占用内存。

Ctrl + L设置如下规则

Process Name  is         codex.exe       Include
Path          contains   logs_2.sqlite   Include
Operation     is         WriteFile       Include(可选)

设置完成后保存,Ctrl + X确保记录为空,Ctrl + E开始捕获。

  • 工具栏上只保留“文件系统活动”,可以关闭注册表、网络和进程活动

分析监控记录

稍等一会儿,主窗口出现如下内容

Procmon1

看到基本都是在写入WAL和更新SHM索引
监控一段时间后(30分钟~1小时), Ctrl + E停止监控


查看累计写入量

打开 Tools → File Summary

Procmon2

By Path 下各日志的 Write Bytes相加,得到闲时(1小时)的总写入量为 10.14MB

这个量级对SSD寿命来说基本可以忽略。


3. 确认官方修复内容

根据GITHUB ISSUE #28224 来看,维护者陆续做了这三件事以修复该问题:

不再记录成功 WebSocket 的完整事件(0.142.0)

旧版本中,每收到一个正常成功的 WebSocket 事件,可能产生三条本地记录:

完整 payload 的 TRACE 日志
一份 OpenTelemetry log
一份 OpenTelemetry trace

修复后只记录如下信息

事件数量 执行耗时 响应时间 解析过程 出错信息

过滤大量无价值日志(0.142.0)

以下日志不再存入本地 SQLite

target=log
codex_otel.log_only
【INFO级】
codex_otel.trace_safe
【INFO级】

同时适用于 cli , desktop app 和 vs code 插件


修复 0.142.0 的过滤漏洞(0.143.0)

142 中排除 target = log 日志时,拦截时日志可能(原本是第三方依赖库的日志)还没有转换为 target = log ,导致 142 版本的拦截失效,仍然有 target = log 绕过检查插入数据库。
0.143.0 中在入库前又检查了一次,确保 target = log 不会写入。


确认完毕,更新本地 codex 到最新版 [0.144.0-alpha.4]


后续观察

更新完毕后,先撤销之前的拦截触发器

  • 记得先关闭 codex 再操作,避免产生临时锁冲突
1
DROP TRIGGER IF EXISTS block_useless_logs;

点击写入更改存盘。

检查日志插入情况

1
2
3
4
5
6
7
SELECT 
strftime('%Y-%m-%d %H:%M', ts, 'unixepoch', 'localtime') as minute,
count(*) as inserts_per_min
FROM logs
GROUP BY minute
ORDER BY minute DESC
LIMIT 10;

检查到每分钟插入日志条数如下
DB1

TODO

利用Procmon持续监控写入量

评论
分享

评论