### 第5章版本庫管理
**目錄**
Subversion版本庫是保存任意數量項目版本化數據的中央倉庫,因此,版本庫成為管理員關注的對象。版本庫的維護一般并不需要太多的關注,但為了避免一些潛在的問題和解決一些實際問題,理解怎樣適當的配置和維護還是非常重要的。
在這一章里,我們將討論如何建立和配置一個Subversion版本庫,還會討論版本庫的維護,包括**svnlook**和**svnadmin**工具的使用(它們都包含在Subversion中)。我們將說明一些常見的問題和錯誤,并提供一些安排版本庫數據的建議。
如果您只是以普通用戶的身份訪問版本庫對數據進行版本控制(就是說通過Subversion客戶端),您完全可以跳過本章。但是如果您已經是或打算成為Subversion版本庫的管理員,您一定要關注一下本章的內容。
### 版本庫基本知識
在進入版本庫管理這塊寬廣的主題之前,讓我們進一步確定一下版本庫的定義,它是怎樣工作的?讓人有什么感覺?它希望茶是熱的還是冰的,加糖或檸檬嗎?作為一名管理員,你應該既從邏輯視角-數據在版本庫中如何展示,又能從物理具體細節的視角-版本庫如何響應一個非Subversion的工具,來理解版本庫的組成。下面的小節從一個比較高的層面覆蓋了這些基本概念。
### 理解事務和修訂版本
從概念上來說,Subversion的版本庫就是一串目錄樹。每一個目錄樹,就是版本庫的文件和目錄在某一時刻的快照。這些快照是客戶端使用者操作的結果,叫做修訂版本。
每一個修訂版本都是以事務樹開始其生命周期。做提交操作時,客戶端建立了一個映射本地修改的Subversion事務(加上客戶端提交操作后任何對版本庫的更改),然后指導版本庫將該樹存儲為下一個快照。要是提交成功,這個事務就會成為新的修訂版本樹,并被賦予新的修訂版本號。如果因為某些原因提交失敗,事務會被銷毀,客戶端將被通知這個事務失敗。
更新的動作也類似這樣。客戶端建立一個臨時的事務樹,映射工作文件的狀態。然后版本庫比較事務樹和被請求的修訂版本樹(通常是最新的,也就是最“年輕”的修訂版本樹),然后發回消息通知客戶端哪些變更需要將拷貝發送到修訂版本樹。更新完成后,臨時事務將被刪除。
事務樹的使用是對版本庫中版本控制文件系統產生永久變更的唯一方法。一個事務的生命周期非常靈活,了解這一點很重要。在更新的情況下,事務只是馬上會被銷毀的臨時樹。在提交的情況下,事務會變成固定的修訂版本(如果失敗的情況下,則會被刪除)。在出現錯誤或bug的情況下,事務可能會被留在版本庫中(不會影響任何東西,但是會占據空間)。
理論上,有一天整個流程能夠發展到對事務進行更加細密的流程控制。可以想象一個系統,在客戶端完成操作,將要保存到版本庫中時,每個加到它的事務都變成一個修訂版本。這將會使每一個新的提交都可以被別人查看到,也許是主管,也許是質量保證小組,他們可以決定是要接收這個事務成為修訂版本,還是放棄它。
### 未受版本控制的屬性
事務和修訂版本在Subversion版本庫中可以附加屬性。這些屬性就是普通的屬性名和屬性值的映射,被用來存儲與對應目錄樹有關的信息。這些屬性名和屬性值跟你的其他數據一樣,被存儲在版本庫文件系統中。
修訂版本和事務的屬性對于存儲一個跟目錄樹相關,但與樹中的某個具體目錄或文件不相關的性質很有用-即并不被客戶端工作拷貝所管理的屬性。舉例來說,當一個新的提交事務在版本庫中被創建時,Subversion給這個事務添加一個叫做`svn:date`的屬性―一個表示事務何時被創建的時間戳。當提交進程結束,該事務成為一個固定的修訂版本,這個目錄樹被賦予一個用來存儲這個版本作者名稱的屬性(`svn:author`)和一個用來存儲與這個修訂版本關聯日志信息的屬性(`svn:log`)。
修訂版本和事務的屬性都是未受版本控制的-因為當它們被修改時,先前的值就被完全舍棄了。修訂版本樹自身是不能變更的,與之關聯的屬性可以修改。你可在日后添加、刪除、修改修訂版本的屬性。如果你提交一個新的修訂版本之后意識到遺漏了一些信息或在日志中的拼寫錯誤,你可以直接以正確的信息覆蓋`svn:log`它的值。
### 版本庫數據存儲
在Subversion1.1中,版本庫中存儲數據有兩種方式。一種是在Berkeley DB數據庫中存儲數據;另一種是使用普通的文件,使用自定義格式。因為Subversion的開發者稱版本庫為[版本化的]文件系統,他們接受了稱后一種存儲方式為FSFS的習慣,也就是說,使用本地操作系統文件系統來存儲數據的版本化文件系統。
建立一個版本庫時,管理員必須決定使用Berkeley DB還是FSFS。它們各有優缺點,我們將詳細描述。這兩個中并沒有一個是更正式的,訪問版本庫的程序與采用哪一種實現方式無關。訪問程序并不知道版本庫如何存儲數據,它們只是從版本庫的API讀取到修訂版本和事務樹。
下面的表從總體上比較了Berkeley DB和FSFS版本庫,下一部分將會詳細講述細節。
**表5.1.版本庫數據存儲對照表**
| 特性 | Berkeley DB | FSFS |
|-----|-----|-----|
| 對操作中斷的敏感 | 很敏感;系統崩潰或者權限問題會導致數據庫“塞住”,需要定期進行恢復。 | 不敏感。 |
| 可只讀加載 | 不能 | 可以 |
| 存儲平臺無關 | 不能 | 可以 |
| 可從網絡文件系統訪問 | 不能 | 可以 |
| 版本庫大小 | 稍大 | 稍小 |
| 可擴展性:修訂版本樹的數量 | 數據庫,沒有限制 | 許多古老的本地文件系統在處理單一目錄包含上千個條目時出現問題。 |
| 可擴展性:文件較多的目錄 | 較慢 | 較快 |
| 速度:檢出最新的代碼 | 較快 | 較慢 |
| 速度: 大的提交 | 較慢,但是時間被分配在整個提交操作中 | 較快,但是最后較長的延時可能會導致客戶端操作超時 |
| 組訪問權處理 | 對于用戶的umask設置十分敏感,最好只由一個用戶訪問。 | 對umask設置不敏感 |
| 功能成熟時間 | 2001年開始使用 | 2004年開始使用 |
#### Berkeley DB
在Subversion的初始設計階段,開發者因為多種原因而決定采用Berkeley DB,比如它的開源協議、事務支持、可靠性、性能、簡單的API、線程安全、支持游標等。
Berkeley DB提供了真正的事務支持-這或許是它最強大的特性,訪問你的Subversion版本庫的多個進程不必擔心偶爾會破壞其他進程的數據。事務系統提供的隔離對于任何給定的操作,Subversion版本庫代碼看到的只是數據庫的靜態視圖-而不是一個在其他進程影響不斷變化的數據庫-并能夠根據該視圖作出決定。如果該決定正好同其他進程所做操作沖突,整個操作會回滾,就像什么都沒有發生一樣,并且Subversion會優雅的再次對更新的靜態視圖進行操作。
Berkeley DB另一個強大的特性是熱備份-不必“脫機”就可以備份數據庫環境的能力。我們將會在[“版本庫備份”一節]討論如何備份你的版本庫,能夠不停止系統對版本庫做全面備份的好處是顯而易見的。
Berkeley DB同時是一個可信賴的數據庫系統。Subversion利用了Berkeley DB可以記日志的便利,這意味著數據庫先在磁盤上寫一個日志文件,描述它將要做的修改,然后再做這些修改。這是為了確保如果如果任何地方出了差錯,數據庫系統能恢復到先前的檢查點―一個日志文件認為沒有錯誤的位置,重新開始事務直到數據恢復為一個可用的狀態。關于Berkeley DB日志文件的更多信息請查看[“管理磁盤空間”一節]。
但是每朵玫瑰都有刺,我們也必須記錄一些Berkeley DB已知的缺陷。首先,Berkeley DB環境不是跨平臺的。你不能簡單的拷貝一個在Unix上創建的Subversion版本庫到一個Windows系統并期望它能夠正常工作。盡管Berkeley DB數據庫的大部分格式是不受架構約束的,但環境還是有一些方面沒有獨立出來。其次,使用Berkeley DB的Subversion不能在95/98系統上運行―如果你需要將版本庫建在一個Windows機器上,請裝到Windows2000或WindowsXP上。另外,Berkeley DB版本庫不能放在網絡共享文件夾中,盡管Berkeley DB承諾如果按照一套特定規范的話,可以在網絡共享上正常運行,但實際上已知的共享類型幾乎都不滿足這套規范。
最后,因為Berkeley DB的庫直接鏈接到了Subversion中,它對于中斷比典型的關系型數據庫系統更為敏感。大多數SQL系統,舉例來說,有一個主服務進程來協調對數據庫表的訪問。如果一個訪問數據庫的程序因為某種原因出現問題,數據庫守護進程察覺到連接中斷會做一些清理。因為數據庫守護進程是唯一訪問數據庫表的進程,應用程序不需要擔心訪問許可的沖突。但是,這些情況與Berkeley DB不同。Subversion(和使用Subversion庫的程序)直接訪問數據庫的表,這意味著如果有一個程序崩潰,就會使數據庫處于一個暫時的不一致、不可訪問的狀態。當這種情況發生時,管理員需要讓Berkeley DB恢復到一個檢查點,這的確有點討厭。除了崩潰的進程,還有一些情況能讓版本庫出現異常,比如程序在數據庫文件的所有權或訪問權限上發生沖突。因為Berkeley DB版本庫非常快,并且可以擴展,非常適合使用一個單獨的服務進程,通過一個用戶來訪問―比如Apache的**httpd**或**svnserve**(參見[第6章 *配置服務器*])―而不是多用戶通過`file:///`或`svn+ssh://`URL的方式多用戶訪問。如果將Berkeley DB版本庫直接用作多用戶訪問,請先閱讀[“支持多種版本庫訪問方法”一節]。
#### FSFS
在2004年中期,另一種版本庫存儲系統慢慢形成了:一種不需要數據庫的存儲系統。FSFS版本庫在單一文件中存儲修訂版本樹,所以版本庫中所有的修訂版本都在一個子文件夾中有限的幾個文件里。事務在單獨的子目錄中被創建,創建完成后,一個單獨的事務文件被創建并移動到修訂版本目錄,這保證提交是原子性的。因為一個修訂版本文件是持久不可改變的,版本庫也可以做到熱備份,就象Berkeley DB版本庫一樣。
修訂版本文件格式代表了一個修訂版本的目錄結構,文件內容,和其它修訂版本樹中相關信息。不像Berkeley DB數據庫,這種存儲格式可跨平臺并且與CPU架構無關。因為沒有日志或用到共享內存的文件,數據庫能被網絡文件系統安全的訪問和在只讀環境下檢查。缺少數據庫花消同時也意味著版本庫的總體體積可以稍小一點。
FSFS也有一種不同的性能特性。當提交大量文件時,FSFS使用O(N)算法來追加條目,而Berkeley DB則用(N^2)算法來重寫整個目錄。另一方面,FSFS通過寫入與上一個版本比較的變化來記錄新版本,這也意味著獲取最新修訂版本時會比Berkeley DB慢一點,提交時FSFS也會有一個更長的延遲,在某些極端情況下會導致客護端在等待回應時超時。
最重要的區別是當出現錯誤時FSFS不會楔住的能力。如果使用Berkeley DB的進程發生許可錯誤或突然崩潰,數據庫會一直無法使用,直到管理員恢復。假如在應用FSFS版本庫時發生同樣的情況,版本庫不會受到任何干擾,最壞情況下也就是會留下一些事務數據。
唯一真正對FSFS不利的是相對于Berkeley DB的不成熟,缺乏足夠的使用和壓力測試,許多關于速度和可擴展性的判斷都是建立在良好的猜測之上。在理論上,它承諾會降低管理員新手的門檻并且更加不容易發生問題。在實踐中,只有時間可以證明。
這可能聽起來很崇高, 但我們所指的只是那些對管理別人工作拷貝數據之外的神秘領域感興趣的人。
- 第1章介紹
- Subversion的歷史
- Subversion的特性
- Subversion的架構
- 安裝Subversion
- Subversion的組件
- 快速入門
- 第2章基本概念
- 版本模型
- Subversion實戰
- 摘要
- 第3章指導教程
- 導入
- 修訂版本: 號碼、關鍵字和日期,噢,我的!
- 初始化的Checkout
- 基本的工作周期
- 檢驗歷史
- 其他有用的命令
- 摘要
- 第4章分支與合并
- 使用分支
- 在分支間拷貝修改
- 常見用例
- 轉換工作拷貝
- 標簽
- 分支維護
- 摘要
- 第5章版本庫管理
- 版本庫的創建和配置
- 版本庫維護
- 添加項目
- 摘要
- 第6章配置服務器
- 網絡模型
- svnserve,一個自定義的服務器
- httpd,Apache的HTTP服務器
- 支持多種版本庫訪問方法
- 第7章高級主題
- 屬性
- Peg和實施修訂版本
- 外部定義
- 賣主分支
- 本地化
- Subversion版本庫URL
- 第8章開發者信息
- 使用API
- 進入工作拷貝的管理區
- WebDAV
- 使用內存池編程
- 為Subversion做貢獻
- 第9章Subversion完全參考
- svn add
- svn blame
- svn cat
- svn checkout
- svn cleanup
- svn commit
- svn copy
- svn delete
- svn diff
- svn export
- svn help
- svn import
- svn info
- svn list
- svn log
- svn merge
- svn mkdir
- svn move
- svn propdel
- svn propedit
- svn propget
- svn proplist
- svn propset
- svn resolved
- svn revert
- svn status
- svn switch
- svn update
- svnadmin
- svnadmin create
- svnadmin deltify
- svnadmin dump
- svnadmin help
- svnadmin hotcopy
- svnadmin list-dblogs
- svnadmin list-unused-dblogs
- svnadmin load
- svnadmin lstxns
- svnadmin recover
- svnadmin rmtxns
- svnadmin setlog
- svnadmin verify
- svnlook
- svnlook author
- svnlook cat
- svnlook changed
- svnlook date
- svnlook diff
- svnlook dirs-changed
- svnlook help
- svnlook history
- svnlook info
- svnlook log
- svnlook propget
- svnlook proplist
- svnlook tree
- svnlook uuid
- svnlook youngest
- svnserve
- svnversion
- mod_dav_svn Configuration Directives
- 附錄A.Subversion對于CVS用戶
- 目錄的版本
- 更多離線操作
- 區分狀態和更新
- 分支和標簽
- 元數據屬性
- 沖突解決
- 二進制文件和轉化
- 版本化的模塊
- 認證
- 轉化CVS版本庫到Subversion
- 附錄C.WebDAV和自動版本化
- 自動版本化交互性
- Subversion和DeltaV
- 術語表