在我供職的公司不僅僅擁有Oracle數據庫,同時還擁有SQL Server數據庫,所以我經常遇見人們向我提兩種問題。
第一種通常都是以"你能教我使用Oracle嗎?"開始的,對此我比較禮貌的回答一般是"當然可以,實際上我正准備辦個Oracle學習班;准備好之後我就叫你"。這是做好人的辦法,我沒有告訴詢問者這可能花費我數周的精力。有時候我進一步告訴他們可以在哪兒去下載Oracle的完整版本,以供他們安裝和熟悉。但是有時候這樣做給我帶來了麻煩,因為它可能招來過多的追隨者。
第二種一般是這樣開頭的"我們遇到了SQL Server的一些問題,我想看看Oracle是如何處理這個問題的"。好的,我們終於有了一些進展了。我可以為他們提供幫助,但是這不會占用我數小時時間。它應該是對某個特定問題進行了慎重地考慮之後的敘述,Oracle對這個問題的答案將為詢問者指出一條道路,可能引導它們解決SQL Server的問題。詢問者接者問"我們的SQL Server數據庫變得太大了--Oracle如何處理這個問題呢"?唉...看來我說錯了。
我想提供幫助,但是...
我的方法也許一直都是錯的。也許我應該寫一個總結材料,歸納可能涉及到的一些問題。當其他人向我尋求幫助的時候,我就可以把這個問題列表給他了。如果那個人正在接受普通的Oracle啟蒙教育,這個列表也許稍微廣泛了一些。另一方面,如果詢問者在搜索特定的和可以量化的問題的解決方案,這個手冊也可以幫助他們沿著正確的方面前進,這樣他們就可以在自己的桌面上找到答案。
但我沒有這樣做,因為這樣做花的時間太多了。盡管我盡可能地幫助這些"寄居者",但是我真的擔心為他們花費了太多的時間,偏離了自己的航向。這樣做將是個不好的先例。它會鼓勵他們在某個時刻遇到某些苦惱的時候再次回來向我求助。作為代替,我僅僅花幾分鐘時間談一下SQL Server中的設計瑕疵。體系結構所涉及到的內容是不能改變的。如果你鑽研數據庫平台對比判斷的技術細節,一般都無法得到那些不言自明的原理。相反地,如果你決定使用微軟的數據庫平台,這些問題就一定存在。它的特性或缺陷可能被我們處理得較好,但是產品基本的機制不容易改變--當然也不容易被封閉源代碼軟件的最終用戶所改變。當然,有些辦法可以減輕痛苦,但是卻無法克服這些問題。兩個平台之間有很大的差異,更不用說很多問題的起源之間的差異了。
請記住,我不是維護街上花店的系統。微軟正在盡自己最大的力量進入企業中,進入Oracle的領地。因此我要討論的是:企業級系統管理員所關心的問題。 我所關心的是...
由於公司需要使用管理企業級系統(我們公司是SAP),我更喜歡使用多用戶(multiuser)數據庫。現在你可能認為我使用這個術語太輕率了。實際上有大量的用戶在多用戶環境中使用SQL Server,不是嗎?但是他們處理大量的並發用戶是受到平台的影響,還是不管並發用戶的?例如,我們來看看鎖(locking)的問題。開始,微軟告訴你"讀取者-阻塞-寫入者"的機制很好,很安全。它會告訴你這個機制防止了用戶執行"錯讀(dirty read)"。不要相信這種鬼話;它只是性能低下的一個借口。這使我想起了Sun長期堅持認為64位系統不必要的立場。不必要是指他們銷售這種產品之前沒有必要存在。接下來,某一天Scott McNealy在你面前高談不斷增長的物理內存尋址的優點。
那麼什麼是"錯讀"?微軟會告訴你,如果某個人正在更新一個數據行,而你准備讀取這個處於更新之中的數據行,就會出現錯讀。錯讀=壞數據--這是微軟希望你相信的內容。但是如果某個更新操作很長時間沒有提交會出現什麼情況?數據實際上沒有真的被改變。如果那個更新操作在事務的末尾回滾了又會出現什麼情況呢?這些讀取者的等待得到了什麼東西?什麼也沒有。
這就好像我在一家超市裡,站在果汁面前,試圖決定買哪一種。我知道自己會選擇一種,我知道我的小孩明天早餐需要喝果汁。我已經伸出了手,但是還沒有決定拿哪一種。上周我買的是蘋果汁,上上周買的是什麼呢?白葡萄汁。我想現在是不是該買酸葡萄汁了。另一方面,我在思考的時候你正好站在我後面,你可能在想"這個白癡什麼時候才能拿一瓶,並且不要擋住我呢?我可知道自己想要什麼"!
你會發現,我們都站在微軟的雜貨店前面,在你能夠看見有哪些東西可以使用之前,你不得不等待,直到我做出決定為止。你看到了誘人的酸葡萄汁正擺放在貨架上,而我也許會買下它,這對於你來說根本是沒有意義的。因為我可能只是看看,但是微軟知道你希望購買水果汁,因此你必須等待我停止閒逛或者選中某樣東西,而這個過程都發生在你得到任何東西之前。
Oracle會使你更渺小、更容易的查看數據嗎?
在街上的Oracle店裡,你可以整天查看哪些東西可以使用,即使我已經查看了,或者我正處在挑選東西的過程中。可能果汁的種類更多,可能我更渺小了,誰知道呢?無論是哪種情況,我都沒有真正做出決定,因此為什麼不讓你看看有些什麼東西呢?也許我會拿走最後一瓶酸葡萄汁,也許不會。但是你看到有些什麼東西會有什麼壞處嗎?你可以打電話給妻子,告訴她"我忘了你要什麼東西了,但是這兒有些什麼..."
你會發現,在Oracle中,讀取者所關心的是,裡面不存在長時間的、持續很久的數據行更新。我可能在內存中修改某個數據行,盡管與其它的人有關,但是該數據行不會被更新,直到我真正地發出提交命令。實際上,我可能不是一個很好的程序員,可能在提交之前,把數據行保持很長時間。或者我可能決定根本不修改記錄,只是進行回滾操作。因此,根本就沒有數據發生改變,但是同時,你也可以繼續自己的業務,不管我是否登錄進系統中,更不用管我是否正在進行更新操作。但是,一旦我修改了數據行,並發出了提交命令,數據行才會改變,並且直到那個時候你才讀取到新的值。因為直到那個時候新的值才正式存在。
你可能認為這是很小的差異。但是我可以告訴你,它是至關緊要的一個。當你必須支持對相同范圍的相同數據表進行幾個並發的更新的某個系統的時候,如果同時始終有幾個用戶在查詢你正在操作的數據,你會發現"讀取者-阻塞-寫入者"機制將使產品停止運作。這種情況在企業系統中根本就是不可接受的。
也許我們以後還可能討論其它的一些架構方面的問題。例如:
· 由於內存不足造成鎖逐步增加
· 由於SQL Server無法支持讀操作的一致性,從而返回錯誤的數據
· 類似DBCC的時間密集型維護事務來檢測/防止性能惡化
· 微軟的"自我調節"數據庫,在很多情況下會妨礙數據庫管理(DBA)
· 無論TPC結果如何,SQL Server都缺少伸縮性
當然,還有更多的問題需要解決,不過今天就到這裡。