作者:Sanjay Ghemawat
          Howard Gobioff
          Shun-Tak Leung
翻译:tinyfool

2.6.3 操作日志

操作日志包含核心元数据变化的历史记录。这对GFS很重要。这不仅是因为它是元数据唯一的持久化存储记录,而且因为它起到了定义同步操作顺序的逻辑时间线的作用。文件和块以及他们的版本,都是唯一和持久地由他们创建时的逻辑时间标识的。

因为操作日志很重要,我们必须稳定的保存它,并保证只有在元数据的变化被持久化保存后,这种变化才对客户端可见。否则,即使块没有发生任何问题,我们仍有可能丢失整个文件系统,或者丢失近期的客户端操作。所以,我们把操作日志复制到多台远程机器,而且仅在把最近的日志记录写入本地以及远程机器的硬盘后,才会对客户端操作进行响应。写入之前主服务器批量处理数个日志记录,减少写入和复制的负载。

主服务器通过重放操作日志恢复它的文件系统。为了降低启动时间,我们必须保持日志足够小。 当日志增长到一个特定尺寸的时候,主服务器就会汇总它的状态为一个检查点,这样它就可以通过从硬盘调入最新的一个检查点来恢复系统,只需要重放检查点后有限数目的日志记录即可。检查点保存在一个压缩B-树形式的结构里,可以直接映射到内存,而且用于命名空间查询时无需额外的解析。这大大提高了恢复速度,而且增强了可用性。

创建一个检查点可能会花点时间,所以主服务器的内部状态被结构为一种形式,这种形式保证了检查点的创建不会对正好这时进入的动作造成延迟。主服务器用分别的线程切换到新的日志文件和创建新的检查点。新的检查点包括切换前所有的动作。集群有百万文件时,创建一个检查点需要一分钟左右。创建完成后,检查点会被写入在本地和远程的硬盘里。

进行恢复仅需要最新的检查点和相应的日志文件。老的检查点和日志文件可以自由的被删除,不过我们通常会保存一些用来应付数据灾难。创建检查点过程中的失败不会对正确性产生任何影响,因为恢复代码可以检测并跳过没有完成的检查点。