Codex 狂吃硬碟、一年寫爆 SSD?logs_2.sqlite 暴增的根因與我的 4 個自救解法

目錄

💡 核心結論速覽 (TL;DR)

  • 問題:Codex 的 app-server 會把海量 TRACE 診斷日誌狂寫進 ~/.codex/logs_2.sqlite,串流時實測每秒寫約 5 MiB,WAL 檔能暴增到數十 GB——極端案例單檔 690GB、一年寫入量推估約 640 TB,足以吃掉一顆消費級 SSD 的保固壽命。
  • 不是你的設定錯,也先不用恐慌:這是已知 bug,連 RUST_LOG=warn 都擋不住這條日誌;官方還沒正式修,但它有上限、完全可控、每個後果都有對應解法。
  • 別急著刪整個資料夾logs_2.sqlite 只是診斷日誌,你的對話記錄在另一個 state_5.sqlite,清日誌不會丟對話。
  • 行動:先用一行指令確認自己中了沒,再從「全關後手動清 → 搬到 RAM/別顆碟 → SQLite trigger 擋寫入」四招挑一個下手;附 Windows 與 Mac 做法。Claude Code 架構不同、沒這個問題。

那天晚上我只是想更新一個小專案,系統卻冷冷跳出「磁碟空間不足」。我愣了一下——前幾天明明還有幾十 G 啊。打開硬碟分析想抓兇手,結果排在最前面的不是什麼影片或虛擬機,而是一個我從來沒正眼看過的檔案:~/.codex/logs_2.sqlite-wal。一個「診斷日誌」,居然腫得比我整個專案資料夾還大。

先給你直接的答案:這不是你電腦的問題,也不是你設定錯。這是 OpenAI Codex 一個已經被回報很多次的 bug——它會把大量日誌狂寫進本機的 SQLite 資料庫,悄悄吃掉你的硬碟空間,更麻煩的是會持續磨損你的 SSD。我每天開著 Codex 跟 Claude 跑開發,用得很兇,所以這個坑我是實打實踩到了。

這篇我想把這件事一次講清楚:它到底在你硬碟裡幹了什麼、嚴重到什麼程度(我會老實把數字攤開,但不是要嚇你,是要讓你知道後果在哪、好做判斷)、怎麼花 30 秒確認自己有沒有中,然後重點來了——四個從最安全到進階的自救解法,Windows 跟 Mac 我都寫。最後再聊一個你大概會問的:那 Claude Code、Cursor 也這樣嗎?要不要乾脆先別用 Codex?答案可能跟你想的不太一樣。


先別恐慌,但你該知道 Codex 到底對你的硬碟做了什麼

一句話:Codex 在背景把「給工程師除錯用」的細到不行的日誌,當成正式資料一樣不停寫進硬碟,而且寫的量大到不合理。這件事的根因,藏在一個很反直覺的地方。

正常情況下,程式用 RUST_LOG=warn 這個環境變數,就只會記「警告」等級以上的事件,TRACE、DEBUG 這種雞毛蒜皮的細節會被擋掉。問題是——根據 官方 repo 上一份寫得很細的 issue,Codex 的 extension 確實有正確設定 RUST_LOG=warn(提報者甚至去翻了 /proc 確認),但那條「寫進 SQLite 的日誌管線」根本繞過了這個過濾,TRACE 等級的東西照樣一筆一筆塞進 logs_2.sqlite。等於你家水龍頭關了,牆裡卻有一條管子在偷放水。

放多快?提報者用 iotop 實測,模型在串流回覆的時候,這條管線對 logs_2.sqlite-wal 的寫入大約是每秒 5 MiB,尖峰到 16 MiB。一個只有 50 個 token 的短回覆,日誌表的 id 就跳了大約 5000 列。聽起來有點抽象,我把它換算成你比較有感的數字:

後果

社群實測到的數字

對你的意義

SSD 被狂寫

開機 21 天寫了約 37 TB,外推 約 640 TB/年

很多消費級 SSD 保固寫入量約 600 TBW,等於可能不到一年就把保固額度燒完

硬碟被塞爆

WAL 檔暴增到數十 GB,極端案例單檔 690GB

磁碟一滿,其他程式跟著出狀況、存檔失敗

App 直接打不開

檔案太大,Codex Desktop 啟動逾時

Windows 上會跳「無法存取本機資料庫」,整個開不起來

備份被灌爆

備份系統把每次暴增的日誌一起抄走

Time Machine/雲端備份空間被無謂吃掉

我知道「640 TB/年」「690GB」這種數字看了會心頭一緊。但我想拉你回來一下:這件事雖然嚴重,卻是有上限、可控的。它不會偷你的對話、不會毀你的專案、也不是不可逆的硬體故障——它就是一條沒人關的水管,你只要把閥門找出來關掉,問題當下就停。後面四個解法就是在做這件事。

說個我自己的觀察。我之前寫過一篇,講 AI 代理很會「開」服務卻不負責「關」,電腦被一整排沒人收的背景 node 程序越拖越慢的那個坑,其實跟這次是同一種味道:AI 工具很會「做事」,卻很少替你「節制」。它一邊幫你跑開發跑得飛快,一邊在你看不到的地方寫了幾百 G 的日誌——而它完全沒打算告訴你。認清這個慣性,你就會養成「順手檢查一下它在背景留了什麼」的習慣,這比任何單一解法都值錢。


怎麼花 30 秒確認自己中了沒?

先別急著動手清,花 30 秒看一眼就知道你有沒有中。判斷的關鍵很簡單:去看 logs_2.sqlite-wal 這個檔有多大。如果它明顯比本體 logs_2.sqlite 還大、甚至大到好幾 GB,那你就是中了。

依你的系統,複製對應那行指令貼進終端機就好:

Mac/Linux(終端機)——直接看 Codex 那幾個日誌檔多大:

  • 快速看總大小:du -sh ~/.codex/logs_2.sqlite*
  • 列出每個檔的大小:ls -lh ~/.codex/logs_2.sqlite*

Windows(PowerShell):

Get-ChildItem $env:USERPROFILE\.codex\logs_2.sqlite* | Select Name, @{n='MB';e={[math]::Round($_.Length/1MB,1)}}

怎麼判讀?本體 logs_2.sqlite 通常幾十到一兩百 MB 還算正常範圍;真正會出事的是那個 -wal 結尾的檔(旁邊還會有個小小的 -shm)。只要 -wal 衝到 GB 等級,就代表那條管線正在狂寫,該處理了。如果你是 macOS,還可以打開「活動監視器」看 Code Helper 或 Codex 的「磁碟」寫入欄,常常會看到一個離譜的累計寫入量。

查完先別關終端機,記住那個數字——等等做完解法,你可以再跑一次同樣的指令,看著它從好幾 G 掉回幾十 MB,那種「閥門關掉了」的踏實感,比我多講十句都有用。


logs_2.sqlite 是什麼?刪掉會丟我的對話記錄嗎?

不會。這題我特別獨立出來講,因為它是大家最怕、也最容易因為怕而不敢動手的點:logs_2.sqlite 裡面只有診斷日誌,沒有你的對話內容。你跟 Codex 講過的話、它做過的事、session 狀態,存在另一個完全不同的檔——state_5.sqlite。兩個是分開的,清掉前者,後者一根寒毛都不會少。

稍微解釋一下這幾個檔的關係,你動手時會比較安心。logs_2.sqlite 是本體資料庫;旁邊那個 -walSQLite 的 Write-Ahead Log,預寫式日誌)是它的「暫存草稿本」,新資料會先寫進這裡再慢慢併回本體;-shm 則是配套的共享記憶體索引檔。正常的資料庫,WAL 會定期「結帳」清空、維持很小;但 Codex 這個 bug 是寫入快到 WAL 根本來不及結帳,就一路膨脹下去。

所以結論很乾脆:這三個 logs_2.sqlite 開頭的檔,你都可以放心清,Codex 下次啟動會自己重建一個乾淨的。要保護的是 state_5.sqlite——那個別亂動。把這條界線記住,後面的解法你就能放開手做了。


四個自救解法,從最安全到進階(Windows/Mac 都有)

直接給你結論:大多數人用「方法一(定期手動清)+方法四(備份排除)」就夠了;嫌麻煩想一勞永逸,再上方法二或三。下面這張表先讓你對號入座,細節我接著一個一個拆。

解法

適合誰

要注意的風險

❶ 全關後手動清

所有人;最安全、零設定

要記得定期做;務必先把 Codex 完全關乾淨

❷ 把日誌搬到 RAM/別顆碟

不想一直手動清的人

需要一點設定;搬到別顆碟只是換地方寫,沒減少寫入量

❸ SQLite trigger 擋寫入

進階、想直接治本的人

社群過渡解,官方修好後要記得還原

❹ 把 WAL 排除在備份外

有開 Time Machine/自動備份的人

搭配前面任一招一起做,幾乎零風險

❶ 全關 Codex,再手動清掉日誌檔。這是最安全的解,也是我自己平常在用的。但這裡有個我第一次踩到的坑要先講:我那時直接把檔刪了,空間卻一點都沒還回來。後來才查到原因——只要還有沒關乾淨、或是被暫停(suspended)的 Codex 背景程序握著那個已刪檔案的 handle,作業系統就不會真正釋放空間(這個現象在 issue #22444 講得很清楚)。所以順序很重要:先把 Codex CLI、Codex Desktop、還有 IDE 裡的擴充全部關掉,連背景殘留的程序一起確認收乾淨,再刪 logs_2.sqlitelogs_2.sqlite-wallogs_2.sqlite-shm。如果你不確定背景是不是真的清乾淨了,我整理過怎麼安全地揪出並收掉這些殘留 AI 代理程序,可以搭著一起看。

❷ 把日誌改寫到記憶體,或搬到另一顆碟。這招的精神是:既然它一定要狂寫,那就讓它寫在「不心疼」的地方。Mac/Linux 可以把 logs_2.sqlite 用符號連結(symlink)指到 RAM 碟,例如 /tmp/dev/shm——寫在記憶體裡,重開機自動清空,而既然裡面只有診斷日誌,重開機丟掉完全沒差。做法是先關掉 Codex,把原檔移走,再 ln -s /tmp/codex_logs_2.sqlite ~/.codex/logs_2.sqlite 建立連結。Windows 比較沒有現成的 RAM 碟,但你可以用另一個更省事的方向:把整個 CODEX_HOME 環境變數指到另一顆容量大、你不那麼在意壽命的硬碟(例如機械碟或次要 SSD),讓 Codex 的所有本機狀態都搬過去。要提醒的是,搬到別顆碟只是換地方寫、沒有減少寫入總量,保護的是你的主 SSD;如果你常讓 Codex 在本機跟另一個 AI agent 同時跑,把某些任務改丟雲端容器跑、根本不碰你本機硬碟,有時候是更乾淨的做法。

❸ 用 SQLite trigger 直接擋掉寫入。這是最治本、但也最進階的一招:在那個日誌資料庫上加一條規則,讓任何想寫進 logs 表的動作都被默默忽略。指令是(一樣,先全關 Codex,且你的電腦要有 sqlite3 工具):

sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"

加完之後,那條偷放水的管子就被你從源頭關掉了,WAL 不會再膨脹。老實說我會把這招留給比較熟悉指令的人,而且要記在心裡:這是社群想出來的過渡解,不是官方做法。等哪天 OpenAI 正式修好、或 Codex 改版重建了這個資料庫,你最好把這條 trigger 還原回去,免得之後真的需要日誌除錯時一片空白。

❹ 把 WAL/SHM 排除在備份之外。這招很容易被忽略,但 CP 值很高。有位 macOS 使用者就發現,他的災情有一半是 Time Machine 每小時的本機快照「忠實地」把那個不斷暴增的日誌一起備份,雪上加霜。做法是去你的備份設定(Time Machine、rsync、或任何雲端備份)把 *.sqlite-wal*.sqlite-shm 加進排除清單。它不能阻止寫入,但能擋住「災情被備份放大一倍」這條額外的傷害,建議搭配前面任一招一起做。

四招怎麼選?如果要我一句話建議:先做❶+❹當常規保養,會寫指令、想徹底了事的就上❸。方法二適合 Mac 使用者一勞永逸,或 Windows 想保護主 SSD 的人。


Claude Code、Cursor 也會這樣嗎?要不要換工具就好?

先講最多人關心的:Claude Code 沒有這個問題,而且是架構上就不會有。我自己同時用這兩套,特地去翻了一下——Claude Code(CLI 版)根本不是用 SQLite 來存日誌的,它把對話記錄存成一個個 JSONL 純文字檔,按你實際對話的速度寫,不是像 Codex 那樣有一條每秒狂寫 5 MiB 的熱迴圈;而且它有自動清理機制,舊記錄會定期被收掉。所以那種「日誌資料庫暴漲到幾百 G」的劇本,在 Claude Code 身上不會上演。如果你也卡在 Claude Code 該跑本機還是接雲端、差在哪,那是另一個更值得你花時間想清楚的選擇。

但我也要誠實補一句,免得你以為換工具就一勞永逸:「本機檔案悄悄膨脹」這個類別的毛病,幾乎每個會在你電腦上常駐跑的 AI 工具都可能有自己的版本,只是形式不同。差別在於 Codex 這次是「同一個 bug、被大量回報、數字很誇張」,所以特別值得單獨處理。至於 Cursor,目前我沒看到同規模的 SSD 寫入災情回報,但我不會因此就拍胸脯保證它一定乾淨——任何會在背景跑指令、開服務、寫快取的 agent,都值得你用上面那招「順手檢查一下它佔了多少空間」。這也是為什麼我一直覺得,你掛了哪些 MCP、養了幾個常駐 agent,自己心裡要有本帳。

所以「要不要換工具」的答案是:不必為了這個 bug 就棄用 Codex。它狂寫日誌歸狂寫日誌,幫你跑開發的本事還在,而且這個問題你花十分鐘就能壓下去。換工具的成本,遠比關掉一條日誌管線高。


那要不要先別用 Codex?我會這樣判斷

直接給判斷:除非你已經出現「SSD 健康度肉眼可見地掉」或「Desktop 直接打不開」這種硬傷,否則我不會建議你停用 Codex,先做好上面的自救就好。但這題值得分人來看,我幫你拆成三種情況對號入座:

  • 偶爾用、桌機、SSD 容量大:照常用,做 ❶+❹ 定期保養就好,真的不用緊張。
  • 每天重度用、筆電、SSD 焊死不能換:務必上 ❷ 或 ❸ 主動保護 SSD——這種機器壞一顆碟特別傷,預防成本最低。
  • 已經 Desktop 打不開或空間爆掉:先用下面 FAQ 的急救法把機器救回來,再決定要不要上長期解。

說說我自己的選擇。我每家 AI 訂閱都付費、用量很大,每個月光 AI 工具就是一筆不小的固定開銷,Codex 對我的產出是有實際貢獻的,所以我不會因為這個 bug 就把它砍掉。我的做法是:在本機保留 Codex 跑那些需要直接讀寫我硬碟的任務,但加上❸把日誌源頭關掉;同時把一些「跑久一點、不急著互動」的任務改丟雲端跑,順便避開兩個 agent 在我電腦上搶資源。如果你本來就在考慮要不要為了多個 AI agent 另外配機器或租雲端算力,這個 bug 剛好是個重新算一次帳的好理由——但先別衝動,多半你不需要為它買新硬體。


FAQ 常見問題

我已經刪了 logs_2.sqlite,硬碟空間卻沒還回來,怎麼辦?

九成是因為還有 Codex 的程序握著那個已刪檔案。被暫停或沒關乾淨的 Codex CLI/Desktop/IDE 擴充,會持續抓著被刪 WAL 的 file handle,作業系統就不會真正釋放空間。解法是把所有 Codex 相關程序徹底關掉(含背景殘留),空間通常就會立刻回來;真的不行就重開機,是最暴力但有效的一招。

我設了 RUST_LOG=warn 為什麼還是狂寫?

因為這個 bug 的核心就是「那條寫進 SQLite 的日誌管線繞過了 RUST_LOG 過濾」。你設的 warn 確實生效在一般日誌上,但對這條 SQLite sink 沒用,TRACE 等級的東西照樣寫。換句話說,靠環境變數調不掉,得用上面的方法二、三從別的角度處理。

Codex Desktop 直接打不開了,怎麼急救?

這多半發生在 Windows,因為 logs_2.sqlite 太大、啟動時資料庫初始化逾時。急救法是:在 Codex 完全關閉的狀態下,去 ~/.codexlogs_2.sqlite 開頭的那幾個檔「移到別處」(先別刪,移到桌面備著就好),再重開 Codex。它會重建一個乾淨的日誌庫,通常就能正常啟動,而且不會動到你的對話與設定。

用 trigger 擋寫入,會不會把 Codex 弄壞?

不會弄壞功能,因為被擋的只是「診斷日誌」,不影響 Codex 跑任務或你的對話。唯一的代價是:之後 Codex 端如果真的需要靠這些日誌除錯,會抓不到資料。所以它比較像「把行車記錄器關掉」——平常沒差,真出事少了一份紀錄。記得官方修好後把這條 trigger 還原。

這個問題官方修了沒?我該追蹤哪裡?

目前官方還沒有正式修復,相關回報在 OpenAI 的 Codex repo 上是公開、被標記成 bug、處理中的狀態(具體 issue 編號我整理在文末參考資料,可以加進追蹤)。等到哪天看到正式修復合併、或新版本 changelog 提到日誌行為調整,你就可以把前面那些臨時手段(尤其是 trigger)安心還原。


結論:AI 工具很會做事,但「節制」要你來把關

把這篇收束成一句話:Codex 狂寫硬碟、磨損 SSD 是真的、也確實嚴重,但它不偷你的東西、不毀你的專案,而且十分鐘就能壓下去。你需要的不是焦慮,是一次把閥門關好的動作。

我自己經歷這一輪後最大的體會是:我們把愈來愈多事情交給 AI 代理去跑,它們很會「開」、很會「寫」、很會「做」,卻很少替你「關」、替你「節制」、替你「收尾」。這不代表它們不好用,而是提醒我們——在享受它幫你飛快幹活的同時,也要養成回頭看一眼「它在我電腦背景留了什麼」的習慣。今天是一條暴衝的日誌,明天可能是別的。會檢查、懂得關閥門的人,才真正握著主導權。

今天就花 30 秒,跑一次前面那行指令,看看你的 logs_2.sqlite-wal 現在多大吧。如果這篇幫你省下了一顆 SSD 的壽命,歡迎接著看我怎麼處理「兩個 AI agent 在同一台電腦搶資源」這個更頭痛的題目,或訂閱我的部落格,我會不定期把這類踩過的坑整理成可以直接抄的解法寄給你。


參考資料

 

延伸閱讀