當前位置: 妍妍網 > 碼農

不小心刪了公司資料庫,停機45分鐘來得及跑路嗎……

2024-02-25碼農

這本該是一個安靜的周六。

我收到來自支持團隊的訊息,說我們的一個客戶遇到問題。我判斷這個問題的重要程度很高,需要立即解決。15分鐘之後,我明確了問題來源——應該刪除資料庫中的一些損壞訂單。

這一操作聽起來小菜一碟,然而……

一、事故還原

如果你不在創業公司工作,請不要嘲笑我。

由於需要刪除的訂單有幾百個,所以我決定編寫一個簡單的 SQL 查詢語句,而不是手動操作( 警告! )。

實際語句稍顯復雜,在此簡化為:

UPDATE ordersSET is_deleted = trueWHEREidin (1, 2, 3)

也許你已經猜到這場災難的影響範圍……

我按下 CTRL + Enter 並執行這條命令。耗時超過1秒時,我才醒悟過來, 客戶端 DBeaver 看到空的第三行,同時忽略了第四行

沒錯,我刪除了資料庫裏的全部訂單。

我感覺整個人都不好了。

二、恢復過程

深吸一口氣後,我意識到得快速行動起來,不能再犯錯誤浪費時間了。

好在恢復工作執行得很好。

  • 停止系統——約 5 分鐘

  • 建立變更前資料庫(幸運的是我們有 PITR)的複制——約 20 分鐘

  • 在等待期間給老板打電話

  • 根據複制更新生產資料庫的資訊*—— 15 分鐘

  • 啟動系統——約 5 分鐘

  • *因為公司具備多個獨立系統,無法停止所有系統,所以我決定不還原整個資料庫,避免在恢復過程中遺失已完成的更改。公司使用 GCP (Google Cloud Platform,谷歌雲平台) 提供的托管 PostgreSQL,所以我在更新前建立了新的複制,匯出複制中的 id 和 is_deleted 列,然後將結果匯入到生產資料庫中。隨後,使用簡單的 update + select 語句。

    顯然,我本可以輕易避免這長達 45 分鐘的停機時間……

    三、究竟發生了什麽?

    整個事件聽起來是一個你永遠不會犯、愚不可及(甚至在大公司根本不允許犯)的錯誤。

    沒錯, 問題根本不在於錯誤的 SQL 語句,人為的小過失從來都不是真正的問題 。我執行那條命令這一動作,只是整個事故鏈條的最後一環。

  • 為什麽在周末處理生產環境?當時問題並不緊急,也沒有人要求我立刻修復故障,我本可以等到周一再處理。

  • 誰會不先在 QA 環境上執行就貿然在生產資料庫中更改呢?

  • 為什麽我不呼叫 API而選擇手動編輯?

  • 如果沒有 API,為什麽我沒及時與同事溝通,對這一敏感操作雙重檢查?

  • 最糟糕的是,為什麽我沒使用事務? 其實只要用了 Begin語句,一旦出錯,使用 Rollback命令(回滾操作) 就能解決。

  • 錯誤環環相扣,但凡避免任何一個錯誤,都不可能發生事故。這些失誤都可以歸因於:我太自信了。

    不過 好在有序的恢復程式阻止了事故連鎖反應 ,如果無法將資料庫恢復到正常狀態,我都不敢想象後果如何……

    四、與車諾比事故有什麽關系?

    幾個月前,我閱讀了【車諾比:一部悲劇史】,車諾比核電廠發生的一系列錯誤使我聯想起了那個被詛咒的周末事故(無意低估或與車諾比核電廠事故比較)。

  • RBMK 反應爐存在根本技術問題。

  • 以上技術問題並未有效傳達。此前發生過涉及該技術問題的事故,但車諾比團隊並不熟悉。

  • 安全檢查期間,團隊沒有按照規範程式操作。

  • 車諾比核電廠爆炸後,蘇聯政府試圖掩蓋事實,加劇了損害程度。

  • 誰應該負責?

    反應爐設計師?其他電廠團隊未準確傳達所遇到的問題?車諾比團隊?蘇聯政府?

    所有人都難逃其咎。 災難從來都不是由單一錯誤導致,而是因一系列錯誤發生。 我們的工作就是盡早打斷這一錯誤鏈條,並盡力做到最好。

    五、後續

    我對與老板的周一談話沒有太多期待。

    但老板的態度讓我驚訝:「(你要)確保不再出現這種情況。但我更欣賞這樣——你犯錯是因為專註並快速行動,以至於做得越多,搞砸得越多。」

    這就是我所需要聽到的。如果以過於「親切」的態度說:「沒事別擔心,謝謝你修復這個問題!」我反而會感覺虛偽。同時,我已經感覺很糟糕了,所以繼續吐槽我無濟於事。

    事故後的改進:

  • 減少對資料庫直接存取的需求,並建立相關的 API

  • 我總是先在 QA 上執行查詢(顯然,沒有什麽比災難更能給人教訓)

  • 我與產品經理商量,了解真正緊急和可以等待的事項

  • 任何對生產環境進行更刪改操作都需要兩個人來完成,這實際上防止了其他錯誤!

  • 我開始使用事務處理機制

  • 六、可供參考的經驗教訓

    事故發生後,我向團隊同事們講述了詳細過程,沒有隱瞞任何細節,也沒有淡化我的過錯。

    責備他人還是不追責,是一個相當微妙的選擇。 當你犯錯時,就是一個傳遞正確資訊的好機會。

    如果你為此道歉 1000 次,同事會認為,當事情發生在他們身上時,你期待他們也要給出相同反應。

    如果你一笑了之,完全忽視事故影響,同事會認為這程度的錯誤是可以接受的。

    如果你承擔責任、學習並予以改進——同事也會用這種態度行事。

    七、總結

  • 鼓勵行動派,關心客戶,並積極解決問題。 這就是初創企業成功的方式。

  • 犯錯要追究責任,尋找避免事故再次發生的方法。

  • 無需落井下石。 有些人需要更多責任感鞭策,而有些人則需要更多的鼓勵,我更傾向於以鼓勵為主。

  • 作者丨 Anton Zaides 編譯丨onehunnit

    來源丨 zaidesanton.substack.com/p/how-i-destroyed-the-companys-db

    *本文為dbaplus社群編譯整理,如需轉載請取得授權並標明出處! 歡迎廣大技術人員投稿,投稿信箱:[email protected]