目录
Subversion资料库是一个可以保存任意多个项目的版本化数据的中心仓库。因此,它成为管理员宠爱和关注最明显的选择对象。 虽然资料库通常不需要太多维护,但是理解如何正确的配置和照看它是非常重要的,这样能避免潜在的问题,并安全的解决实际的问题。
在本章,我们讨论如何创建和配置Subversion资料库。我们也会谈到资料库维护,包括svnlook和 svnadmin工具(它们随Subversion一起提供)的用法。我们将强调一些常见的问题和错误,给出一些 如何安排资料库中数据的建议。
如果你计划只以一个有数据处于版本控制之下的用户的角色来访问资料库(就是说,通过Subversion客户程序), 你完全可以跳过这一章。但是,如果你是,或者想成为一个Subversion资料库管理员, [11] 你一定要重视这一章。
在投入资料库管理的广阔主题之前,我们来进一步定义什么是资料库。它看起来什么样?感觉起来什么样?它喝茶喜欢热的 还是冰的,加糖吗?还是要点柠檬?作为一个管理员,你应该从两方面都理解资料库的组成,逻辑视图——关于数据在资料库中 如何表示;具体的物理视图——对于非Subversion工具,资料库看起来和用起来是怎样的。下一节非常概括的介绍了一些基本的概念。
从概念上说,一个Subversion资料库是一系列的目录树。每个树是一个你资料库中版本化的文件和目录在某个时间点的快照。 这些快照是由一些客户端操作的结果形成的,它们被称为修订版。
每个修订版的生命从一个事务树开始。当作一次提交时,客户程序创建了一个事务,它把本地修改(加上那些 从客户提交开始时已经发生在资料库中的修改)做镜像并指示资料库把这个树 作为序列中下一个修订版保存。如果提交成功,这个事务被有效的提升为新的修订版树。如果由于某些原因提交失败,这个事务被 取消并把失败通知到客户端。
更新以类似的方式工作。客户程序创建了一个临时的事务树,它是工作副本状态的镜像。然后资料库比较事务树和被请求的修订版树( 通常是最近的,或者“最年轻的”树),并把信息送回客户端,通知它要把它们的工作副本 转化为那个修订版树的拷贝需要那些修改。在更新完成后,临时事务会被删除。
唯一的对资料库中版本化的文件系统作永久修改的方法是利用事务树。但是,明白事务的生命周期的高度灵活性是非常重要的。 在更新的情况下,事务是会被立即删除的临时树。在提交的情况下,事务被转化为永久的修订版(如果提交失败,会被删除)。 在出错或者有bug的情况下,事务可能会意外的留在资料库哪儿(不会真的影响什么,但仍然占用空间)。
理论上,某天整个工作流应用可能围绕一个更加细粒度的事务生命周期展开。设想这样一个系统应是可行的, 在客户端向资料库描述了它的修改后,每个被提名要成为修订版的事务将停留在那里。 这将使每一次新的提交都能被别人检查,可能经理或者QA团队的工程师,他们能选择把事务提升为修订版,或者中止它。
资料库中的事务和修订版可以在他们上面附加属性。这些属性是普通的键值映射,通常用来保存一些它们附加于其上的树的信息。 这些属性的名字和值和你其他的树数据一起被存储在资料库文件系统中。
修订版和事务属性可以用来把那些在树中与文件和目录没有明确的关系的信息关联到树上
——那种不由客户工作副本来管理的信息。例如,当一个新的提交事务在资料库中被创建时,Subversion添加一个
名为svn:date的属性到这个事务——一个表示事务创建时间的日期戳。到提交过程完成,并且
事务被提升为持久的修订版,这个树也会被赋予一个属性来保存修订版作者的名字(svn:author),
还有一个属性来保存附加于这个修订版的日志消息(svn:log)。
修订版和事务属性是非版本化属性(unversioned properties)——当它们被修改后,它们
先前的值就被永远丢弃了。并且,虽然修订版树本身是不可变的,但是附加于其上的属性并非如此。你可以在以后任何时候添加,删除
,以及修改修订版属性。如果你提交了一个新的修订版,后来发现你在日志信息中写了某些错误的信息或有些拼写错误,你只要
用新的正确的日志信息替换svn:log属性原来的值就行了。
到Subversion1.1版,在资料库中存储数据有两种选择。一种资料库类型是把所有东西保存在Berkeley DB数据库中; 另一种在普通的文件中,用一种自定义的格式来保存数据。因为Subversion开发者常常把资料库称为“[版本化的]文件系统” ,它们习惯于称后一种资料库为FSFS:就是说,这是一种用本地操作系统文件系统存储数据来实现的版本化文件系统。
当一个资料库创建时,管理员必须决定是用Berkeley DB 还是 FSFS。它们各有优缺点,我们一会儿会谈到。 没有哪个比另一个更“官方”,访问资料库的程序和实现细节是隔离的。程序不知道资料库是如何存储数据的; 它们只是通过资料库API来查看修订版和事务。
这里有一张表,总体上比较了Berkeley DB 和FSFS 资料库。下一节将深入细节。
表 5.1. 资料库数据存储比较
| 特性 | Berkeley DB | FSFS |
|---|---|---|
| 对中断的敏感性 | 非常敏感;失败或者遇到权限问题会留在数据库里“像个楔子”,需要进行日志恢复过程。 | 非常不敏感。 |
| 是否能通过只读的mount使用 | 否 | 是 |
| 平台独立的存储 | 否 | 是 |
| 通过网络文件系统使用 | 否 | 是 |
| 资料库大小 | 较大 | 较小 |
| 伸缩性:修订版树的数目 | 数据库;没问题 | 一些老的本地文件系统不能处理在单个目录里有数千项的情况。 |
| 伸缩性:有很多文件的目录 | 较慢 | 较快 |
| 速度:检出最新的代码 | 较快 | 较慢 |
| 速度:大的提交 | 较慢,但工作负担散布在整个提交过程中 | 较快,但最后的延迟可能导致客户端超时 |
| 群组权限处理 | 对用户umask问题敏感;最好只用一个用户访问 | 可在有umask问题情况下工作 |
| 代码成熟度 | 从2001年开始使用 | 从2004年开始使用 |
在最初的Subversion设计阶段进行时,有很多原因使开发者决定使用Berkeley DB,包括它是基于开源许可证的, 可以支持事务,可靠性,性能,API简单性,线程安全,支持游标等等。
Berkeley DB 提供了真正的事务支持——可能是它最强的特性。当多个进程访问你的资料时,不用担心破坏别人的数据。 事务系统提供的这种隔离使得对于任何操作,Subversion资料库代码看到的是数据库的一个静态视图——而不是一个 在别的程序控制下经常改变的数据库——从而可以根据这个视图来作决定。如果做出的决策碰巧和别的进程作的冲突, 整个操作被会滚,就像从未发生过。Subversion会适当的在新的,更新了的(并且仍然是静态的)数据库视图上尝试操作。
Berkeley DB 的另一个主要特性是热备份(hot backups)——不使数据库“离线”就能备份它的能力。 我们在“资料库备份”一节将讨论如何备份资料库,但可以对你的资料库做完整的全功能的备份而不需要 停工的好处是显而易见的。
Berkeley DB也是一个非常可靠的数据库系统。Subversion使用了Berkeley DB的日志工具,这意味着 数据库首先把所有修改的描述写到磁盘上的日志文件里,然后才进行修改。这保证了如果有什么错误发生, 数据库系统可以回到先前的检查点checkpoint——日志文件记录的不会崩溃的那个地方—— 直到数据恢复到稳定状态再重新开始事务。参见“管理磁盘空间”一节得到更多Berkeley DB日志文件的信息
但是每一支玫瑰都是带刺的,我们必须说明Berkeley DB的一些已知的局限。首先,Berkeley DB环境是不易移植的。你不能简单地 把一个在Unix系统创建的Subversoin资料库复制到一个Windows系统并期望它能工作。虽然Berkeley DB数据库格式大体上是独立的架构, 但是有一些环境方面不是这样。第二,Subversion使用Berkeley DB的方式无法在Windows 95/98系统上工作——如果你需要在Windows机器 上保存一个资料库,一定要用Windows 2000 或 Windows XP。并且,你应该永远不要把 Berkeley DB 资料库保存在一个网络共享中。 虽然 Berkeley DB 承诺可以在满足一系列特定条件的网络共享上工作,但是几乎没有哪个已知的共享可以真的满足所有那些条件。
最后,因为Berkeley DB是Subversion直接连接的库。因此,它比通常的关系数据库系统对中断更为敏感。
例如,大部分SQL系统有一个专用的服务器进程来协调所有对表的访问。如果一个正在访问数据的程序由于某些原因崩溃了,这个数据库
守护进程注意到这个中断的连接并清理任何遗留的垃圾。并且因为这个数据库守护进程是唯一可以访问表的进程,应用程序不需要担心
权限冲突。但是,在Berkeley DB里不是这样的。Subversion(以及使用Subversion库的程序)直接访问数据库表,这意味着程序崩溃会
使数据库处于一个暂时的不一致的、不可访问的状态。当这种事发生时,管理员需要让Berkeley DB恢复到一个检查点,这有一点儿烦人。
除了进程崩溃,其他的事也可以导致资料库“被楔住”,比如有某些程序在数据库文件的权限和归属上冲突。因此虽然
BerkeleyDB资料库非常快和可伸缩,但最好通过单个用户的单个服务器进程来使用——比如Apache的httpd或者
svnserve(参见第 6 章 服务器配置)——而不是由许多不同的用户通过file:///或者
svn+ssh://URL来访问它。如果要直接通过多个用户来使用Berkeley DB,一定要读“支持多种资料库访问方式”一节。
在2004年中,第二种资料库存储系统诞生了:一个完全不用数据库的系统。FSFS资料库在单个文件中保存一个修订版树,因此所有的资料库 修订版可以在一个放满了编号文件的单个子目录中找到。事务在另一个分开的子目录里创建。当事务完成时,一个单一的事务文件被创建并 移动到修订版目录中,因而保证了提交是原子的。并且因为修订版文件是永久的不变的,这种资料库也可以在“运行中”备份, 就像Berkeley DB资料库那样。
修订版文件格式代表了一个修订版的目录结构,文件内容,以及对于其他修订版树中文件的增量。与Berkeley DB数据库不同, 这种存储格式可以在不同操作系统间移植并对CPU架构不敏感。因为没有使用日志文件或内存共享文件,资料库可以通过网络文件系统安全的 访问并在只读环境中查看。没有数据库也意味着整个资料库尺寸要较小一点。
FSFS也有不同的性能特性。当提交一个有大量文件的目录是,FSFS使用一个O(N)的算法来追加条目,而 Berkeley DB 使用一个O(N^2)的算法 来重写整个目录。另一方面,FSFS用相对于先前的树的增量来写最新的文件版本,这意味着检出最新的树要比取出再Berkeley DB HEAD修订 版中的全文存储的数据要慢一些。FSFS在最后完成提交时还有一个较长的延时,这在极端情况下会导致客户端在等待响应时超时
然而最重要的不同是如果发生了错误FSFS不会被“楔住”。如果一个使用Berkeley DB数据库的进程碰到权限问题或者突然 崩溃了,数据库将处于不可用状态直到管理员恢复它。如果相同的场景发生在使用FSFS资料库的进程上,资料库根本不会受影响。最坏的 情况是一些事务数据被留在那儿了。
唯一真正的对于FSFS的争议是它相对于Berkeley DB不成熟。它还没有被大量的使用和压力测试过,因此关于速度和伸缩性的许多断言不过 是这样:基于良好的推测得出的断言。理论上,它承诺对新管理员门槛较低并不易发生问题。实践上,只有让时间来做判断。