我相信,在日常工作中,DBA們都遇到過各類大小事故。很多時候,我們也是在各種事故中不斷成長起來的。有的可能是硬件、產品、網絡等等我們不可控因素造成,有的時候是人為因素使然。
剛入行的時候,我非常害怕事故,哪怕不是和自己直接相關的,在處理的時候都心臟快速跳動,血壓升高。伴隨著經驗不斷豐富,處理過的問題越來越多,終于慢慢組織總結了很多東西。然而很多時候,我遇到過相當數量的同行,在處理完事故之后,反而一身輕松,覺得萬事大吉了。現實中一次事故解決之后,可能只是整個事件的剛開始。針對不同類型的事故,處理之后,該怎么應對,我也有一些自己的心得,最終的目的都是避免此類事故再度發生。
類型1:低級錯誤造成的事故
這一類不僅僅是在新手DBA中,哪怕一些老DBA仍然有可能發生。去年國慶假期,我收到公司報警系統的通知,一臺SQL Server的數據磁盤空間報警,觸發了90%和95%的閾值。那會還在外面,根據以往經驗,這是月初結賬導致,過了第一周,后面數據增量不會太快,節后返工處理即可。于是就手機ack掉。
誰知節后回到工作中,一下子很多東西都壓過來,一時之間竟把這事給忘了,終于在10月的第三周一個下班回家的路上,磁盤寫滿了。恰好還是部門一把手用相關應用報警先發現,而不是業務們先發現,總算給部門保留了最后一絲顏面。緊急擴容處理之后,第二天來到公司,就被狠狠批了一頓。我曾經一度想編個其他理由去蒙混過關,思量再三,還是和盤托出,這是一個低級錯誤的事實。那會的部門一把手是個性子很直的人,我又是他非常信任的人,所以在他看來,這件事情實在不該發生。
之后我將公司的報警平臺機制做了調整,在監控級別上給自己多上了一把鎖。同時與其他DBA同事進行了相關討論,遇到這種95%級別的報警,如果自己不在公司或者短期內不能登錄電腦工作,就第一時間在群里找其他DBA或者操作系統的SA,緊急做擴容或者清理,處理完成后在群里反饋結果。同時,如果長假,盡量確保組內DBA與SA,至少有一個人在當天能夠登錄系統,哪怕采用輪流值班的方式,確保類似事件不再發生。在工具、流程和人的三個層面做好保險,從而確保類似的事件不再出現。
很多DBA,尤其是資深DBA,通常在發生低級錯誤導致事故的時候,內心都多少有些抗拒,往往只是草草處理收場。然而一個經驗豐富的DBA出現低級錯誤的時候,恰恰可能就是某個環節出現了問題。和一些冷門問題不同的是,這些某個環節存在問題的場景,很可能在不同的時機再次觸發從,可能引起更大的事故造成更多的損失。千萬不要得過且過,勇敢誠實面對這些東西,將隱患的環節通過整改,避免下次再度出現才是重中之重。
類型2:因設備自身造成的事故
這一類事故是平時比較多的,尤其一些公司,設備老舊甚至超齡服役多年時,就會經常發生。
幾年前的年底財務結算期間,我們負責核心財務系統的Exadata出了一次事故。三個存儲節點,短時間內壞了兩個。確切說,是第一個節點壞了報修之后到原廠工程師上門修復之前的時間段,另一個也故障了。事后Oracle原廠工程師說,這事除了倒霉,真沒法解釋了,他做了多年硬件售后,也沒有遇到過不到4小時內連續壞兩個的情況。然而這種黑天鵝事件,恰恰就發生了。
然而我們的備用服務器是配置只有生產環境一半的另一臺Exadata,平時的業務量是可以扛住,但是年底財務結算,業務量是平時數倍的情況時,根本扛不住。更糟糕的是,這臺備用服務器之前被我們當做備件庫用,生產環境的硬件如果出問題,例如交換機或者主板,我們會優先拔下它上面的硬件給生產環境用。上面的硬件幾乎都已經被換了個遍,誰也不敢保證,這臺機器上的硬件拆下來能夠給主機用,一旦備機也出了問題,就意味著所有熱數據都沒有了,只能從帶庫恢復,這中間還有備份和生產的時間差。最后部門一把手和財務一把手開了一晚上的會,拍板決定,盡快搶修生產環境,業務臨時中止至第二天早上上班。經過一晚上的搶修,終于恢復了兩個存儲節點中的一個。數據庫得以恢復,而另一個換過主板之后仍然不能修復,只能由更資深的工程師到達現場來檢查修復。
前后折騰了半個月,這期間還因為元旦跨年耽擱了幾天。兩臺存儲節點都修復之后,我們還驚魂未定。然而對我們來說,整個事故的復盤總結才剛剛開始。這臺Exadata服役時間已經超過4年,進入了硬件故障開始頻出的階段。而部門一把手憤怒的點在于,這么重要的事情,居然提前沒有知會他,等到故障出來了,他才知道這臺機器已經服役了這么久,硬件都頻繁更換過。這類問題該怎么規避,成為了后來復盤的關鍵點。
從流程上來說,當第一個節點硬件出了問題后,我們沒有立即聯系Oracle原廠工程師,盡快上門檢查,這中間耽誤了兩小時,如果原廠工程師早些到達,也許第二個故障節點的隱患會被提前發現,從而有準備地停機更換。對于核心財務這種任何公司都是最優先保障的系統,應當第一時間聯系售后的負責人,行動越早,耽誤的時間就越少。而從運維的角度,我們每年一次的服務器巡檢,顯然已經不足以應對這臺服役快5年的老服務器。事后我們決定,每年多買些原廠人天,除了將例行巡檢提高到半年一次的頻率,在年結保障期間,由原廠Oracle工程師一對一在公司駐場,遇到問題第一時間相應解決。此外,由部門一把手與財務部門開會,講述硬件問題可能后續帶來的風險,并建議業務部門盡早追加預算購買新設備替代。
應對這類事故,我的建議是,不要抱著僥幸心理,任何的硬件設備都是有壽命的。在進入高齡服役階段,一定要及時向領導反饋。并且膽大向領導提出及時更換硬件的建議。而在事故發生的第一時間,聯系原廠售后人員上門。不要抱著自己想辦法解決的一根筋想法,即便是售后人員到來之前,你自己解決了,這也是在正常不過的。而他們第一時間收集各類信息和反饋,回到公司提交給相關人員,同樣是有價值的。不要在山崩雪崩的時候想著怎么秀肌肉展現自己,而是要動用各種自己想到的資源和途徑解決問題。此外,和業務部門建立起快速的溝通渠道,一旦出了問題,第一時間溝通協調,將業務損失降到最低。
類型3:其他人或其他系統造成的事故
之前公司為了節省硬件成本,曾經把一些平時負載不高的數據庫以不同的實例或schema放在了同一套硬件服務器上。這些業務共享一套硬件,跑了兩年相安無事。
直到有一天,在下午交易時間里,突然報警系統發出了告警,磁盤IO過高,此外歸檔日志的生成肉眼可見同樣在飛速增長。之前可以撐一周的歸檔日志空間,短時間內寫滿了,而系統自動備份的頻率跟不上,終于數據庫報了無法歸檔的錯誤,導致幾個相關業務全部中斷。幾個應用系統的負責人幾乎是腳前腳后給我打電話或者發信息,質問我到底怎么回事。這一刻我成了靶子,密密麻麻被打滿了躺槍的彈孔。
我只好把歸檔日志臨時挪到其他磁盤,保證歸檔正常進行,同時去檢查到底哪些語句執行導致。最后發現,有幾個表,insert和update的次數都高的嚇人。然后把語句發給了相關應用負責人后,我才勉強不被幾個人同時diss。經過排查才發現,應用運維的人員,下午誤操作,執行了一個之前用于版本升級調試的應用任務,這個任務就在后臺瘋狂生成著歸檔日志。停掉之后,這才恢復正常。
這個事故原因本身不復雜,但是在交易時間造成幾個應用業務中斷,卻是一個不小的事故。如果再多幾分鐘,怕是就要上報監管機構,這就不是一個技術問題了。第二天我們開會復盤,重點就是如何避免這類事情再度發生。因為是應用系統那邊的問題,所以最終的結果也是由該系統的負責人負責內部團隊的建設和整改,確保此類事件不要再發生。但是從DBA的角度,這件事情卻給了我很大的心理陰影。如果核心交易系統出現這種問題,會不會我們這幫人就都被一鍋端拿補償回家了。
后來我總結出幾個辦法,第一個是,要求應用團隊在交易時間里每一個操作,都必須在群里發出。確保開市時間每一次操作都有跡可循,如果某個時間點之后系統出現哪些異常,就可以直接追溯到之前最近的一次操作內容。第二個是,將相關數據庫每天自動生成的健康報告同樣發送給應用負責一份。讓他們對自己系統所使用的數據庫情況做一個常規了解,其中包括備份情況、磁盤使用率、過去一天歸檔增長數量、用戶登錄情況等等。這也為后來我自己的工作節省了很多麻煩事。
類型4:DBA知識經驗不足問題造成的事故
這類問題也是比較常見的,同時也是很雜的。很多商業數據庫經過幾十年的迭代,已經無比復雜。一個DBA學習和工作5年,可能都不見得遇到特定的場景。一旦某個場景觸及到自己知識盲區的時候,再正常不過了。
之前我曾經把一套數據庫從Oracle10g遷移到11g,那時候剛工作沒多久,也是我第一次做大版本遷移。做完以后測試各種一些基礎功能沒有問題,也就交給了應用團隊。而應用團隊在開始使用之后開始發行問題,有個別業務場景性能有了明顯的下降。應用負責人找到我,讓我幫忙看。我嘗試著把有問題的業務場景的表找出來,再找到相關的SQL語句,查看執行計劃。非常奇怪的是,同一條語句,新庫舊庫的執行效率差異還挺大。一時之間有點懵,折騰了一個下午,也沒能有效解決。乙方的DBA給我打電話,問我統計信息是否重新收集,我這才知道,原來數據庫遷移之后,這些東西要重新做。當時我假裝自己忘了這一步,掩蓋過去不知道這件事情的事實。
這類問題我認為是事后分析解決反而容易的,因為事故觸及了自己哪些知識盲區,DBA自己是心中有數的。在遇到問題并解決問題的過程,也是不斷增加自己經驗的過程。遇到這類事情,要在事故解決之后,第一時間把事故報告寫好,盡量詳細。這對于以后遇到類似場景規避問題有著很重要的作用。同時,做到根據事故報告里自己的經驗和知識盲區,舉一反三,深入學習探索,是一個很快提高自己的途徑。
六年前,跟我同期入職的一個DBA,我負責Oracle,他負責SQL Server,甚至比我早入行還早了兩年。四年的工作下來,我總結了很多事故報告和經驗,在處理問題方面越來越得心應手。而他基本上都是憑記憶去處理,兩個人處理問題的能力慢慢就被拉大。有時候甚至有些SQL Server的重現的問題,我都已經大概記住了思路,而他還要重新去翻各種文檔。在我離職之后,他也慢慢放起了自己的DBA之旅,開始朝著運維流程管理的方向前進。也許對他來說,也不失是一個更好的職業路徑。
總而言之,每一次事故,在發生解決后,我們仍然要去反思,為什么會發生,為什么要這么處理,如何應對才能以后盡量規避。不同類型的事故,暴露出來的問題也是不同的,流程的、人員的、技術認知的甚至有的短期內都不一定找得到真正的根源。有時候多思考一下,多走一步,就會給你未來的工作減輕很多負擔,規避很多風險。




