天天看點

【玩轉騰訊雲】使用資料庫Mysql如何避免删庫跑路(資料丢失)

生産環境使用資料庫最怕的就是資料丢失了,下面針對各種資料丢失場景展開。

場景一:人為操作引起,包括:故意的删庫跑路、手抖誤操作。

應對方法:

  • 有備無患,建立備份恢複體系,包括:每天自動備份、備份檔案存到另外一台機器、備份檔案無法删除(dba無備份檔案删除權限)、從備份檔案和binlog恢複資料。是以不要用雲伺服器自建資料庫,而是直接使用雲資料庫,雲資料庫已經把這些都做好了,沒必要去把别人踩過的坑再踩一遍。
  • 做好監控,第一時間發現事故。可以是業務程式讀寫資料庫異常時報警,也可以專門寫監控程式監控全部表是否可讀。
  • 日常容災演練,事故發生後不至于手忙腳亂。包括:資料恢複操作文檔化、流程化,每個月或每個季度,在騰訊雲測試環境練習一次。本文末尾附上騰訊雲資料恢複操作方法。
  • 做好權限管理,按最小化原則,隻配置設定夠用的最少權限,嚴控有删庫權限的人數,減少事故發生。
  • 生産環境操作之前,需要先對SQL評審和測試,減少事故發生。為了恢複資料時好恢複,表結構不要使用外鍵限制、日常最好不要跨表操作。
  • 生産環境操作,需要在業務低谷時段操作。如果誤操作需要恢複,對使用者影響最小。
  • 建立事故懲罰制度,懲罰力度與影響的資料量、故障時長相關。有懲罰,生産環境操作才會小心謹慎。

場景二:硬碟故障,而且壞的很徹底,硬碟資料完全讀不出來了(binlog損毀,無法恢複全部資料)

應對方法:

  • 搭建主從,全部資料存2份,2個硬碟同時故障的機率相比1個硬碟下降了幾個數量級。是以還是建議:不要用雲伺服器自建資料庫,而是直接使用雲資料庫高可用版。高可用版每台主執行個體包含主備雙機,全部資料存2份,可靠性比單機高不少。
  • 如果全部資料存2份還不放心,可以存第3份,比如:給高可用主執行個體添加隻讀執行個體、不買高可用版直接買金融版(一主兩備3台機器)。

場景三:地震,多個硬碟同時故障(小機率事件真的發生了)

應對方法:

  • 事先給主執行個體添加異地災備,全部資料在另一個城市也存一份。有異地災備後,達到金融級的“兩地三中心”。如果是金融類、電商類業務,這是必需的。
  • 省錢小竅門:如果隻是為了備份,災備執行個體可以選最低配置,等到容災切換時再更新配置。

場景四:我們在程式設計時是不能假設要調用的接口工作完全正常,要考慮接口工作不正常時怎麼處理。同樣的,我們不能假設騰訊雲可靠性達到100%,需要考慮騰訊雲出故障了、騰訊雲dba删庫跑路、或者某個潛藏的bug未來某個時段爬起來删庫。比如:現在(2020-04-18),騰訊雲就有安全漏洞,web使用者可以通過

銷毀/退貨+立即下線

将主執行個體、相關的隻讀執行個體、災備執行個體、自動冷備檔案

全部删掉

(删1個冷備檔案是無法操作的,删全部資料卻可以操作),而且整個過程

不會發出短信或郵件通知

,如果web帳号洩露或者dba惡意報複公司,就可以通過銷毀/退貨+立即下線删庫跑路。(這個漏洞,騰訊雲應該改為:允許web使用者自助銷毀,但在銷毀時發短信或郵件通知,而且資源回收筒資料庫立即下線不可以自助操作)

應對方法:

  • 可以每天手動将騰訊雲備份檔案下載下傳,或者開通資料庫外網通路,資料自動備份到其他雲廠商,當然這麼做有個前提:新的存儲空間是安全的,資料不會洩露,不會被黑客或者内鬼拿走。特别說明下,每日自動備份檔案和實時完整資料平均差0.5天。

附錄:資料恢複操作流程

1 操作之前,告知業務團隊,避免他們浪費人力排查問題

2 收回業務程式帳号的資料庫寫權限(從可讀可寫降級為隻讀)

3 騰訊雲恢複資料(也叫回檔、復原)

3.1 點選雲資料庫“備份恢複”面闆的“回檔”按鈕

3.2 回檔方式建議選擇快速(普通方式比較慢,極速方式不支援整庫恢複)

3.3 選擇要恢複的庫或者表:如果隻需要恢複部分表,就不要勾選整個庫,恢複會快很多

3.4 選擇要恢複到過去哪個時間

3.5 驗證恢複出來的資料是否正确、完整,補上恢複時間點之後業務程式正常的資料寫入,這部分寫入不應該被取消撤回(目前騰訊雲不支援)

3.6 将恢複出來的庫表上線(目前騰訊雲不支援)

4 恢複業務程式帳号的資料庫寫權限

5 告知業務團隊生産環境資料庫已恢複正常

下面用2個案例說明第3步如何在騰訊雲上恢複資料:

案例一:誤删user表中的一行或一列

假設删除發生在09點00分00.5秒,00秒到00.5秒業務程式有3條正常寫入sql,那麼應該檢視最近寫入成功日志将回檔時間定在00秒,并在恢複出來的庫表運作那3條正常寫入

【玩轉騰訊雲】使用資料庫Mysql如何避免删庫跑路(資料丢失)

對騰訊雲的建議1:

選擇時間點會碰到一個問題,很多時候是

不清楚需要撤回操作發生的準确時間點

(比如:誤操作後沒有馬上意識到誤操作了,或者誤操作者和恢複者不是同一人),如果時間點選擇在事故時間點之後,那麼恢複出來的資料還是錯的,如果時間點選擇在事故時間點之前,但是離的稍微遠了些,那麼後面補正常的資料改動工作會比較大。

是以建議:在選擇時間點之前,提供

查詢該庫表最後1000條運作成功的寫sql

,根據這個日志可以選事故時間點之前挨的最近的時間。

對騰訊雲的建議2:希望有

資料對比

功能,比較恢複前和恢複後的資料差異。資料遷移那已有資料對比功能。

對騰訊雲的建議3:資料對比出差異後希望有

差異合入

新庫表功能,可以是在成功寫入日志中選擇恢複時間點之後業務程式正常寫入sql到新庫表批量執行。當然更好的互動方式是:

放棄讓使用者選擇復原到哪個時間點

,而是改為從成功寫入日志中選擇哪幾條sql需要取消撤回(選中的sql在恢複回放時會被過濾忽略掉,未選中的按順序全部執行),這種互動方式最後就不需要再做差異資料合入的。即:

從版本復原變為指令撤回

,在雲資料庫世界,使用者誤删不再是通過作業系統指令對檔案做删除,而是通過sql删除,背後都有1條待撤回的sql。

對騰訊雲的建議4:将恢複出來的庫表上線,需要進行名字互換,希望支援

一鍵名字互換

功能。線上運維需要提高自動化程度,減少手工操作,因為手工操作越多,誤操作也越多。

案例二:誤删整個庫或者整張表

【玩轉騰訊雲】使用資料庫Mysql如何避免删庫跑路(資料丢失)

對騰訊雲的建議5:如果是整庫或整張表被誤删,這時在選擇庫表時無法操作,需要換個工具先建空庫或空表,操作被打斷、不流暢,而且不熟悉的使用者可能不知道要這麼操作。建議:庫表清單不是展示當下存在的庫表,而是

展示冷備檔案裡有記錄的庫表

。如果庫表目前不存在也可以恢複,那麼恢複建立的庫表名可以直接填原始名(不帶_bak),這樣第3.6步為了上線新庫表的名字互換操作也可以省去。

騰訊雲恢複功能給我的感覺是:提供了一個

通用、簡單、易操作

的互動方案,但是

設想的使用場景不夠真實

,真實場景是業務任何時候都有使用者通路,不是每次線上操作都可以先業務停寫,不是每次事故都是按計劃制造出來的、都知道事故發生的準确時間,也不是業務正常寫入和誤操作泾渭分明、簡單復原到誤操作前一個時間點就完事了。