在結束故障并清除了問題后,GitLab給出一個帖子,總結了導致長達18小時服務中斷的原因、他們計劃如何繼續發展,以及整個事故是如何發生的。
數據庫的高負載在一開始被診斷為大量垃圾郵件的涌入。但是在進一步審查后,明確了是由于無事生非的家伙將一位GitLab員工舉報為濫用,事故因此而惡化了。另一位員工在審查濫用報告時并沒有意識到被舉報的賬號其實是團隊中一位工程師的賬號,因此意外地刪除了該賬號:
我們隨后發現這一部分負載是由一個后臺任務試圖去移除GitLab員工及其相關數據所導致的。這就是他們的賬號被標識為濫用并意外地被刪除的結果。
根據作為當事人的工程師在故障報告中的記錄,他的賬號被刪除是因為“我們收到來自一位用戶的垃圾郵件報告,該用戶是在發出垃圾郵件報告的10分鐘前創建的。這就產生了人為錯誤,刪除了我的所有項目。”
由于數據庫負載的加重,預寫式日志 (WAL,Write-Ahead Log)在得到從數據庫處理之前就被主數據庫清洗掉了,導致主數據庫停止向從數據庫復制。不幸的是,WAL歸檔也并未被打開。WAL歸檔會要求數據段在得到移除許可前被歸檔。
由于復制已經停止了,需要對從數據庫做一次重建。啟動復制需要一個空的數據目錄,因此一位工程師手工清理干凈了一個目錄。但該目錄并非是從數據庫的數據目錄,他意外地清除了主數據庫的數據目錄。
雖然主數據庫的不幸損失應該只會讓站點關閉一小段時間,但是對于GitLab團隊而言事情更糟。在努力恢復數據的過程中,團隊發現自己的備份無法工作。作為備份的主要方法的pg_dump由于版本不匹配的問題而不能運行,因此并未備份任何東西。沒有人知道存在這個失敗,通知郵件因為不支持DMARC被服務器拒收。
其它的備份方法也因為各種原因而無法使用,團隊并未對數據庫使用Azure磁盤快照。即使使用了磁盤快照,在線取回數據也將花費很長的時間:
每個存儲賬號的限制大概為30TB。恢復快照時使用同一存儲賬號中的主機通常會完成得很快。但是當用在不同存儲賬號中的主機時,完成該過程將需要數小時乃至數天。
唯一的方法是恢復事故發生之前六個小時的LVM快照。
團隊在改進他們的修復恢復過程中碰上了14個問題,最終完成了快照的恢復。他們在事故發生后兩個星期中實現了WAL-E,功能是將WAL數據段實時地歸檔到AWS S3。對一次恢復的測試表明,這種備份類型在兩個小時以內就可以恢復到指定的時間點。此外,他們正在實現一個自動測試PostgreSQL備份恢復的系統。
查看英文原文: GitLab.com Postmortem Digs into Root Causes of 18 Hour Outage