全球最大開源程式碼平臺GitHub的競爭對手GitLab,昨日驚爆工程師team-member-1(GitLab匿名處理,簡稱甲工程師)誤刪近300GB的正式環境資料,GitLab也緊急啟動修程序,除了利用Google Doc即時更新維修進度外,甚至也利用YouTube全程直播長達8小時的維修資料庫過程。
在這次事件中,GitLab總共損失了6小時的資料,包含開發Issue、合併請求、專案留言等檔案。GitLab表示,此次總有707名使用者遭受波及,5,037個開發專案受到影響。不過GitLab強調,由於Git儲存庫並未受到損害,站方仍然有能力重建在誤刪事件發生前,系統所儲存的專案,「但是我們無法復原這些專案相關的Issue。」
GitLab也在官方部落格上,按照時間順序,揭露此事件的來龍去脈,以及站方做出的相對應策略。根據GitLab,此事件總共可以分成3大階段。
第一波事件:不當使用者試圖癱瘓資料庫
GitLab表示,在世界協調時間(UTC)1月31日晚上6點,站方發現不當使用者(spammer)大量建立程式碼剪貼簿(Snippet),利用此手段攻擊資料庫,使其運作變得不穩定。此時GitLab已經開始介入,除了了解事件外,也要進行反擊。到了晚上9點,由於GitLab資料庫承受過多資料寫入,寫入程序中已經開始產生鎖死(lockup)現象,導致站方系統發生無法進行存取的情況。
面對這群不當使用者的攻擊,GitLab祭出大招,鎖定其IP位置進行封鎖外,也移除不當使用者的帳號。GitLab表示,其中1名使用者,還利用GitLab儲存庫(Repository),假作為CDN服務,讓4萬7千個IP位址都使用單一帳號登入,「導致資料庫的工作流量相當大。」
第二波事件:資料庫運作近乎停擺
GitLab表示,到了晚上10點,已經開始接獲使用者通報,「因為資料庫複製程序Lag的太嚴重,幾乎可說是停止運作」,延遲寫入的資料已經達4GB之多。
而GitLab也表示,資料庫停止運作的原因在於,1號資料庫的流量負載過高,「無法即時將資料寫入至2號資料庫。」
在第二階段中,GitLab首先嘗試修復2號資料庫,但是它並無法連線至1號資料庫,「因為系統預設參數max_wal_senders 中,待命伺服器連線數目過低。」
根據PostgreSQL的官方文件的定義,開發者可以透過max_wal_senders,限制當前待命伺服器數目的最大值。另外,此參數也不可以高於參數max_connections的設定,限定PostgreSQL資料庫伺服器連線數目的最大值。
但即便甲工程師試圖已經將最大連線數,從2千調高至8千,但是2號資料庫仍然無法開始執行複寫程序。
第三波事件:誤刪資料庫的慘劇發生
當晚時間11點,當時決定要下班走人的甲工程師認為,應該是肇因於PostgreSQL檔案目錄的問題,才無法使用備份指令pg_basebackup進行復原,甲工程師決定將該Directory移除。
但是在甲工程師下了清除指令後,才驚覺他並沒有切換目錄,而是直接在儲存正式環境資料的1號資料庫執行。雖然他終止了該命令,但是為時已完,300GB的資料,已經刪掉絕大部分,只剩下4.5GB。
多方備援手段皆不管用
按照常理推論,即使發生如此慘劇,GitLab其他的備份管道也應起作用,不至於無法復原資料。但GitLab坦承,雖然站方擁有LVM快照、日常備份、Azure硬碟快照,以及AWS S3等多種備份機制,「但複寫程序真是脆弱的不得了」,除了容易出錯,相關文件歸檔機制也不佳。GitLab表示,即使擁有5個備援管道,「沒有一個運作可靠。」
在誤刪的慘劇發生後,GitLab已經展開修復行動,試圖從Staging資料庫中尋找遺失的資料。在此次事件中,雖然Git儲存庫未受到影響,「遺失正式環境資料對我們是無法接受的。」GitLab也預計在數天後,公開宣布此事成因及未來的應變措施。
雖然GitLab犯下了相當嚴重的失誤,但是站方不僅第一時間就坦承,同時還利用Google Doc公開維修進度,以及YouTube直播維修資料庫過程。這次GitLab事件的處理,也獲得外國社群的讚許,稱讚其大方面對錯誤,更表示,意外難免發生,而GitLab應該以此次事件為借鏡,繼續往前走。