對於備份的敬畏

別的方向不敢說,至少在數據庫行業,我敢拍胸脯說,如果你的數據庫不考慮備份,連最起碼的備份都沒有,一點都沒有的話,那麼你搞那麼多的優化和改進最後都可能被一次故障抹平。

讓我現在很難理解或者焦急的是,我瞭解的很多行業/公司裡面,其實備份做得很一般,最普遍的一類問題是隻有備份,沒有恢復。恢復都沒試過,沒有演練過,你備份有啥意義。在DBA 1.0的時代,對於DBA的定位,最重要的職責就是數據恢復,這裡要強調的是,最重要的,沒有之一,當然到了DBA 3.0甚至更新的版本迭代,不那麼重提備份恢復是因為現狀應該會很好了,相比於雲時代的挑戰,備份恢復已經相對成熟了,所以沒有放入以前的那個位置,但是我們的狀態還是很早之前的。

別怪我說話直,是這麼簡單的道理,好像大家都不知道,還需要碰到問題吃點虧才能長記性,這個代價實在是有些大了。

我的手機裡有很多的朋友,以至於我每隔一段時間就會自然的收到一些千奇百怪的問題。有的朋友的數據庫遇到了無備份的破壞場景需要恢復,有的是邏輯問題導致的數據丟失,一旦發生問題,少則是丟失數據,多則影響核心業務,損失都是成百上千萬的。都說運維部門只花錢不掙錢,如果在這個時候還捅出簍子來,那麼我們的工作會更加被動,甚至極端情況下有些同學的職業生涯就在此轉折。

我現身說法來講一個例子,今天對於備份的認識算是更加深刻了一些。我們花了很長一段時間,投入了不少的精力來做SQL Server到MySQL的存儲過程轉義,聯調測試。因為處於測試階段,所以我們就沒有考慮像線上業務的高可用或者災備,在保證功能的前提下,我們先著重於結合業務測試數據。

因為需要做schema層面的調整,比如一個數據庫的名字是testdb_dbo,我們需要修改為testdb,那麼在MySQL層面是無法直接修改數據庫名字的,所以一種自然的方式就是備份數據,然後重新建庫,導入數據。

我也深深知道這個操作的重要性,所以在備份的時候,做了好幾個層面的備份,第一個層級的備份是數據庫級的,比如有兩個數據庫,那麼我就對每個數據庫生成一個備份,使用的命令類似:

mysqldump --single-transaction --databases testdb_dbo > testdb.sql

然後做第二層備份,害怕萬一遺漏了什麼,我做了一個全庫備份,使用了--all-database級別的備份

然後我做了第三層級的備份,做了數據文件的備份,這裡因為空間的原因,我著重就備份了整個數據庫的物理文件,也是按照數據庫的文件夾級別來備份的。

做好了這幾個層面的備份之後,我覺得差不多了,於是刪除了已有的數據庫,創建新的數據庫,導入數據,一切看起來都是很順暢的,從權限和數據表的方案問來說,沒有發現什麼問題。

但是過了一天之後,同事給我反饋,存儲過程訪問不了了,這個時候拿著問題再來看這個問題,我突然發現恢復後的幾個數據庫裡面都沒有存儲過程了。我突然想起來,我竟然犯了一個錯誤,那就是做數據庫級別備份的時候,竟然沒有添加--routines選項,導致存儲過程沒有備份,帶著一絲的僥倖,我查看了數據庫級別的備份文件,確實沒有procedure的字樣,我覺得問題好像麻煩了,然後我打開物理備份,因為是直接拷貝的物理文件,抓狂的是ibdata這樣的文件還沒有備份,所以物理備份理論上是可以恢復的,但是恢復存儲過程,從目前的情況來說,也是不可行的。

然後回到救命稻草,那就是全庫備份,我還在不斷的問自己,全庫備份是否需要再聲明--routines選項。如果沒有的話,那麼我們這段時間的努力就全白費了。在全庫備份中找到了procedure的字樣,總算讓我有點踏實了,我重新恢復了數據,最後算是把存儲過程都恢復回來了。事情到了這一步,其實也算是有驚無險。我想著也給了我敲響了警鐘,但是做全庫備份還是絕對的不重視,差點因為文件命名的關係,把全庫備份給刪掉了,幸虧是好的一方面,要不我們接下來該怎麼走,可能就比較糾結了。可能是去找歷史的備份,或者找一個最近的備份歸檔,顯然那麼這個事情會暴露出更多的問題和隱患,最終的結果也會存在諸多的差異。

有的同學可能會認為運維把自己做好就行了,應用層面出了問題,那麼這個鍋可能和我們就沒有關係了,其實不然。比如應用層面因為邏輯問題導致數據丟失,這個責任和邊界很清晰,但是問題還是要解決,結果求助DBA去恢復數據庫的時候,發現我們的數據庫備份就存在問題,那麼這個鍋肯定會到我們的頭上。這個是我們首要保證的。

另外一個就是流程化,規範化的落地,比如應用的重大變更一定要備份,可能這個時候備份對於他們來說意義不大,他們可以確實不需要備份等等,但是從流程的角度來說我們還是需要備份的,一旦發生了意料之外的情況,我們還有解救措施。


分享到:


相關文章: