日前,Gitlab.com發(fā)生了一個大事,某同學誤刪了數(shù)據(jù)庫,這個事看似是個低級錯誤,不過,因為Gitlab把整個過程的細節(jié)都全部暴露出來了,所以,可以看到很多東西,而對于類似這樣的事情,我自己以前也干過,而在最近的兩公司中我也見過(Amazon中見過一次,阿里中見過至少四次),正好通過這個事來說說一下自己的一些感想和觀點吧。我先放個觀點:你覺得有備份系統(tǒng)就不會丟數(shù)據(jù)了嗎?
事件回顧
整個事件的回顧Gitlab.com在第一時間就放到了Google Doc上,事后,又發(fā)了一篇Blog來說明這個事,在這里,我簡單的回顧一下這個事件的過程。
首先,一個叫YP的同學在給gitlab的線上數(shù)據(jù)庫做一些負載均衡的工作,在做這個工作時的時候突發(fā)了一個情況,Gitlab被DDoS攻擊,數(shù)據(jù)庫的使用飆高,在block完攻擊者的IP后,發(fā)現(xiàn)有個staging的數(shù)據(jù)庫(db2.staging)已經(jīng)落后生產(chǎn)庫4GB的數(shù)據(jù),于是YP同學在Fix這個staging庫的同步問題的時候,發(fā)現(xiàn)db2.staging有各種問題都和主庫無法同步,在這個時候,YP同學已經(jīng)工作的很晚了,在嘗試過多個方法后,發(fā)現(xiàn)db2.staging都hang在那里,無法同步,于是他想把db2.staging的數(shù)據(jù)庫刪除了,這樣全新啟動一個新的復制,結(jié)果呢,刪除數(shù)據(jù)庫的命令錯誤的敲在了生產(chǎn)環(huán)境上(db1.cluster),結(jié)果導致整個生產(chǎn)數(shù)據(jù)庫被誤刪除。(陳皓注:這個失敗基本上就是 “工作時間過長” + “在多數(shù)終端窗口中切換中迷失掉了”)
在恢復的過程中,他們發(fā)現(xiàn)只有db1.staging的數(shù)據(jù)庫可以用于恢復,而其它的5種備份機制都不可用,第一個是數(shù)據(jù)庫的同步,沒有同步webhook,第二個是對硬盤的快照,沒有對數(shù)據(jù)庫做,第三個是用pg_dump的備份,發(fā)現(xiàn)版本不對(用9.2的版本去dump 9.6的數(shù)據(jù))導致沒有dump出數(shù)據(jù),第四個S3的備份,完全沒有備份上,第五個是相關的備份流程是問題百出的,只有幾個粗糙的人肉的腳本和糟糕的文檔,也就是說,不但是是人肉的,而且還是完全不可執(zhí)行的。(陳皓注:就算是這些備份機制都work,其實也有問題,因為這些備份大多數(shù)基本上都是24小時干一次,所以,要從這些備份恢復也一定是是要丟數(shù)據(jù)的了,只有第一個數(shù)據(jù)庫同步才會實時一些)
最終,gitlab從db1.staging上把6個小時前的數(shù)據(jù)copy回來,結(jié)果發(fā)現(xiàn)速度非常的慢,備份結(jié)點只有60Mbits/S,拷了很長時間(陳皓注:為什么不把db1.staging給直接變成生產(chǎn)機?因為那臺機器的性能很差)。數(shù)據(jù)現(xiàn)在的恢復了,不過,因為恢復的數(shù)據(jù)是6小時前的,所以,有如下的數(shù)據(jù)丟失掉了:
粗略估計,有4613 的項目, 74 forks, 和 350 imports 丟失了;但是,因為Git倉庫還在,所以,可以從Git倉庫反向推導數(shù)據(jù)庫中的數(shù)據(jù),但是,項目中的issues等就完全丟失了。 大約有±4979 提交記錄丟失了(陳皓注:估計也可以用git倉庫中反向恢復)。 可能有 707 用戶丟失了,這個數(shù)據(jù)來自Kibana的日志。 在1月31日17:20 后的Webhooks 丟失了。
因為Gitlab把整個事件的細節(jié)公開了出來,所以,也得到了很多外部的幫助,2nd Quadrant的CTO – Simon Riggs 在他的blog上也發(fā)布文章 Dataloss at Gitlab 給了一些非常不錯的建議:
關于PostgreSQL 9.6的數(shù)據(jù)同步hang住的問題,可能有一些Bug,正在fix中。 PostgreSQL有4GB的同步滯后是正常的,這不是什么問題。 正常的停止從結(jié)點,會讓主結(jié)點自動釋放WALSender的鏈接數(shù),所以,不應該重新配置主結(jié)點的 max_wal_senders 參數(shù)。但是,停止從結(jié)點時,主結(jié)點的復數(shù)連接數(shù)不會很快的被釋放,而新啟動的從結(jié)點又會消耗更多的鏈接數(shù)。他認為,Gitlab配置的32個鏈接數(shù)太高了,通常來說,2到4個就足夠了。 另外,之前gitlab配置的max_connections=8000太高了,現(xiàn)在降到2000個是合理的。 pg_basebackup 會先在主結(jié)點上建一個checkpoint,然后再開始同步,這個過程大約需要4分鐘。 手動的刪除數(shù)據(jù)庫目錄是非常危險的操作,這個事應該交給程序來做。推薦使用剛release 的 repmgr 恢復備份也是非常重要的,所以,也應該用相應的程序來做。推薦使用 barman (其支持S3) 測試備份和恢復是一個很重要的過程。
看這個樣子,估計也有一定的原因是——Gitlab的同學對PostgreSQL不是很熟悉。
隨后,Gitlab在其網(wǎng)站上也開了一系列的issues,其issues列表在這里 Write post-mortem (這個列表可能還會在不斷更新中)