{{< details >}}

  • Tier: 基础版,专业版,旗舰版
  • Offering: 私有化部署

{{< /details >}}

极狐GitLab 的恢复操作从备份中恢复数据,以维护系统连续性并从数据丢失中恢复。恢复操作:

  1. 恢复数据库记录和配置
  2. 恢复 Git 仓库、容器注册表镜像和上传的内容
  3. 恢复软件包注册表数据和 CI/CD 产物
  4. 恢复账户和群组设置
  5. 恢复项目和群组维基
  6. 恢复项目级别的安全文件
  7. 恢复外部合并请求差异

恢复过程需要一个与备份相同版本的现有极狐GitLab 安装。请遵循先决条件并在生产环境中使用之前测试完整的恢复过程。

恢复先决条件

目标极狐GitLab 实例必须已经在运行

在执行恢复之前,您需要一个正常运行的极狐GitLab 安装。这是因为执行恢复操作的系统用户(git)通常不被允许创建或删除 SQL 数据库(gitlabhq_production)以导入数据。所有现有数据要么被删除(SQL),要么移动到一个单独的目录(例如仓库和上传)。恢复 SQL 数据时会跳过由 PostgreSQL 扩展拥有的视图。

目标极狐GitLab 实例必须具有完全相同的版本

您只能将备份恢复到创建时的完全相同版本和类型(CE 或 EE)的极狐GitLab。例如,CE 15.1.4。

如果您的备份版本与当前安装版本不同,您必须在恢复备份之前降级升级您的极狐GitLab 安装。

极狐GitLab 机密必须恢复

要恢复备份,您还必须恢复极狐GitLab 机密。如果您正在迁移到一个新的极狐GitLab 实例,您必须从旧服务器复制极狐GitLab 机密文件。这些包括数据库加密密钥、CI/CD 变量和用于双因素身份验证的变量。没有这些密钥,会发生多个问题,包括启用双因素身份验证的用户无法访问,以及极狐GitLab Runner 无法登录。

恢复:

  1. /etc/gitlab/gitlab-secrets.json(Linux 软件包安装)
  2. /home/git/gitlab/.secret(自行编译安装)
  3. 恢复机密(云原生极狐GitLab)

某些极狐GitLab 配置必须与原始备份环境匹配

您可能还希望恢复之前的 /etc/gitlab/gitlab.rb(对于 Linux 软件包安装)或 /home/git/gitlab/config/gitlab.yml(对于自行编译安装)以及任何 TLS 密钥、证书(/etc/gitlab/ssl/etc/gitlab/trusted-certs)或SSH 主机密钥。

某些配置与 PostgreSQL 中的数据紧密相关。例如:

  • 如果原始环境有三个仓库存储(例如,defaultmy-storage-1my-storage-2),那么目标环境也必须在配置中定义至少这些存储名称。
  • 从使用本地存储的环境恢复备份,即使目标环境使用对象存储,也会恢复到本地存储。迁移到对象存储必须在恢复之前或之后完成。

恢复作为挂载点的目录

如果您正在恢复到作为挂载点的目录中,您必须确保这些目录在尝试恢复之前是空的。否则,极狐GitLab 会在恢复新数据之前尝试移动这些目录,从而导致错误。

阅读更多关于配置 NFS 挂载的信息。

Linux 软件包安装的恢复

此过程假设:

  1. 您已经安装了与创建备份时完全相同版本和类型(CE/EE)的极狐GitLab。
  2. 您至少已经运行过一次 sudo gitlab-ctl reconfigure
  3. 极狐GitLab 正在运行。如果没有,请使用 sudo gitlab-ctl start 启动它。

首先,确保您的备份 tar 文件位于 gitlab.rb 配置中描述的备份目录 gitlab_rails['backup_path'] 中。默认路径是 /var/opt/gitlab/backups。备份文件需要由 git 用户拥有。

sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/
sudo chown git:git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar

停止连接到数据库的进程。让其他极狐GitLab 继续运行:

sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
# Verify
sudo gitlab-ctl status

接下来,确保您已完成恢复先决条件步骤,并在从原始安装复制极狐GitLab 机密文件后运行 gitlab-ctl reconfigure

接下来,恢复备份,指定您希望恢复的备份 ID:

{{< alert type=”warning” >}}

以下命令将覆盖您的极狐GitLab 数据库的内容!

{{< /alert >}}

# NOTE: "_gitlab_backup.tar" is omitted from the name
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

如果您的备份 tar 文件与安装的极狐GitLab 版本不匹配,则恢复命令会中止并显示错误消息:

GitLab version mismatch:
  Your current GitLab version (16.5.0-ee) differs from the GitLab version in the backup!
  Please switch to the following version and try again:
  version: 16.4.3-ee

安装正确的极狐GitLab 版本,然后重试。

{{< alert type=”warning” >}}

当您的安装使用 PgBouncer 时,恢复命令需要附加参数,无论是出于性能原因还是与 Patroni 集群一起使用。

{{< /alert >}}

接下来,重启并检查极狐GitLab:

sudo gitlab-ctl restart
sudo gitlab-rake gitlab:check SANITIZE=true

验证数据库值可以被解密,特别是如果 /etc/gitlab/gitlab-secrets.json 被恢复,或者如果目标恢复是不同的服务器。

sudo gitlab-rake gitlab:doctor:secrets

为了增加保证,您可以对上传的文件执行完整性检查

sudo gitlab-rake gitlab:artifacts:check
sudo gitlab-rake gitlab:lfs:check
sudo gitlab-rake gitlab:uploads:check

恢复完成后,建议生成数据库统计信息以提高数据库性能并避免 UI 中的不一致:

  1. 进入数据库控制台
  2. 运行以下命令:

    SET STATEMENT_TIMEOUT=0 ; ANALYZE VERBOSE;
    

Docker 镜像和极狐GitLab Helm chart 安装的恢复

对于使用 Docker 镜像或极狐GitLab Helm chart 在 Kubernetes 集群上的极狐GitLab 安装,恢复任务期望恢复目录为空。然而,使用 Docker 和 Kubernetes 卷挂载时,一些系统级目录可能会在卷根创建,例如 Linux 操作系统中发现的 lost+found 目录。这些目录通常由 root 拥有,这可能会导致访问权限错误,因为恢复 Rake 任务以 git 用户身份运行。要恢复极狐GitLab 安装,用户必须确认恢复目标目录为空。

对于这两种安装类型,备份 tar 包必须位于备份位置(默认位置是 /var/opt/gitlab/backups)。

Helm chart 安装的恢复

极狐GitLab Helm chart 使用恢复极狐GitLab Helm chart 安装中记录的过程

Docker 镜像安装的恢复

如果您正在使用 Docker Swarm,因为 Puma 被关闭,所以容器可能在恢复过程中重启,从而导致容器健康检查失败。为了解决这个问题,临时禁用健康检查机制。

  1. 编辑 docker-compose.yml

    healthcheck:
      disable: true
    
  2. 部署堆栈:

    docker stack deploy --compose-file docker-compose.yml mystack
    

可以从主机运行恢复任务:

# Stop the processes that are connected to the database
docker exec -it <name of container> gitlab-ctl stop puma
docker exec -it <name of container> gitlab-ctl stop sidekiq

# Verify that the processes are all down before continuing
docker exec -it <name of container> gitlab-ctl status

# Run the restore. NOTE: "_gitlab_backup.tar" is omitted from the name
docker exec -it <name of container> gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

# Restart the GitLab container
docker restart <name of container>

# Check GitLab
docker exec -it <name of container> gitlab-rake gitlab:check SANITIZE=true

自行编译安装的恢复

首先,确保您的备份 tar 文件位于 gitlab.yml 配置中描述的备份目录中:

## Backup settings
backup:
  path: "tmp/backups"   # Relative paths are relative to Rails.root (default: tmp/backups/)

默认是 /home/git/gitlab/tmp/backups,并且需要由 git 用户拥有。现在,您可以开始备份程序:

# Stop processes that are connected to the database
sudo service gitlab stop

sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production

示例输出:

Unpacking backup... [DONE]
Restoring database tables:
-- create_table("events", {:force=>true})
   -> 0.2231s
[...]
- Loading fixture events...[DONE]
- Loading fixture issues...[DONE]
- Loading fixture keys...[SKIPPING]
- Loading fixture merge_requests...[DONE]
- Loading fixture milestones...[DONE]
- Loading fixture namespaces...[DONE]
- Loading fixture notes...[DONE]
- Loading fixture projects...[DONE]
- Loading fixture protected_branches...[SKIPPING]
- Loading fixture schema_migrations...[DONE]
- Loading fixture services...[SKIPPING]
- Loading fixture snippets...[SKIPPING]
- Loading fixture taggings...[SKIPPING]
- Loading fixture tags...[SKIPPING]
- Loading fixture users...[DONE]
- Loading fixture users_projects...[DONE]
- Loading fixture web_hooks...[SKIPPING]
- Loading fixture wikis...[SKIPPING]
Restoring repositories:
- Restoring repository abcd... [DONE]
- Object pool 1 ...
Deleting tmp directories...[DONE]

接下来,如果有必要,恢复 /home/git/gitlab/.secret如前所述

重启极狐GitLab:

sudo service gitlab restart

仅从备份中恢复一个或几个项目或群组

虽然用于恢复极狐GitLab 实例的 Rake 任务不支持恢复单个项目或群组,但您可以通过将备份恢复到一个单独的、临时的极狐GitLab 实例,然后从那里导出您的项目或群组来使用替代方法:

  1. 在与您想要恢复的备份实例相同的版本上安装一个新的极狐GitLab实例。
  2. 将备份恢复到这个新实例,然后导出您的项目群组。有关导出功能的更多信息,请参见导出功能的文档。
  3. 导出完成后,转到旧实例并导入它。
  4. 在完成您想要的项目或群组的导入后,您可以删除新的临时极狐GitLab 实例。

恢复增量仓库备份

每个备份档案都包含一个完整的自包含备份,包括通过增量仓库备份程序创建的备份。要恢复增量仓库备份,请使用与恢复任何其他常规备份档案相同的说明。

恢复选项

极狐GitLab 提供的用于从备份中恢复的命令行工具可以接受更多选项。

当存在多个备份时指定要恢复的备份

备份文件使用以备份 ID开头的命名方案。当存在多个备份时,您必须通过设置环境变量 BACKUP=<backup-id> 来指定要恢复的 <backup-id>_gitlab_backup.tar 文件。

在恢复过程中禁用提示

在从备份中恢复期间,恢复脚本会提示确认:

  • 如果启用了写入到 authorized_keys 设置,则在恢复脚本删除并重建 authorized_keys 文件之前。
  • 当恢复数据库时,在恢复脚本删除所有现有表之前。
  • 在恢复数据库后,如果恢复模式时出现错误,在继续之前,因为进一步的问题可能会发生。

要禁用这些提示,请将 GITLAB_ASSUME_YES 环境变量设置为 1

  • Linux 软件包安装:

    sudo GITLAB_ASSUME_YES=1 gitlab-backup restore
    
  • 自行编译安装:

    sudo -u git -H GITLAB_ASSUME_YES=1 bundle exec rake gitlab:backup:restore RAILS_ENV=production
    

force=yes 环境变量也会禁用这些提示。

在恢复时排除任务

您可以通过添加环境变量 SKIP 来排除恢复时的特定任务,其值是以下选项的逗号分隔列表:

  • db(数据库)
  • uploads(附件)
  • builds(CI 作业输出日志)
  • artifacts(CI 作业产物)
  • lfs(LFS 对象)
  • terraform_state(Terraform 状态)
  • registry(容器注册表镜像)
  • pages(Pages 内容)
  • repositories(Git 仓库数据)
  • packages(软件包)

要排除特定任务:

  • Linux 软件包安装:

    sudo gitlab-backup restore BACKUP=<backup-id> SKIP=db,uploads
    
  • 自行编译安装:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> SKIP=db,uploads RAILS_ENV=production
    

恢复特定的仓库存储

{{< history >}}

  • 在极狐GitLab 15.0 中引入。

{{< /history >}}

{{< alert type=”warning” >}}

极狐GitLab 17.1 及更早版本受到竞争条件影响,可能导致数据丢失。问题影响到已被 fork 并使用极狐GitLab 对象池的仓库。为了避免数据丢失,仅使用极狐GitLab 17.2 或更高版本恢复备份

{{< /alert >}}

使用多个仓库存储时,可以分别使用 REPOSITORIES_STORAGES 选项恢复来自特定仓库存储的仓库。该选项接受存储名称的逗号分隔列表。

例如:

  • Linux 软件包安装:

    sudo gitlab-backup restore BACKUP=<backup-id> REPOSITORIES_STORAGES=storage1,storage2
    
  • 自行编译安装:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> REPOSITORIES_STORAGES=storage1,storage2
    

恢复特定仓库

{{< history >}}

  • 在极狐GitLab 15.1 中引入。

{{< /history >}}

{{< alert type=”warning” >}}

极狐GitLab 17.1 及更早版本受到竞争条件影响,可能导致数据丢失。问题影响到已被 fork 并使用极狐GitLab 对象池的仓库。为了避免数据丢失,仅使用极狐GitLab 17.2 或更高版本恢复备份

{{< /alert >}}

您可以使用 REPOSITORIES_PATHSSKIP_REPOSITORIES_PATHS 选项恢复特定仓库。两个选项都接受项目和群组路径的逗号分隔列表。如果您指定一个群组路径,群组和子群组中的所有项目中的所有仓库都将被包含或跳过,具体取决于您使用的选项。这些群组和项目必须存在于指定的备份中或目标实例上。

{{< alert type=”note” >}}

REPOSITORIES_PATHSSKIP_REPOSITORIES_PATHS 选项仅适用于 Git 仓库。它们不适用于项目或群组数据库条目。如果您创建了一个带有 SKIP=db 的仓库备份,它本身不能用于恢复特定仓库到新实例。

{{< /alert >}}

例如,要恢复 Group Agroup-a)中所有项目的所有仓库、Group BProject Cgroup-b/project-c)的仓库,并跳过 Group A 中的 Project Dgroup-a/project-d):

  • Linux 软件包安装:

    sudo gitlab-backup restore BACKUP=<backup-id> REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
    
  • 自行编译安装:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
    

恢复未打包的备份

如果找到一个未打包的备份(使用 SKIP=tar 制作),并且没有选择备份 BACKUP=<backup-id>,则使用未打包的备份。

例如:

  • Linux 软件包安装:

    sudo gitlab-backup restore
    
  • 自行编译安装:

    sudo -u git -H bundle exec rake gitlab:backup:restore
    

使用服务器端仓库备份恢复

{{< history >}}

  • 在极狐GitLab 16.3 中的 gitlab-backup 中引入。
  • 在极狐GitLab 16.6 中引入的 gitlab-backup 中支持恢复指定备份而非最新备份的服务器端支持。
  • 在极狐GitLab 16.6 中引入的 gitlab-backup 中支持创建增量备份的服务器端支持。
  • 在极狐GitLab 17.0 中引入的 backup-utility 中的服务器端支持。

{{< /history >}}

当收集服务器端备份时,恢复过程默认为使用创建服务器端仓库备份中显示的服务器端恢复机制。您可以配置备份恢复,以便每个仓库所在的 Gitaly 节点负责直接从对象存储中提取必要的备份数据。

  1. 在 Gitaly 中配置服务器端备份目标
  2. 启动服务器端备份恢复过程并指定您希望恢复的备份 ID

{{< tabs >}}

{{< tab title=”Linux package (Omnibus)” >}}

sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

{{< /tab >}}

{{< tab title=”Self-compiled” >}}

sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=11493107454_2018_04_25_10.6.4-ce

{{< /tab >}}

{{< tab title=”Helm chart (Kubernetes)” >}}

kubectl exec <Toolbox pod name> -it -- backup-utility --restore -t <backup_ID> --repositories-server-side

当使用基于 cron 的备份时,添加 --repositories-server-side 标志到额外参数。

{{< /tab >}}

{{< /tabs >}}

故障排除

以下是您可能遇到的问题以及潜在的解决方案。

使用输出警告从 Linux 软件包安装恢复数据库备份

如果您正在使用备份恢复程序,您可能会遇到以下警告消息:

ERROR: must be owner of extension pg_trgm
ERROR: must be owner of extension btree_gist
ERROR: must be owner of extension plpgsql
WARNING:  no privileges could be revoked for "public" (two occurrences)
WARNING:  no privileges were granted for "public" (two occurrences)

请注意,尽管有这些警告消息,备份仍然成功恢复。

Rake 任务以 gitlab 用户身份运行,该用户对数据库没有超级用户访问权限。当恢复启动时,它也以 gitlab 用户身份运行,但也尝试更改它无权访问的对象。这些对象对数据库备份或恢复没有影响,但会显示警告消息。

由于 Git 服务器钩子导致恢复失败

从备份中恢复时,当以下条件为真时,您可能会遇到错误:

  • 使用极狐GitLab 15.10 及更早版本的方法配置了 Git 服务器钩子 (custom_hook)
  • 您的极狐GitLab 版本为 15.11 及更高版本
  • 您创建了指向极狐GitLab 管理位置之外目录的符号链接

错误看起来像这样:

{"level":"fatal","msg":"restore: pipeline: 1 failures encountered:\n - @hashed/path/to/hashed_repository.git (path/to_project): manager: restore custom hooks, \"@hashed/path/to/hashed_repository/<BackupID>_<GitLabVersion>-ee/001.custom_hooks.tar\": rpc error: code = Internal desc = setting custom hooks: generating prepared vote: walking directory: copying file to hash: read /mnt/gitlab-app/git-data/repositories/+gitaly/tmp/default-repositories.old.<timestamp>.<temporaryfolder>/custom_hooks/compliance-triggers.d: is a directory\n","pid":3256017,"time":"2023-08-10T20:09:44.395Z"}

要解决此问题,您可以更新极狐GitLab 版本 15.11 及更高版本的 Git 服务器钩子,并创建一个新的备份。

使用 fapolicyd 时恢复成功但仓库显示为空

当使用 fapolicyd 增强安全性时,极狐GitLab 可能会报告恢复成功但仓库显示为空。有关更多故障排除帮助,请参见Gitaly 故障排除文档