一、 現階段DBA對系統性能及穩定性所做的調整工作
目前DBA對系統性能的調整工作大致是這麼幾個方面:
1、 在硬件層面進行調優,這通常就是直接花錢,買設備、擴容。
2、 在DB層面進行調優,比如調整初始化參數,調整數據庫物理結構。
3、 對應用的SQL進行優化,比如在數據庫分析statspack,調整Top SQL。
4、 只有非常少數的,通常是對系統穩定要求較高的一些公司的應用,才會在新的應用上線前,讓DBA對sql進行充分的審核與評估。
問題:在應用系統的分析、設計、開發階段,就目前情況看,很少有DBA參與,而應用系統上線或者開發工作基本結束後,DBA所能做的調優工作其實是很有限的。
二、 許多應用系統的性能或穩定性仍不理想
許多應用系統的性能並不理想,或者系統數據會出現一些難以重現的奇怪的錯誤,這些問題(尤其是性能問題)有時並不是在系統初期就會體現出來,但是隨著系統的運行、數據的增多而逐步變得難以解決,給系統後期的功能擴展和用戶使用上帶來了不少麻煩,造成這些問題的原因,往往體現了一點:開發、設計這些系統的人不了解數據庫!以基於Oracle的應用為例,簡要舉例說明:
底層數據結構不合理
由於缺少專業DBA的協助,很多系統設計出來的底層數據庫表結構問題重重。而做過系統的人都知道,底層數據庫結構不合理,帶來的改造代價之大幾乎等於一次重構!我見過一個OLTP系統,其核心表竟有100個字段,平均一條記錄超過8K,如果按Oracle默認的8K一個Block,一半以上的行必須產生行鏈接!
而最糟糕的是,設計這樣表結構的人還認為自己充分利用了冗余來降低表之間的連接,事實上,其人根本不曉得什麼是范式、什麼是更新異常,按照范式,這個表應該拆分為兩個表的,但如果要改幾乎所有的程序都要改!雖然范式不是越高越好,但絕對是設計的人必須吃透的一個東西。在冗余上,相信大多數DBA都認為,級聯更新的代價是非常高的,因此冗余應當避免發生級聯更新的情況,對於關系型數據庫設計中冗余的使用,絕不是門很容易掌握的技巧。
不合理的底層數據庫結構設計,給系統的性能埋下了重磅的定時炸彈,這個系統在客戶那裡跑不到一年,數據量稍微上去些,性能、穩定性就直線下降,而重構的成本又極高,買新服務器肯定是只能治標。而假如底層數據表結構是資深DBA設計的又會如何?當然,如果完全讓DBA去做數據庫表結構的設計,DBA就必須非常清楚地了解整個系統的業務細節信息,這在DBA來說,人力資源上是有一定困難的,畢竟維護好線上服務器就已經占用了DBA很多的資源,並且領導們通常更看重這點。
很少有領導能認識到DBA在系統開發設計中所起到的作用,和維護線上系統、處理DB故障相比,對整個系統的穩定性和性能,是同樣重要的!
SQL性能問題
系統的開發,通常和DBA是沒有什麼關系的,但是,如果DBA對系統有足夠的了解,這時候也是可以做不少貢獻的。比如,檢查系統業務的數據流是否正確,這個需要通過一些手段,比如sqltrace、10046等,詳細對系統的邏輯實現進行檢查,一方面查出系統中過於消耗資源的或編寫不規范的SQL及時進行調整優化,另一方面,查出系統中不合理的數據庫訪問,不要到了線上才發現問題,那時可能已經宕機了。簡單舉個例子,當一個頁面需要多處顯示商品的類目列表時,程序往往容易犯一個錯誤,就是多次以同樣的SQL讀取出同樣的數據,並應用於每一個列表顯示上,如果你只讀取一次,或者干脆在Web層進行cache(要有適當的刷新策略),就可以大大減少單次訪問該頁面在DB上的I/O消耗。有時甚至會檢查出根本不需要被執行的SQL,也在這些和自己毫不相干的功能中頻繁地執行著……同時,對數據流的檢查還能夠查出一些隱藏得較深的系統Bug,這個更需要基於DBA對業務細節的了解。
誰說DBA只會花錢?如果一個服務器I/O負載達到極限,大多數人只能選擇擴容,最多重構部分功能來作些優化,而從statspack往往可以看出,系統的I/O資源多數是被一些並不該如此頻繁執行的SQL給占用了,它們單次執行並不慢,但占用系統資源比例卻異常高,這些問題,細化在每一個業務中,對這些問題的檢查和數據流優化,就是對系統資源的最大節省,就是省錢!這個工作,或許只有DBA才能稱職。
並發問題
誰都知道系統有並發存在,可是我們在設計系統的時候,又往往是按照單一業務的思維模式來設計、編碼,很少考慮同一業務、不同業務之間並發運作可能產生的問題。通常,系統無規律地出現一些“奇怪的”、“不可能的”錯誤,極有可能就是並發惹的禍,而背後的問題,往往體現了設計人員不了解數據庫的鎖機制,無法和業務很好地結合。設計的人不了解數據庫,而DBA又不了解業務,這就導致了很多本來可以避免的問題產生。
最經典的就是Tom Kytes舉的酒店預定的例子,當兩個服務員同時按下查找預定房間的按鈕,結果是兩個人都預訂到了同一間客房,這個問題很經典,在目前看來也很容易解決,不就是加上鎖麼?但是,這只是一個例子,在你實際應用的系統中,你這樣貿然地加上for update,又可能導致別的問題!比如:死鎖。在一個復雜的業務系統中,死鎖不難見到,這個是設計者的設計漏洞,需要設計者全面衡量業務關系,然後對表的鎖定制定規則來盡量避免的。學會使用鎖來保證數據的完整性還是不夠的,還要靈活應用鎖,適當采用樂觀鎖定。
如果對於重要的業務,一律免談,直接悲觀鎖定也是不可取的,會給系統的維護帶來一些問題,某些業務這樣做甚至會帶來數據的大面積鎖定時,在OLTP上的代價很高,嚴重影響系統並發能力。我曾經碰到一個錯誤數據的問題,分析後,確定是兩個不同的業務間並發,同時缺少必要的鎖定,而造成的錯誤數據。但基於該業務的特殊性,加鎖的代價是昂貴的,在DBA的仔細追究下,確認了可以通過樂觀鎖定也即提交時檢驗的方式來達到兩全其美的目的。從這裡可以看出,數據的健康和完整性,與系統的並發能力有時是矛盾的,但有經驗的DBA能夠教你如何獲取最佳方案,當然,前提是DBA參與設計並熟悉業務。
系統架構的問題
DBA不是系統架構師,但數據庫是一個應用系統核心的部分,同時,由於數據庫服務器不像應用服務器那樣便於擴展,因此往往也是整個系統性能的瓶頸所在,所以架構師在設計系統架構時,應該充分考慮DBA的意見,要考慮到DBA對數據庫中的SQL進行性能調整的便利性甚至是可行性!
否則就可能導致DBA及開發團隊對系統的性能問題反應過慢甚至束手無策!我曾經見過一個架構,它無法實現oracle最普通的分頁SQL!綁定變量就根本不在考慮中!再就是有些第三方組件或架構,能夠幫助我們的系統生成SQL,這當然很省事,能夠加快開發速度,可是在這樣的系統中,DBA如果想要優化一條SQL可能很難,因為開發人員要修改的東西相對較多,修改的工作量大、耗時長,並且工作量多肯定就更容易帶來新的錯誤!Oracle大師Tom Kytes也曾在經典著作Export one on one中反對使用這種自動產生SQL的組件或架構,這種東西很可能給你的系統帶來性能和維護上的問題!
這些問題,如果咨詢過資深DBA,相信會盡早發現並在架構上得到修復或調整。而到了系統開發的後期,架構的問題已經很難做本質的調整了。假如你的系統要求非常高效,並且並發訪問較大,那麼建議架構師傾向於尊重DBA的意見,這對整個系統的性能以及持續地調優將非常重要。而DBA,對系統架構也要有一定的認識,並明確自己在現有架構中遇到的困難是什麼。
三、 提高應用系統的性能、穩定性
除了DBA原本的DB調優、SQL調優、服務器維護等日常工作以外,擴展DBA的工作范疇,強化DBA在系統開發過程中的控制能力和決定權。
1、 讓DBA參與到需求分析中去,並充分理解用戶需求,從DB的角度來理解和考慮這些需求實現的成本。
2、 Schema的設計必須由DBA設計確定或者審核確定,這點也要求DBA必須了解業務系統,才能整理出正確的、有良好擴展性的E-R關系。
3、 讓DBA更深入的參與系統的設計,盡可能地讓DBA了解應用的業務設計細節,這對於DBA審核數據流是起到決定性作用的,如果有條件,業務的數據流應當作為系統的文檔之一,以便將來的反復核查。
4、 在系統上線之前,由DBA審核sqltrace中的sql以及數據流邏輯,最好是能給出一些重要業務功能在DB成本(比如I/O)上的評估結果。
5、 系統上線後的性能監控,及時作出調整甚至一定范圍內重構優化數據訪問邏輯。
如上所述,則DBA的人力資源必然不足,因此,細化DBA的工作,進行分工是正確並且高效的,在一些公司,已經將DBA分為專管線上服務器的產品DBA和專管開發、參與系統設計的開發DBA,從不同方面全面保障系統的穩定和高效,值得借鑒!