1. 程式人生 > >刪庫是不可能刪庫的,這輩子是不可能刪庫的

刪庫是不可能刪庫的,這輩子是不可能刪庫的

知乎話題:不小心刪庫是一種怎樣的體驗

一、引言

讀完了知乎上對於“刪庫”這個話題下面的討論,我感受頗深,“刪庫”這兩個字雖然最近已經成為了計算機專業的學生或工作人員開玩笑的常用詞彙,但與此同時,這其實也是一個嚴肅的安全問題。

刪庫這個操作沒有太大的難度,但造成的損失確實巨大的,尤其是對於一些大型公司,他們的資料有很高的含金量,刪庫這種操作會對他們造成巨大的損失:

某機場請了一個大牛DBA去幫忙調資料庫的時候出了意外,結果幾個小時內整個機場無法正常執行,損失幾百萬

所有使用者都不能繳費。這可是一千三四百萬金額的錢啊,銀行已經扣錢了

...

出現這種事情不僅僅是因為某個人不小心的結果,後面隱藏著整個團隊或公司的安全意識淡薄,看了這麼多的討論,我發現意外發生的原因主要集中在”管理”、“備份”、“習慣”這幾點上。

二、問題分析

1.管理:

首先來說一下管理的問題,管理在技術上主要體現在許可權,常見的問題就是給一些技術不夠熟練或者不靠譜的人較高的許可權,知乎下面很多人都是由於不小心改動了正式庫,才造成了巨大的損失,如果他們只能修改測試庫的話就不會造成這麼大的問題。體現的更明顯的則是在Linux下,很多人都是有了root許可權之後執行了”rm -rf /”這條命令,然後才使得悲劇發生,而在討論中查詢“實習”這個關鍵詞之後,卻能看到很多的結果,可見正是由於這種許可權的管理不嚴密,才造成了這些意外的發生。

除此之外團隊內部的協調問題也會造成嚴重的安全問題,比如:“初步檢查發現是我週末的清理臨時檔案的計劃任務指令碼,因為邏輯是“進入XX目錄,然後刪除所有檔案”結果XX目錄當時不存在(被另一個同事重新命名了)從而在根目錄開刪”,這段話,這就是一個協調不夠好的結果,造成這個結果的可能原因就是命名不夠醒目,比較隨意,導致同事人為這是一個無關緊要的檔案然後重新命名或者刪除。協調還體現在文件上,很多突發情況發生時,很少看到有人去檢視相關的文件,這有兩種可能,一種是開發人員沒有書寫相關的文件,另一種是使用人員沒有看文件的意識,不管是哪一種,他們都忽略了文件的重要性。

最後就是團隊應該對可能出現的問題做好預案,並且提前給員工打好預防針,真的不小心操作失誤一定要及時的報告上級,而不是隱藏:一方面,由於有日誌,隱藏不太可能,另一方面,知道操作原因也有助於團隊及時進行補救,相比及時進行補救,隱藏等待問題爆發造成的損失更大。

2.備份:

在話題下面的案例中,大多數人的救命稻草都是”備份”,無論大型還是小型公司往往都會有備份,就是備份時間長短的問題,或是幾月,或是幾天。但是意外發生時,幾月前的備份和幾天甚至一天前的備份的修復體驗可就完全不同了,沒備份就只能靠手工,而這效率則極低,所以犯錯的人要付多大的代價完全取決於備份的人有多懶了。

個人的經歷則往往更慘,很多案例都是不小心格式化了自己的電腦、自己的U盤,然後失去了十幾年的青春回憶,甚至裡面雷軍的例子--被修過電腦時候不再寫程式碼。如果他們曾經備份過,就可以極大的減小自己的損失了。

3.習慣:

個人習慣也往往會造成很大的影響,這裡根據文件中的案例列舉一些常見的不良習慣:

  • 格式化之前不確認有沒有重要資料。
  • 對生產庫與測試庫或者生產環境與測試環境沒有明顯的區分。
  • update、delete不加條件或沒有稽核條件。
  • Shift+delete刪除檔案。
  • 沒有及時git。
  • 執行不熟悉的命令。
  • rm -rf前沒有任何的確認

三、問題重現與解決方法

這一節根據上一節分析出的一些問題進行重現,並提出解決方案,在可能的情況下對解決方案進行演示:

1.管理:

就從許可權問題上來進行重現,展示資料庫和Linux系統下給一些技術不夠熟練的人一些不恰當許可權可能帶來的危害。

1.1.資料庫操作:

圖1.對一些重要的表給予一名新手過高的許可權可能發生的事情
圖1.對一些重要的表給予一名新手過高的許可權可能發生的事情

 

圖2.嚴格把控許可權後執行危險語句的結果
圖2.嚴格把控許可權後執行危險語句的結果

 

資料庫本身已經有許可權的機制了,作為DBA應該靈活的運用GRANT與REVOKE語句,給予每個人恰當的許可權,而不是一股腦的給每個人所有許可權。這也說明一個公司擁有一個負責的DBA的重要性,這樣做也可以在根源上斷絕新人犯錯誤的可能性,從圖1和圖2的對比也可以明顯的看出這樣做的好處。

1.2.Linux控制檯操作: 

圖3.某人執行了rm -rf語句造成的後果
圖3.某人執行了rm -rf語句造成的後果

Linux控制檯下執行rm -rf這條語句往往會造成嚴重的後果,如圖3,很多重要的檔案一秒消失。作為系統管理員,就有職責預防這條語句執行時可能造成的後果。 

 

圖4.管理員嚴格限制了許可權後執行rm -rf的情況

 首先對於一些用於讀的檔案,管理員可以在讀寫許可權上進行控制,如圖4,利用chmod命令將檔案或資料夾對他人的許可權置為只讀,這樣可以有效的防止他人刪除自己的檔案,除非他擁有root許可權。

圖4.管理員嚴格限制了許可權後執行rm -rf的情況
圖5.使用chattr命令防止檔案被刪除

管理員也可以使用chattr這個更強大的命令來對檔案進行保護,它可以改變檔案屬性,讓刪除變得更難。如圖5,在使用了chattr命令後,他人首先無法對檔案進行刪除了,非但如此,自己如果誤刪檔案,也無法成功,甚至使用sudo命令也是如此,這也足以見得該命令對於檔案的保護之強大。當然這種保護也不是永久的,隨時可以把檔案屬性再修改為可修改,但這需要sudo許可權,如果有人專門取消了檔案不可刪除屬性然後再進行了刪除,也基本上可以確定刪除操作是故意執行的了。

 1.3.管理層面的措施:

 由於沒有相關的經歷,這裡我摘取了討論中一些感覺比較有效的例子作為參考,雖然這可能導致工作效率較低,但是應該足夠安全:

看了這個回答就發現我們公司這麼變態的安全管理還是很有必要的。
要刪庫?對不起,所有碰production database的程式碼都得先review,再提交,再release才可以。想要誤操作一下,至少得過peer reviewer和release engineer兩關才操作得了。
即使這樣,我好像還是不小心刪過一回。不算刪吧,寫錯地方,把其他資料覆蓋了。幸好每個小時都有備份,馬上恢復,大概損失了5分鐘的資料。
故意刪文件的遇到過一個。X被從A專案調到B專案去,心懷不滿,當即就把A專案的所有文件全刪了。接手的發現了,馬上彙報上級。第二天,凡經過X手上使用過公司電腦刪除過的所有檔案都回來了轉到了X老闆手裡面,工作N年累計的幾十萬個檔案,包括很多X很多私人檔案,什麼自己記的帳,還有保險單之類的,全部都恢復出來了。之後X就被開除了。後來我才知道,公司所有電腦,每15分鐘到一個小時都會自動備份。
所以我也絕對不敢在公司電腦上幹私事。--知乎匿名使用者

搞了這麼多年資料庫還沒有犯過這種錯誤,不是個人水平厲害,而是運營制度嚴格。太TM嚴了,我不覺得一般公司有必要搞的大家跟神經病似的,不過還是分享一下吧。還有要是公司沒錢,就不用浪費時間繼續往下看了
1,首先任何人犯錯都不是個人問題,而是制度的問題。不論技術多高,學歷多牛,經驗多豐富,只要是人,都有可能犯錯,區別是犯錯的概率有大有小。要防止(完全防止理論上是不可能的)或減少個人犯錯的機率,首先從規章制度下手,比如:
分割環境。線上資料庫除了支援線上業務,不承擔任何其他功能。開發,測試,預演都要有自己的拷貝,各個環境之間物理分割。
許可權控制。運營資料庫只允許運營部門訪問,所以只有可能運營的人不小心在非線上環境犯錯,開發和測試人員不會在運營環境犯錯。
系統變動。線上資料庫不能隨便改,哪怕是很小的改動,公認的人畜無害,也不能不經批准擅自改動。這主要是保證線上系統的穩定性,還有就在遇到複雜的bug,可以迅速回到以前的狀態。
自動化。這個很重要,沒時間展開聊,基本想法是機器出差的概率比人低。
2,系統變更要有嚴格的管理和詳細的記錄。這個不是給事後諸葛亮預備的,在改動之前相關人員和部門要清楚更改內容,無論是資料庫升級,還是改個密碼,大家要清楚為什麼改,改什麼,改了以後有什麼影響,改出問題怎麼辦。
下面內容太多,懶了。。。
計劃
測試
批准
更改
緊急情況
3,線上系統的問題是所以人的問題。負責運營的兄弟們是不是聽過類似“這個程式碼在QA跑的好好的,在你們這兒出的問題和我無關”?這種思想從上到下一定要杜絕,我的問題就是公司的問題,公司的問題就是你的問題。我見過為了趕進度測試不完整,程式碼不優化,全等到了production再說的部門,操作這種產品出差率很高,甚至有時不得不線上修改。
4,線上系統穩定性由高層決定。
前邊說的說到底就是錢的問題,不過有錢有有錢的活法,沒錢有沒錢的活法,全看大boss是不是捨得給運營部門投錢。想要五個9的資料庫,全套測試環境要花錢,全套預演環境要花錢,自動化軟體,管理軟體也要花錢,什麼?沒錢?那對不起刪庫有可能無法避免。” --知乎使用者’嚮往退休

 2.備份:

 2.1.資料庫備份方式:

由於資料庫往往部署於Linux伺服器上,因此我們可以利用Linux的指令碼來實現自動化部署。

首先實現一個備份用的指令碼:

#!/bin/bash
#檔名: backSql.sh
#用途:備份資料庫
USERNAME='test' #資料庫使用者名稱
PASSWORD='test' #資料庫密碼
DATABASE='ztest'    #資料庫名稱
curDate=`date "+%Y-%m-%d_%H:%M:%S"` #檔名根據當前時間生成
mysqldump -u$USERNAME -p$PASSWORD "$DATABASE">~/桌面/資訊保安/test/$curDate.sql

然後在crontab裡面新增一個新的任務:

圖6.新增備份任務到計劃任務表中
圖6.新增備份任務到計劃任務表中

這裡為了演示,設定兩分鐘備份一次,實際上一小時備份一次就已經足夠了。

圖7.執行情況
圖7.執行情況

2.2.Linux部分檔案備份方式

對於Linux下的一些重要的原始碼或者圖片之類的檔案也可以經常進行備份,或者寫到crontab中進行定時備份,我們可以利用簡單的zip之類的壓縮命令壓縮目標資料夾,然後配合ssh命令上傳到某其它伺服器中實現備份的目的,也可以利用rsync命令更方便的實現快照功能。

之前學Shell指令碼的時候用zip和except命令實現過一些指令碼來對一個資料夾進行過備份:

圖8.back.sh備份的主要邏輯
圖8.back.sh備份的主要邏輯
圖9.upload.sh 上傳壓縮過的檔案
圖9.upload.sh 上傳壓縮過的檔案
圖10.deleteHistory.sh 刪除歷史檔案
圖10.deleteHistory.sh 刪除歷史檔案

 基本思路就是在本地對資料夾進行壓縮,然後上傳到雲伺服器,並且清除掉歷史檔案,不過事實上,Linux下也有更好用的自帶的備份方式,就是rsync命令:

圖11.執行rsync備份快照到遠端伺服器與還原檔案到本地

 如圖11所示,使用rsync命令可以一鍵將檔案備份到遠端伺服器,在需要的時候可以再將其很輕鬆的恢復到本地,而不需要編寫額外的指令碼。這個命令也可以配合crontab使用,使得備份更加自動化。

2.3.關於備份的其它要注意的點:

執行自動化備份之後應該經常抽查備份檔案,檢視備份是否與預期的相同,有時候有可能由於某種原因導致備份檔案出錯,而這相當於毀掉了自己的救命稻草,因此應該經常檢查確保萬無一失。

此外有時候沒有很好的備份時我們可以檢視執行日誌,比如MySQL資料庫就可以檢視binlog,這樣即使通過手工輸入也能挽回部分損失,知乎下的討論中很多沒有做備份的人也是用log保住了一部分資料。

 3.個人習慣:

個人不良習慣也是導致危險操作的原因之一,這裡我從討論中找出了一些很好的做法或者是自己想出的一些應對方式。

3.1.生產庫與測試庫 生產環境和測試環境分不清:

生產環境和測試環境的控制檯最好使用不同的使用者名稱登入,同時主機名也儘量避免重複,這樣可以幫助我們分清測試環境和生產環境。

此外知乎下有人提供的在mysql下分清兩種環境的建議也非常不錯:

啟動mysql時設定一個特定的prompt。使用--prompt=來給生產環境設定一個特別的提示符。
$ mysql -uroot -p --prompt='PRODUCTION> '

PRODUCTION> SELECT 1 + 2;

3.2.在根目錄下rm -rf或者是在root許可權下cd ..進入根目錄: 

關於這點我覺得最好的方法是儘量不要用root角色來做事,需要高許可權的時候再sudo比較好,此外rm -rf之類的危險操作之前最好先使用pwd來檢視一下當前目錄,確保自己不會做出什麼不好的事情來。

3.3.直接執行不知道的命令:

這是一個很危險的做法,在多人工作的情況下,誰用了某個命令就要對自己的行為負責,所以最好不要去貿然執行不知道的命令,否則就要背這個鍋。在自己工作的時候即使要執行不知道的命令,也最好百度一下用法,防止造成不必要的損失。

3.4.update、delete不加條件或條件加錯:

我在執行update和delete之前,會先用select語句加上where執行一下看看會有多少結果收到影響,然後再使用delete或者update語句正式執行,這樣做會讓自己在修改資料之前再次確認,防止自己出錯。

圖12.MySQL Workbench執行危險語句時的效果
圖12.MySQL Workbench執行危險語句時的效果

此外,在MySQL Workbench中嘗試執行不加where的語句時,它會報錯,如圖12,而直接在命令列中執行卻不會,這也說明了一些資料庫視覺化工具已經考慮到這種粗心的問題了,所以我們也可以利用這些工具來輔助我們對資料庫進行操作。

3.5.刪除非常徹底,不留後路:

知乎話題下的討論中,我看到了很多不錯的做法,比如:

  • 刪除時不要用shift
  • 不要著急清理回收站,除非確認這些東西不會再用到
  • 儘量用mv命令而不是rm命令來刪除

總之原則就是“給自己留條後路”,所以我現在在刪除某個檔案時也往往使用mv *** ***.old來代替rm ***,希望有一天也會感謝自己的這種做法吧。

3.6.不會善用git:

很多團隊或者都會使用git來進行程式碼的維護,但如果寫了程式碼不commit、push,一旦發生了什麼意外,可能很多天的工作量都變成了徒勞。因此經常commit並且寫好詳細的註釋才是最好的做法,一方面,這樣可以讓別人看見自己的努力,另一方面,這也是對自己的一份保險,即使本地的程式碼庫沒了也可以再pull一份下來而不是從頭再來。

四、總結:

總之,“刪庫”這個問題發生的原因主要在於人們的安全意識不夠,我們可以用管理+技術來對這種情況加以預防,同時也要培養自己良好的習慣,防止不好的習慣給自己帶來不良的影響,最後希望“從刪庫到跑路”這句話只存在與玩笑之中吧。