文档

备份规则说明

更新时间:

备份模式

  • 全量+增量:代码备份默认支持全量+增量模式,以提升备份速度,节约备份空间;

  • 归档和清理:备份数据每隔七天会自动归档,用户可根据自身情况决定是否清理历史归档,释放存储空间,节约OSS存储成本;

全量备份

全量备份即对当前的仓库进行全量的备份,备份内容包含仓库的全部引用和全部对象,所以全量备份通常耗时较长。备份成功后, 用户可以从 OSS 下载对应的全量备份文件,并轻松的恢复成一个 Git 仓库, 更多关于恢复的介绍请看后文。

默认地, 当仓库第一次备份时, 因为OSS上没有任何历史的备份存在,Codeup 将进行一次全量备份。例如, 一个企业仓库路径叫做 alibaba/codeup.git, 当对其进行全量备份成功后, OSS 上存储的备份文件和路径如下:

6-7.png

根据OSS控制台的截图, 我们来对存储的存放问题进行详细介绍:

存储路径:企业下的所有备份(归档除外)都将存储在OSS Bucket下的名为repositories目录下(截图中蓝框开头), 仓库备份文件的存储路径格式为 /repositories/<企业仓库路径>/<仓库UUID>,其中:

  • 第一级路径/repositories: 所有企业的仓库备份的根路径

  • 第二级路径<企业仓库路径>:企业仓库的路径,例如本例中为alibaba/codeup

  • 第三级路径<仓库UUID>: 企业仓库的唯一标识值

备份相关文件

  • 备份文件名格式: 一次仓库备份将生成并上传多个文件, 这些文件有统一的文件前缀名称,但不同的文件后缀, 例如上图示例中备份共生成了4个文件, 其中文件前缀名称为"alibaba_codeup-full-20210223094414", 而文件后缀名各不相同

  • .bundle文件:bundle文件是备份文件中最核心的文件,用户可以根据bundle文件将仓库备份还原为一个Git仓库,bundle文件后缀为".bundle"

  • .list文件: list文件为备份时刻仓库ref信息的汇总记录,对比不同的list文件,可以轻松的查看两次备份间隔仓库ref发生的变化(更新、新增或删除)

  • .checksum文件:checksum文件为备份时刻仓库数据的checksum值, 用户无需关注

  • .lsremote文件: lsremote文件为备份后针对bundle文件的ls-remote信息记录,用户无需关注

增量备份

增量备份对比全量备份稍复杂,具备在备份的空间占用上通常更小,执行速度更快的特点。每当 Codeup 检测到在当前 /repositories/<企业仓库路径>/<仓库UUID> 下存在历史备份时,备份策略都会选择使用增量备份而非全量备份。

仓库有更新的增量备份场景

假设,当前仓库备份存在一次历史的全量备份文件,在第二次触发仓库备份之前,我们向仓库的某一分支做了新的代码推送。 随后触发一次新的仓库备份,因为仓库存在update,将对仓库进行增量备份, 如下图:

6-7.png

根据OSS控制台的截图, 我们来对应介绍:

  • 存储路径: 增量备份的存储路径与全量备份的存储位置并无差别,仓库备份文件的存储路径格式仍为 /repositories/<企业仓库路径>/<仓库UUID>, 新的备份文件:

# 产生4个增量备份文件,序号为1(在文件名中有所体现),分别为:
alibaba_codeup-inc-1-20210224074738.bundle
alibaba_codeup-inc-1-20210224074738.checksum
alibaba_codeup-inc-1-20210224074738.list
alibaba_codeup-inc-1-20210224074738.lsremote

备份相关文件介绍:

  • 备份文件名格式: 增量备份与全量备份类似,文件类型与全量备份的文件类型相同,差异在备份文件的命名上,全量备份文件的标识为full, 而增量备份文件标识为inc-<order>, 其中<order> 代表增量的次数序号。文件名称的差别,可以让我们清楚的区分备份的类型是全量的还是增量。

仓库无更新的增量备份场景

如果在仓库没有产生新的更新的情况下, 即没有更新的版本提交推送或者只有删除ref的操作(例如删除分支),当触发仓库增量备份后, 不会产生.bundle.lsremote文件。

根据OSS控制台的截图, 我们来对应介绍:

# 产生3个增量备份文件,序号为2(因为本次为第二次增量备份),分别为:
alibaba_codeup-inc-2-20210224082031.bundle.log
alibaba_codeup-inc-2-20210224082031.checksum
alibaba_codeup-inc-2-20210224082031.list

备份相关文件介绍:

*.bundle.log文件: 因为仓库没有更新,所以本次增量备份不会产生.bundle.lsremote 文件。但会代替产生一个.bundle.log 文件,文件中记录了此次备份没有产生.bundle文件的原因:

# alibaba_codeup-inc-2-20210224082031.bundle.log 文件
内容如下:
fatal:Refusing to create empty bundle.

文件内容的含义为,因为仓库没有更新,不会创建bundle文件。虽然不会创建bundle文件,但是本次增量备份仍然是成功的, 因为可能存在ref被删除的情况,这种情况下可以通过对比与上一次备份的.list的差异便可以追溯。

历史备份文件归档

从前面的介绍,我们了解到的仓库备份文件生成的位置位于/repositories/<企业仓库路径>/<仓库UUID>下,随着备份次数和备份文件的增多,管理和寻找备份文件可能会变得越加困难,所以 Codeup 提供了历史备份归档功能解决这一问题,同时也可以尽可能的节约存储空间成本。

历史备份归档的触发条件

/repositories/<企业仓库路径>/<仓库UUID>下存储的.bundle文件个数 >=7(个)时, 备份将自动触发归档功能, 将当前/repositories/<企业仓库路径>/<仓库UUID>下存储的全部备份文件进行归档, 归档目录为:

/archive/<企业仓库路径>/<仓库UUID>/rotate-<归档日期>,当归档完成后,将自动重新触发一次全量备份。

归档目录截图如下:

4

归档目录中包含了上一时刻备份目录下的所有备份文件。

归档结束后, 会自动对仓库进行一次全量备份。

备份如何恢复

当存在成功的备份记录,进入对应 OSS 空间查看:

7根据全量备份还原

下面将介绍,如何根据全量备份文件进行还原:

  • 首先, 将全量备份文件从OSS上下载到本地

➜  ls |grep bundle
alibaba_codeup-full-20210224084658.bundle
  • 下载完成后,根据全量备份的bundle文件进一步恢复代码仓库

➜  git clone alibaba_codeup-full-20210224084658.bundle
Cloning into 'alibaba_codeup-full-20210224084658'...
Receiving objects: 100% (6/6), done.
➜  cd alibaba_codeup-full-20210224084658
➜  ls -ltra
total 8
drwx------@  7 tenglong.tl  staff  224  2 24 16:54 ..
drwxr-xr-x   4 tenglong.tl  staff  128  2 24 16:54 .
-rw-r--r--   1 tenglong.tl  staff    6  2 24 16:54 test.file
drwxr-xr-x  13 tenglong.tl  staff  416  2 24 16:54 .git

可以看到,此时我们根据 bundle 文件已经成功 clone 出了要恢复的代码仓库。

根据增量备份还原

增量还原与全量还原类似但稍稍复杂,不是clone而是fetch(pull)操作,假设我们现在拥有三个备份的文件, 分别为三个时间点产生(T0/T1/T2/T3), 其中:

  • T0: 对应的bundle文件为alibaba_codeup-full-20210224084658.bundle

  • T1: 对应的bundle文件为alibaba_codeup-inc-1-20210224084659.bundle

  • T2: 仓库对比T1没有增量更新内容, 故不会产生.bundle文件, 而会产生.bundle.log文件

  • T3: 对应的bundle文件为alibaba_codeup-inc-3-20210224084700.bundle首先,需要根据T0时刻备份文件恢复代码仓库, 下载全量备份文件alibaba_codeup-full-20210224084658.bundle到本地, 然后执行git clone操作进行备份还原:

➜  git clone alibaba_codeup-full-20210224084658.bundle recovery.git

执行成功后,recovery.git为T0时刻代码仓库。

  • 在此基础上, 如果我们要将recovery.git仓库恢复为T1时刻代码仓库,那么只需下载T1时刻的增量备份文件alibaba_codeup-inc-1-20210224084659.bundle到本地, 然后执行:

➜  cd recovery.git
➜  git remote add inc-1 ~/Downloads/alibaba_codeup-inc-1-20210224084659.bundle 
➜  git fetch inc-1
Receiving objects: 100% (6/6), done.
From /Users/tenglong.tl/Downloads/alibaba_codeup-inc-1-20210224084659.bundle
 * [new branch]      topic_2    -> inc-1/topic_2
 * [new branch]      master     -> inc-1/master
 * [new tag]         v2.0       -> v2.0

可以看到我们基于T0时刻的代码仓库,成功将T1时刻的增量内容更新到了recovery.git仓库中, 如果我们希望切换到更新后的某一个分支,可以执行:

➜  git checkout -b topic_2 inc-1/topic_2
Branch 'topic_2' set up to track remote branch 'topic_2' from 'inc-1'.
Switched to a new branch 'topic_2'
  • 以T0时刻代码仓库为基础, 下载T3时刻的增量备份文件alibaba_codeup-inc-3-20210224084700.bundle到本地, 然后执行:

➜  git remote add inc-3 ~/Downloads/alibaba_codeup-inc-3-20210224084700.bundle 
➜  git fetch inc-3
Receiving objects: 100% (3/3), done.
From /Users/tenglong.tl/Downloads/alibaba_codeup-inc-3-20210224084700.bundle
 * [new branch]      master     -> inc-3/master

同理,此时我们已经将T3时刻的增量内容更新到了 recovery 仓库中,可以看到本次更新的分支为 master 分支,如果我们希望 checkout 到T3时刻的 master 上, 可以执行:

➜  git checkout master
➜  git pull inc-3 master
From /Users/tenglong.tl/Downloads/alibaba_codeup-inc-3-20210224084700.bundle
 * branch            master     -> FETCH_HEAD
Updating 324711e..4bdbff9
Fast-forward
 lol.txt | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 lol.txt

这样成功根据 T3 时刻的备份, 恢复了当时的 master 分支的内容。

重要

如果我们只需要恢复到全量备份的时间点, 我们只需下载对应的全量备份文件, 然后执行git clone <xxxx-full-xxxx.bundle>即可恢复;

根据我们的增量备份原理, 假设如果当前有T0->T1->T2 三个时刻的备份文件, 如果我们要恢复T3时刻仓库, 必须按照顺序首先依次恢复 T0 ,T1 和 T3 的备份文件, 如果直接根据 T2 时刻的备份文件,将会失败;