概要:
上一篇中,在拦截 TRACE/DEBUG 日志的 Trigger 生效时,Procmon 监控一小时的总写入量约为 10.14MB。
后来更新 Codex 并撤销 Trigger,我又监控了一小时。这次 logs_2.sqlite 相关文件的总写入量变成了194MB。
也就是说,撤销 Trigger 后的写入量约为之前的 19 倍。这其中主库写入 70MB, WAL 写入 123MB 。
查看日志来源
先统计数据库最新一条日志之前 60 秒内,各日志级别和 target 的写入数量:
1 | WITH cutoff AS ( |
从结果来看,官方移除无价值日志的维护已经起效,之前提到的那些日志没有再出现。
不过,目前仍然存在高频写入的 TRACE 日志。(例如TRACE codex_app_server::outgoing_message)
检查WAL写回主库频率及数据量
在 Procmon 中设置以下过滤条件:
Process Name is codex.exe
Path is C:\Users\用户名\.codex\logs_2.sqlite
Operation is FlushBuffersFile
持续监控一小时,共捕捉到 17 次针对 logs_2.sqlite 主库的刷盘操作:
刷盘通常发生在checkpoint后写回主库时,因此可近似认为这一小时内完成了 17轮 checkpoint。
即 WAL 达到阈值 → 将 WAL 的更改写回主库 → WAL 从头记录 的过程约重复了17次
继续修改过滤条件为Operation is SetEndOfFileInfomationFile,得到这17次刷盘前SQLite设置的主库大小
图中 Detail 的 EndOfFile: 14,286,848 代表: SQLite 需要让主数据库文件增长到这个大小,才能继续写入后面的页面。
也就是说在这一小时 17 次的写回主库操作中,主库大小从 14 MB → 26 MB → 38 MB,实际增长了约 24 MB 的大小。
按数据库页大小为 4096 B 计算,就是净增加了 5839 个数据库页面。
不过实际上主库的总写入量约为 70 MB , 即还有约 46 MB 的写入是更新了主库中已有页(可能是清除日志或其他操作)。因此主库文件的实际增长量只有约 24 MB 而非 70 MB 。
可以看到图中当前主库的文件大小为 38 MB , 和最后一次 EndOfFile: 38203392 设置的数值一致。
DB Browser 可能影响 WAL 重置
监控期间,logs_2.sqlite-wal 从 4 MB 增长到了 14 MB。
如果 DB Browser 仍保持读取连接,例如正在浏览数据或执行查询,checkpoint 可能执行不完全,WAL 也无法重置并从头复用,因此会越长越大…
不过主要原因应该还是清除 Trigger 后 TRACE 日志增长过快导致的。
处理建议
- DB Browser 查询完后,点击关闭数据库释放连接。
- 如果是命令行查询,一次性命令完成后 SQLite 会自动关闭连接;如果进入了 sqlite> 交互模式,则需要使用 .quit 退出。
- 如果 WAL 已经很大,彻底关闭 Codex、ChatGPT 和 DB Browser。最后一个 SQLite 连接关闭时通常会执行最终 checkpoint,并清理 WAL、SHM 文件。
下次打开 Codex 后,WAL 会重新开始增长。
logs_2.sqlite、WAL 与 SHM 三者的关系
logs_2.sqlite:保存已经 checkpoint 的基础数据。logs_2.sqlite-wal:保存已提交、但还没写回主库的页面更新。相比主库数据更新logs_2.sqlite-shm:WAL 的临时索引和锁状态,帮助 SQLite 定位最新页面。
查询时: 打开的是 logs_2.sqlite。SQLite 会通过 SHM 检查所需页面在 WAL 中是否有更新版本:有就读取 WAL,没有才读取主库,因此查询到的是两者合并后的最新结果。
- 如果主库丢了,单靠 WAL 通常无法还原完整数据库;
- 如果 WAL 暂时没 checkpoint,单独复制主库则可能缺少最新提交。
因此不要在 Codex 运行时只复制 logs_2.sqlite 做备份,最好使用 SQLite 的 .backup 命令或先正常关闭所有连接。
关于 WAL 和主库写入量差值的说明
WAL 写入 123 MB,主库写入 70 MB,这两个之间有差值是正常的。
- 这是因为 WAL 会记录多个修改版本
可能中间改了10次,但主库只在 checkpoint 时记录最终的版本只写最新一个。
TODO
综合下来本次监控发现:去除 trigger 后修复版本的日志写入量仍然偏大,计划再找时机监控取多段数据分析。
如果后续写入量仍然居高不下,考虑继续应用 trigger 拦截或者启用 RUST_LOG 按模块定向过滤日志
评论