Sentry 在 2015 年 7 月遇到 PostgreSQL 引發的災難,這一切都與 XID 的設計有關。

PostgreSQL 官方網站聲明 [1],XID 是 32 bits,理論上限為四百萬筆交易。為了避免這個問題,最好每二百萬筆交易時就要執行 VACUUM。否則一旦超出這個上限值時,整個 PostgreSQL 的 MVCC (INSERT / DELETE / UPDATE 依據此實作) 都會失效。

不幸地,Sentry 就是遇到這個問題。在這次慘痛事件後,Sentry 建議 PostgreSQL 的使用者們,如果你的系統負載很高,而你又關閉 AUTOVACUUM 時,最終你會因為 XID 達到上限值而使得 MVCC 不再正常運作,造成資料遺失等各種麻煩問題。

另外文中更指出,網路上很多人建議關閉 AUTOVACUUM,改以排程或手動選擇負載低的期間執行 VACUUM。但 Sentry 認為這是不明智的,你只要知道不運行 AUTOVACUUM 會帶來的各種嚴重後果就會明白了。

The internet is full of awful advice of users suggesting you should turn off autovacuum, or run it manually at low traffic times, or simply adjust its schedule to run less often. To know why that’s ill-advised, you first need to understand the consequences of autovacuum not running.

回顧我在 2015 年 4 月分享的【淺入淺出 MySQL & PostgreSQL】[2]。其中 59 ~ 69 頁及 133 ~ 134 頁有專門提及這點。(簡報後來新增 Sentry 案例)

當 PostgreSQL 官方網站及 Sentry 慘痛經驗都建議不要輕易關閉 AUTOVACUUM 時,我想大家也就不用輕易相信網路上那些建議關閉 AUTOVACUUM 改以手動的【專家們】了。

參考連結

[1] PostgreSQL: 23.1. Routine Vacuuming [2] 淺入淺出 MySQL & PostgreSQL