在Subversion的初始設(shè)計階段,開發(fā)者因為多種原因而決定采用Berkeley DB,比如它的開源協(xié)議、事務(wù)支持、可靠性、性能、簡單的API、線程安全、支持游標(biāo)等。
Berkeley DB提供了真正的事務(wù)支持-這或許是它強(qiáng)大的特性,訪問你的Subversion版本庫的多個進(jìn)程不必?fù)?dān)心偶爾會破壞其他進(jìn)程的數(shù)據(jù)。事務(wù)系統(tǒng)提供的隔離對于任何給定的操作,Subversion版本庫代碼看到的只是數(shù)據(jù)庫的靜態(tài)視圖-而不是一個在其他進(jìn)程影響不斷變化的數(shù)據(jù)庫-并能夠根據(jù)該視圖作出決定。如果該決定正好同其他進(jìn)程所做操作沖突,整個操作會回滾,像什么都沒有發(fā)生一樣,并且Subversion會優(yōu)雅的再次對更新的靜態(tài)視圖進(jìn)行操作。
Berkeley DB另一個強(qiáng)大的特性是熱備份-不必“脫機(jī)”可以備份數(shù)據(jù)庫環(huán)境的能力。(備份問題在本文暫不討論)
Berkeley DB同時是一個可信賴的數(shù)據(jù)庫系統(tǒng)。Subversion利用了Berkeley DB可以記日志的便利,這意味著數(shù)據(jù)庫先在磁盤上寫一個日志文件,描述它將要做的修改,然后再做這些修改。這是為了確保如果如果任何地方出了差錯,數(shù)據(jù)庫系統(tǒng)能恢復(fù)到先前的檢查點—一個日志文件認(rèn)為沒有錯誤的位置,重新開始事務(wù)直到數(shù)據(jù)恢復(fù)為一個可用的狀態(tài)。關(guān)于Berkeley DB日志文件的更多信息可以參考svn中文使用說明中的“管理磁盤空間”一節(jié)。
但是每朵玫瑰都有刺,我們也必須記錄一些Berkeley DB已知的缺陷。首先,Berkeley DB環(huán)境不是跨平臺的。你不能簡單的拷貝一個在Unix上創(chuàng)建的Subversion版本庫到一個Windows系統(tǒng)并期望它能夠正常工作。盡管Berkeley DB數(shù)據(jù)庫的大部分格式是不受架構(gòu)約束的,但環(huán)境還是有一些方面沒有獨立出來。其次,使用Berkeley DB的Subversion不能在95/98系統(tǒng)上運行—如果你需要將版本庫建在一個Windows機(jī)器上,請裝到Windows2000或WindowsXP上。另外,Berkeley DB版本庫不能放在網(wǎng)絡(luò)共享文件夾中,盡管Berkeley DB承諾如果按照一套特定規(guī)范的話,可以在網(wǎng)絡(luò)共享上正常運行,但實際上已知的共享類型幾乎都不滿足這套規(guī)范。
后,因為Berkeley DB的庫直接鏈接到了Subversion中,它對于中斷比典型的關(guān)系型數(shù)據(jù)庫系統(tǒng)更為敏感。大多數(shù)SQL系統(tǒng),舉例來說,有一個主服務(wù)進(jìn)程來協(xié)調(diào)對數(shù)據(jù)庫表的訪問。如果一個訪問數(shù)據(jù)庫的程序因為某種原因出現(xiàn)問題,數(shù)據(jù)庫守護(hù)進(jìn)程察覺到連接中斷會做一些清理。因為數(shù)據(jù)庫守護(hù)進(jìn)程是訪問數(shù)據(jù)庫表的進(jìn)程,應(yīng)用程序不需要擔(dān)心訪問許可的沖突。但是,這些情況與Berkeley DB不同。Subversion(和使用Subversion庫的程序)直接訪問數(shù)據(jù)庫的表,這意味著如果有一個程序崩潰,會使數(shù)據(jù)庫處于一個暫時的不一致、不可訪問的狀態(tài)。當(dāng)這種情況發(fā)生時,管理員需要讓Berkeley DB恢復(fù)到一個檢查點,這的確有點討厭。除了崩潰的進(jìn)程,還有一些情況能讓版本庫出現(xiàn)異常,比如程序在數(shù)據(jù)庫文件的所有權(quán)或訪問權(quán)限上發(fā)生沖突。因為Berkeley DB版本庫非?,并且可以擴(kuò)展,非常適合使用一個單獨的服務(wù)進(jìn)程,通過一個用戶來訪問—比如Apache的httpd或svnserve(可以參考svn中文使用說明中的 配置服務(wù)器)—而不是多用戶通過file:///或svn+ssh://URL的方式多用戶訪問。如果將Berkeley DB版本庫直接用作多用戶訪問,可以參考svn中文使用說明中的“支持多種版本庫訪問方法”一節(jié)。
FSFS
在2004年中期,另一種版本庫存儲系統(tǒng)慢慢形成了:一種不需要數(shù)據(jù)庫的存儲系統(tǒng)。FSFS版本庫在單一文件中存儲修訂版本樹,所以版本庫中所有的修訂版本都在一個子文件夾中有限的幾個文件里。事務(wù)在單獨的子目錄中被創(chuàng)建,創(chuàng)建完成后,一個單獨的事務(wù)文件被創(chuàng)建并移動到修訂版本目錄,這保證提交是原子性的。因為一個修訂版本文件是持久不可改變的,版本庫也可以做到熱備份,象Berkeley DB版本庫一樣。
修訂版本文件格式代表了一個修訂版本的目錄結(jié)構(gòu),文件內(nèi)容,和其它修訂版本樹中相關(guān)信息。不像Berkeley DB數(shù)據(jù)庫,這種存儲格式可跨平臺并且與CPU架構(gòu)無關(guān)。因為沒有日志或用到共享內(nèi)存的文件,數(shù)據(jù)庫能被網(wǎng)絡(luò)文件系統(tǒng)安全的訪問和在只讀環(huán)境下檢查。缺少數(shù)據(jù)庫花消同時也意味著版本庫的總體體積可以稍小一點。
FSFS也有一種不同的性能特性。當(dāng)提交大量文件時,F(xiàn)SFS使用O(N)算法來追加條目,而Berkeley DB則用(N^2)算法來重寫整個目錄。另一方面,F(xiàn)SFS通過寫入與上一個版本比較的變化來記錄新版本,這也意味著獲取新修訂版本時會比Berkeley DB慢一點,提交時FSFS也會有一個更長的延遲,在某些極端情況下會導(dǎo)致客護(hù)端在等待回應(yīng)時超時。
重要的區(qū)別是當(dāng)出現(xiàn)錯誤時FSFS不會楔住的能力。如果使用Berkeley DB的進(jìn)程發(fā)生許可錯誤或突然崩潰,數(shù)據(jù)庫會一直無法使用,直到管理員恢復(fù)。假如在應(yīng)用FSFS版本庫時發(fā)生同樣的情況,版本庫不會受到任何干擾,壞情況下也是會留下一些事務(wù)數(shù)據(jù)。
真正對FSFS不利的是相對于Berkeley DB的不成熟,缺乏足夠的使用和壓力測試,許多關(guān)于速度和可擴(kuò)展性的判斷都是建立在良好的猜測之上。在理論上,它承諾會降低管理員新手的門檻并且更加不容易發(fā)生問題。在實踐中,只有時間可以證明。
總之,這兩個中并沒有一個是更正式的,訪問版本庫的程序與采用哪一種實現(xiàn)方式無關(guān)。通過上文和下表(從總體上比較了Berkeley DB和FSFS版本庫),讀者可以自行選擇自己需要的存儲方式
特性 | Berkeley DB | FSFS |
---|---|---|
對操作中斷的敏感 | 很敏感;系統(tǒng)崩潰或者權(quán)限問題會導(dǎo)致數(shù)據(jù)庫“塞住”,需要定期進(jìn)行恢復(fù)。 | 不敏感。 |
可只讀加載 | 不能 | 可以 |
存儲平臺無關(guān) | 不能 | 可以 |
可從網(wǎng)絡(luò)文件系統(tǒng)訪問 | 不能 | 可以 |
版本庫大小 | 稍大 | 稍小 |
可擴(kuò)展性:修訂版本樹的數(shù)量 | 數(shù)據(jù)庫,沒有限制 | 許多古老的本地文件系統(tǒng)在處理單一目錄包含上千個條目時出現(xiàn)問題。 |
可擴(kuò)展性:文件較多的目錄 | 較慢 | 較快 |
速度:檢出新的代碼 | 較快 | 較慢 |
速度: 大的提交 | 較慢,但是時間被分配在整個提交操作中 | 較快,但是后較長的延時可能會導(dǎo)致客戶端操作超時 |
組訪問權(quán)處理 | 對于用戶的umask設(shè)置十分敏感,好只由一個用戶訪問。 | 對umask設(shè)置不敏感 |
功能成熟時間 | 2001年開始使用 | 2004年開始使用 |