# Back up and restore GitLab

> 原文：[https://docs.gitlab.com/ee/raketasks/backup_restore.html](https://docs.gitlab.com/ee/raketasks/backup_restore.html)

*   [Requirements](#requirements)
*   [Backup timestamp](#backup-timestamp)
*   [Back up GitLab](#back-up-gitlab)
    *   [Storing configuration files](#storing-configuration-files)
    *   [Backup options](#backup-options)
        *   [Backup strategy option](#backup-strategy-option)
        *   [Backup filename](#backup-filename)
        *   [Rsyncable](#rsyncable)
        *   [Excluding specific directories from the backup](#excluding-specific-directories-from-the-backup)
        *   [Skipping tar creation](#skipping-tar-creation)
        *   [Uploading backups to a remote (cloud) storage](#uploading-backups-to-a-remote-cloud-storage)
            *   [Using Amazon S3](#using-amazon-s3)
            *   [Digital Ocean Spaces](#digital-ocean-spaces)
            *   [Other S3 Providers](#other-s3-providers)
            *   [Using Google Cloud Storage](#using-google-cloud-storage)
            *   [Specifying a custom directory for backups](#specifying-a-custom-directory-for-backups)
        *   [Uploading to locally mounted shares](#uploading-to-locally-mounted-shares)
        *   [Backup archive permissions](#backup-archive-permissions)
        *   [Configuring cron to make daily backups](#configuring-cron-to-make-daily-backups)
    *   [Limit backup lifetime for local files (prune old backups)](#limit-backup-lifetime-for-local-files-prune-old-backups)
*   [Restore GitLab](#restore-gitlab)
    *   [Restore prerequisites](#restore-prerequisites)
    *   [Restore for installation from source](#restore-for-installation-from-source)
    *   [Restore for Omnibus GitLab installations](#restore-for-omnibus-gitlab-installations)
    *   [Restore for Docker image and GitLab Helm chart installations](#restore-for-docker-image-and-gitlab-helm-chart-installations)
    *   [Restoring only one or a few project(s) or group(s) from a backup](#restoring-only-one-or-a-few-projects-or-groups-from-a-backup)
*   [Alternative backup strategies](#alternative-backup-strategies)
*   [Additional notes](#additional-notes)
*   [Troubleshooting](#troubleshooting)
    *   [Restoring database backup using Omnibus packages outputs warnings](#restoring-database-backup-using-omnibus-packages-outputs-warnings)
    *   [When the secrets file is lost](#when-the-secrets-file-is-lost)
        *   [Reset CI/CD variables](#reset-cicd-variables)
        *   [Reset Runner registration tokens](#reset-runner-registration-tokens)
        *   [Reset pending pipeline jobs](#reset-pending-pipeline-jobs)
    *   [Container Registry push failures after restoring from a backup](#container-registry-push-failures-after-restoring-from-a-backup)
    *   [Backup fails to complete with Gzip error](#backup-fails-to-complete-with-gzip-error)

# Back up and restore GitLab[](#back-up-and-restore-gitlab-core-only "Permalink")

GitLab 提供了 Rake 任务来备份和还原 GitLab 实例.

应用程序数据备份将创建一个包含数据库，所有存储库和所有附件的存档文件.

您只能将备份还原到与其创建时**完全相同的** GitLab **版本和类型（CE / EE）** . 将存储库从一台服务器迁移到另一台服务器的最佳方法是通过备份还原.

## Requirements[](#requirements "Permalink")

为了能够进行备份和还原，您需要在系统上安装两个基本工具.

*   **Rsync** ：如果您安装了 GitLab：
    *   使用 Omnibus 软件包，您已经准备就绪.
    *   从源代码中，确保已安装`rsync` . 例如：

        ```
         # Debian/Ubuntu sudo apt-get install rsync # RHEL/CentOS sudo yum install rsync 
        ```

## Backup timestamp[](#backup-timestamp "Permalink")

**注意：**在 GitLab 9.2 中，时间戳格式从`EPOCH_YYYY_MM_DD`更改为`EPOCH_YYYY_MM_DD_GitLab_version` ，例如`1493107454_2018_04_25`将变为`1493107454_2018_04_25_10.6.4-ce` .

备份存档将保存在`config/gitlab.yml`文件中指定的`backup_path`中. 文件名将为`[TIMESTAMP]_gitlab_backup.tar` ，其中`TIMESTAMP`标识创建每个备份的时间以及 GitLab 版本. 如果您需要还原 GitLab 并且有多个备份可用，则需要时间戳.

例如，如果备份名称为`1493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar` ，则时间戳为`1493107454_2018_04_25_10.6.4-ce` .

## Back up GitLab[](#back-up-gitlab "Permalink")

GitLab 提供了一个简单的命令行界面来备份整个实例. 它备份您的：

*   Database
*   Attachments
*   Git 存储库数据
*   CI / CD 作业输出日志
*   CI / CD 作业工件
*   LFS 对象
*   容器注册表图像
*   GitLab 页面内容

**警告：** GitLab 不会备份任何配置文件，SSL 证书或系统文件. 强烈建议您[阅读有关存储配置文件的信息](#storing-configuration-files) .

如果您已通过 Omnibus 软件包安装了 GitLab，请使用以下命令：

```
sudo gitlab-backup create 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

如果您已经从源代码安装了 GitLab，请使用以下命令：

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

如果您正在 Docker 容器中运行 GitLab，则可以从主机运行备份：

```
docker exec -t <container name> gitlab-backup create 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

如果您正在 Kubernetes 集群上使用[GitLab Helm 图表](https://gitlab.com/gitlab-org/charts/gitlab) ，则可以通过`kubectl`在 GitLab 任务运行`backup-utility`窗格上使用`backup-utility`脚本运行备份任务. 有关更多详细信息，请参考[备份 GitLab 安装](https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/backup-restore/backup.md#backing-up-a-gitlab-installation) ：

```
kubectl exec -it <gitlab task-runner pod> backup-utility 
```

与 Kubernetes 情况类似，如果已扩展 GitLab 集群以使用多个应用程序服务器，则应选择一个指定节点（不会自动扩展）以运行备份 Rake 任务. 由于备份 Rake 任务与主 Rails 应用程序紧密相连，因此通常在该节点上您还运行 Unicorn / Puma 和/或 Sidekiq.

输出示例：

```
Dumping database tables:
- Dumping table events... [DONE]
- Dumping table issues... [DONE]
- Dumping table keys... [DONE]
- Dumping table merge_requests... [DONE]
- Dumping table milestones... [DONE]
- Dumping table namespaces... [DONE]
- Dumping table notes... [DONE]
- Dumping table projects... [DONE]
- Dumping table protected_branches... [DONE]
- Dumping table schema_migrations... [DONE]
- Dumping table services... [DONE]
- Dumping table snippets... [DONE]
- Dumping table taggings... [DONE]
- Dumping table tags... [DONE]
- Dumping table users... [DONE]
- Dumping table users_projects... [DONE]
- Dumping table web_hooks... [DONE]
- Dumping table wikis... [DONE]
Dumping repositories:
- Dumping repository abcd... [DONE]
Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
Deleting tmp directories...[DONE]
Deleting old backups... [SKIPPING] 
```

### Storing configuration files[](#storing-configuration-files "Permalink")

The [backup Rake task](#back-up-gitlab) GitLab provides does **not** store your configuration files. The primary reason for this is that your database contains encrypted information for two-factor authentication, the CI/CD ‘secure variables’, and so on. Storing encrypted information along with its key in the same place defeats the purpose of using encryption in the first place.

**警告：**机密文件对于保留数据库加密密钥至关重要.

**至少** ，您必须备份：

对所有人;

*   `/etc/gitlab/gitlab-secrets.json`
*   `/etc/gitlab/gitlab.rb`

从源安装：

*   `/home/git/gitlab/config/secrets.yml`
*   `/home/git/gitlab/config/gitlab.yml`

For [Docker installations](https://docs.gitlab.com/omnibus/docker/), you must back up the volume where the configuration files are stored. If you have created the GitLab container according to the documentation, it should be under `/srv/gitlab/config`.

对于 Kubernetes 集群上的[GitLab Helm 图表安装](https://gitlab.com/gitlab-org/charts/gitlab) ，必须遵循[备份机密](https://docs.gitlab.com/charts/backup-restore/backup.html)说明.

您可能还想备份所有 TLS 密钥和证书以及[SSH 主机密钥](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079) .

如果您使用 Omnibus GitLab，请参阅一些其他信息[来备份您的配置](https://docs.gitlab.com/omnibus/settings/backups.html) .

万一机密文件丢失，请参阅[故障排除部分](#when-the-secrets-file-is-lost) .

### Backup options[](#backup-options "Permalink")

GitLab 提供的用于备份实例的命令行工具可以使用更多选项.

#### Backup strategy option[](#backup-strategy-option "Permalink")

在 GitLab 8.17 中[引入](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8728) .

默认的备份策略实际上是使用 Linux 命令`tar`和`gzip`将数据从相应的数据位置流式传输到备份. 在大多数情况下，这可以正常工作，但是在数据快速变化时可能会引起问题.

当`tar`读取数据时更改数据时，错误`file changed as we read it`可能会`file changed as we read it`发生`file changed as we read it`将导致备份过程失败. 为了解决这个问题，8.17 引入了一种名为`copy`的新备份策略. 该策略在调用`tar`和`gzip`之前将数据文件复制到一个临时位置，从而避免了错误.

副作用是备份过程将占用额外的 1X 磁盘空间. 该过程尽力在每个阶段清理临时文件，这样问题就不会复杂化，但是对于大型安装而言，这可能是一个相当大的变化. 这就是为什么`copy`策略不是 8.17 中的默认策略的原因.

要使用`copy`策略而不是默认的流策略，请在 Rake task 命令中指定`STRATEGY=copy` . 例如：

```
sudo gitlab-backup create STRATEGY=copy 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

#### Backup filename[](#backup-filename "Permalink")

**警告：**如果使用自定义备份文件名，则将无法[限制备份的寿命](#limit-backup-lifetime-for-local-files-prune-old-backups) .

默认情况下，将根据上面["备份时间戳记"](#backup-timestamp)部分中的规范创建一个备份文件. 但是，可以通过设置`BACKUP`环境变量来覆盖文件名的`[TIMESTAMP]`部分. 例如：

```
sudo gitlab-backup create BACKUP=dump 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

生成的文件将是`dump_gitlab_backup.tar` . 这对于使用 rsync 和增量备份的系统很有用，并且将导致更快的传输速度.

#### Rsyncable[](#rsyncable "Permalink")

为了确保生成的归档文件可以通过 rsync 智能传输，可以设置`GZIP_RSYNCABLE=yes`选项. 这会将`--rsyncable`选项设置为`gzip` . 这仅在与设置["备份文件名"选项](#backup-filename)结合使用时才有用.

注意，不能保证`gzip`中的`--rsyncable`选项在所有发行版中都可用. 要验证它在您的发行版中是否可用，您可以运行`gzip --help`或查阅手册页.

```
sudo gitlab-backup create BACKUP=dump GZIP_RSYNCABLE=yes 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

#### Excluding specific directories from the backup[](#excluding-specific-directories-from-the-backup "Permalink")

您可以通过添加环境变量`SKIP`选择从备份中免除的内容. 可用的选项有：

*   `db` (database)
*   `uploads` (attachments)
*   `repositories` （Git 仓库数据）
*   `builds` （CI 作业输出日志）
*   `artifacts` （CI 作业工件）
*   `lfs` （LFS 对象）
*   `registry` （容器注册表图像）
*   `pages` （页面内容）

使用逗号同时指定多个选项：

所有 Wiki 将作为`repositories`组的一部分进行备份. 备份期间将跳过不存在的 Wiki.

对于 Omnibus GitLab 软件包：

```
sudo gitlab-backup create SKIP=db,uploads 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

对于源安装：

```
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=db,uploads RAILS_ENV=production 
```

#### Skipping tar creation[](#skipping-tar-creation "Permalink")

创建备份的最后一部分是生成包含所有部分的`.tar`文件. 在某些情况下（例如，如果备份是由其他备份软件获取的），创建`.tar`文件可能会浪费精力，甚至直接有害，因此可以通过将`tar`添加到`SKIP`环境变量中来跳过此步骤.

将`tar`添加到`SKIP`变量`SKIP`包含备份的文件和目录保留在用于中间文件的目录中. 创建新备份时，这些文件将被覆盖，因此您应确保将它们复制到其他位置，因为系统上只能有一个备份.

对于 Omnibus GitLab 软件包：

```
sudo gitlab-backup create SKIP=tar 
```

对于源安装：

```
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=tar RAILS_ENV=production 
```

#### Uploading backups to a remote (cloud) storage[](#uploading-backups-to-a-remote-cloud-storage "Permalink")

从 GitLab 7.4 开始，您可以让备份脚本上载它创建的`.tar`文件. 它使用[Fog 库](http://fog.io/)执行上传. 在下面的示例中，我们使用 Amazon S3 进行存储，但是 Fog 还允许您使用[其他存储提供商](http://fog.io/storage/) . GitLab 也为 AWS，Google，OpenStack Swift，Rackspace 和 Aliyun [导入了云驱动程序](https://gitlab.com/gitlab-org/gitlab/blob/30f5b9a5b711b46f1065baf755e413ceced5646b/Gemfile#L88) . [也可以使用](#uploading-to-locally-mounted-shares)本地驱动程序.

[Read more about using object storage with GitLab](../administration/object_storage.html).

##### Using Amazon S3[](#using-amazon-s3 "Permalink")

对于 Omnibus GitLab 软件包：

1.  将以下内容添加到`/etc/gitlab/gitlab.rb` ：

    ```
    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'AWS',
      'region' => 'eu-west-1',
      'aws_access_key_id' => 'AKIAKIAKI',
      'aws_secret_access_key' => 'secret123'
      # If using an IAM Profile, don't configure aws_access_key_id & aws_secret_access_key
      # 'use_iam_profile' => true
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket' 
    ```

2.  [Reconfigure GitLab](../administration/restart_gitlab.html#omnibus-gitlab-reconfigure) for the changes to take effect

##### Digital Ocean Spaces[](#digital-ocean-spaces "Permalink")

该示例可用于阿姆斯特丹（AMS3）中的存储桶.

1.  将以下内容添加到`/etc/gitlab/gitlab.rb` ：

    ```
    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'AWS',
      'region' => 'ams3',
      'aws_access_key_id' => 'AKIAKIAKI',
      'aws_secret_access_key' => 'secret123',
      'endpoint'              => 'https://ams3.digitaloceanspaces.com'
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket' 
    ```

2.  [重新配置 GitLab](../administration/restart_gitlab.html#omnibus-gitlab-reconfigure)以使更改生效

**注意：**如果通过使用 Digital Ocean Spaces 看到`400 Bad Request` ，则可能是由于使用了备份加密. 由于 Digital Ocean Spaces 不支持加密，因此删除或注释包含`gitlab_rails['backup_encryption']`的行.

##### Other S3 Providers[](#other-s3-providers "Permalink")

并非所有 S3 提供程序都与 Fog 库完全兼容. 例如，如果尝试上传后看到`411 Length Required`错误， `aws_signature_version` [于此问题](https://github.com/fog/fog-aws/issues/428) ，您可能需要将`aws_signature_version`值从默认值降级为 2.

对于源安装：

1.  Edit `home/git/gitlab/config/gitlab.yml`:

    ```
     backup:
        # snip
        upload:
          # Fog storage connection settings, see http://fog.io/storage/ .
          connection:
            provider: AWS
            region: eu-west-1
            aws_access_key_id: AKIAKIAKI
            aws_secret_access_key: 'secret123'
            # If using an IAM Profile, leave aws_access_key_id & aws_secret_access_key empty
            # ie. aws_access_key_id: ''
            # use_iam_profile: 'true'
          # The remote 'directory' to store your backups. For S3, this would be the bucket name.
          remote_directory: 'my.s3.bucket'
          # Turns on AWS Server-Side Encryption with Amazon S3-Managed Keys for backups, this is optional
          # encryption: 'AES256'
          # Turns on AWS Server-Side Encryption with Amazon Customer-Provided Encryption Keys for backups, this is optional
          #   This should be set to the encryption key for Amazon S3 to use to encrypt or decrypt your data.
          #   'encryption' must also be set in order for this to have any effect.
          #   To avoid storing the key on disk, the key can also be specified via the `GITLAB_BACKUP_ENCRYPTION_KEY` environment variable.
          # encryption_key: '<key>'
          # Specifies Amazon S3 storage class to use for backups, this is optional
          # storage_class: 'STANDARD' 
    ```

2.  [重新启动 GitLab](../administration/restart_gitlab.html#installations-from-source)以使更改生效

如果要将备份上传到 S3，则可能需要创建具有受限访问权限的新 IAM 用户. 要使上载用户仅能上载备份，请创建以下 IAM 配置文件，将`my.s3.bucket`替换为存储桶的名称：

```
{  "Version":  "2012-10-17",  "Statement":  [  {  "Sid":  "Stmt1412062044000",  "Effect":  "Allow",  "Action":  [  "s3:AbortMultipartUpload",  "s3:GetBucketAcl",  "s3:GetBucketLocation",  "s3:GetObject",  "s3:GetObjectAcl",  "s3:ListBucketMultipartUploads",  "s3:PutObject",  "s3:PutObjectAcl"  ],  "Resource":  [  "arn:aws:s3:::my.s3.bucket/*"  ]  },  {  "Sid":  "Stmt1412062097000",  "Effect":  "Allow",  "Action":  [  "s3:GetBucketLocation",  "s3:ListAllMyBuckets"  ],  "Resource":  [  "*"  ]  },  {  "Sid":  "Stmt1412062128000",  "Effect":  "Allow",  "Action":  [  "s3:ListBucket"  ],  "Resource":  [  "arn:aws:s3:::my.s3.bucket"  ]  }  ]  } 
```

##### Using Google Cloud Storage[](#using-google-cloud-storage "Permalink")

如果要使用 Google Cloud Storage 保存备份，则必须首先从 Google 控制台创建访问密钥：

1.  转到存储设置页面[https://console.cloud.google.com/storage/settings](https://console.cloud.google.com/storage/settings)
2.  选择"互操作性"并创建访问密钥
3.  记下"访问密钥"和"秘密"并将其替换为以下配置
4.  在存储桶高级设置中，确保选择了访问控制选项"设置对象级别和存储桶级别权限"
5.  确保您已经创建了存储桶

对于 Omnibus GitLab 软件包：

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'Google',
      'google_storage_access_key_id' => 'Access Key',
      'google_storage_secret_access_key' => 'Secret',

      ## If you have CNAME buckets (foo.example.com), you might run into SSL issues
      ## when uploading backups ("hostname foo.example.com.storage.googleapis.com
      ## does not match the server certificate"). In that case, uncomnent the following
      ## setting. See: https://github.com/fog/fog/issues/2834
      #'path_style' => true
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.google.bucket' 
    ```

2.  [重新配置 GitLab](../administration/restart_gitlab.html#omnibus-gitlab-reconfigure)以使更改生效

对于源安装：

1.  Edit `home/git/gitlab/config/gitlab.yml`:

    ```
     backup:
        upload:
          connection:
            provider: 'Google'
            google_storage_access_key_id: 'Access  Key'
            google_storage_secret_access_key: 'Secret'
          remote_directory: 'my.google.bucket' 
    ```

2.  [重新启动 GitLab](../administration/restart_gitlab.html#installations-from-source)以使更改生效

##### Specifying a custom directory for backups[](#specifying-a-custom-directory-for-backups "Permalink")

Note: This option only works for remote storage. If you want to group your backups you can pass a `DIRECTORY` environment variable:

```
sudo gitlab-backup create DIRECTORY=daily
sudo gitlab-backup create DIRECTORY=weekly 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

#### Uploading to locally mounted shares[](#uploading-to-locally-mounted-shares "Permalink")

You may also send backups to a mounted share (for example, `NFS`,`CIFS`, or `SMB`) by using the Fog [`Local`](https://github.com/fog/fog-local#usage) storage provider. The directory pointed to by the `local_root` key **must** be owned by the `git` user **安装时** (mounting with the `uid=` of the `git` user for `CIFS` and `SMB`) or the user that you are executing the backup tasks under (for Omnibus packages, this is the `git` user).

除`local_root`密钥外， `backup_upload_remote_directory` **必须**设置`local_root` . 这是已安装目录中的子目录，备份将被复制到该子目录，如果不存在，则会创建备份. 如果要将压缩文件复制到的目录是已安装目录的根目录，请使用`.` 代替.

**注意：**由于文件系统性能可能会影响 GitLab 的整体性能，因此我们不建议使用 EFS 进行存储. [有关](../administration/high_availability/nfs.html#avoid-using-awss-elastic-file-system-efs)更多详细信息，请参见[相关文档](../administration/high_availability/nfs.html#avoid-using-awss-elastic-file-system-efs) .

对于 Omnibus GitLab 软件包：

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    gitlab_rails['backup_upload_connection'] = {
      :provider => 'Local',
      :local_root => '/mnt/backups'
    }

    # The directory inside the mounted folder to copy backups to
    # Use '.' to store them in the root directory
    gitlab_rails['backup_upload_remote_directory'] = 'gitlab_backups' 
    ```

2.  [重新配置 GitLab，](../administration/restart_gitlab.html#omnibus-gitlab-reconfigure)以使更改生效.

对于源安装：

1.  Edit `home/git/gitlab/config/gitlab.yml`:

    ```
    backup:
      upload:
        # Fog storage connection settings, see http://fog.io/storage/ .
        connection:
          provider: Local
          local_root: '/mnt/backups'
        # The directory inside the mounted folder to copy backups to
        # Use '.' to store them in the root directory
        remote_directory: 'gitlab_backups' 
    ```

2.  [重新启动 GitLab，](../administration/restart_gitlab.html#installations-from-source)以使更改生效.

#### Backup archive permissions[](#backup-archive-permissions "Permalink")

由 GitLab 创建的备份存档（ `1393513186_2014_02_27_gitlab_backup.tar` ）默认情况下将具有所有者/组`git` / `git`和 0600 权限. 这是为了避免其他系统用户读取 GitLab 的数据. 如果您需要备份存档具有不同的权限，则可以使用" archive_permissions"设置.

对于 Omnibus GitLab 软件包：

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    gitlab_rails['backup_archive_permissions'] = 0644 # Makes the backup archives world-readable 
    ```

2.  [重新配置 GitLab，](../administration/restart_gitlab.html#omnibus-gitlab-reconfigure)以使更改生效.

对于源安装：

1.  Edit `/home/git/gitlab/config/gitlab.yml`:

    ```
    backup:
      archive_permissions: 0644 # Makes the backup archives world-readable 
    ```

2.  [重新启动 GitLab，](../administration/restart_gitlab.html#installations-from-source)以使更改生效.

#### Configuring cron to make daily backups[](#configuring-cron-to-make-daily-backups "Permalink")

**警告：**以下 cron 作业不会[备份您的 GitLab 配置文件](#storing-configuration-files)或[SSH 主机密钥](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079) .

您可以安排一个 cron 作业来备份您的存储库和 GitLab 元数据.

对于 Omnibus GitLab 软件包：

1.  编辑`root`用户的 crontab：

    ```
    sudo su -
    crontab -e 
    ```

2.  在那里，添加以下行以安排每天凌晨 2 点进行备份：

    ```
    0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1 
    ```

    **注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:create` .

对于源安装：

1.  编辑`git`用户的 crontab：

    ```
    sudo -u git crontab -e 
    ```

2.  在底部添加以下行：

    ```
    # Create a full backup of the GitLab repositories and SQL database every day at 2am
    0 2 * * * cd /home/git/gitlab && PATH=/usr/local/bin:/usr/bin:/bin bundle exec rake gitlab:backup:create RAILS_ENV=production CRON=1 
    ```

**注意：**如果没有错误， `CRON=1`环境设置将告诉备份脚本禁止所有进度输出. 建议减少 Cron 垃圾邮件.

### Limit backup lifetime for local files (prune old backups)[](#limit-backup-lifetime-for-local-files-prune-old-backups "Permalink")

**警告：**如果您使用[自定义文件名](#backup-filename)进行备份，则此操作将无效.**注意：**此配置选项仅管理本地文件. GitLab 不会自动修剪存储在第三方[对象](#uploading-backups-to-a-remote-cloud-storage)存储中的旧文件，因为用户可能没有列出和删除文件的权限. 建议您为对象存储配置适当的保留策略（例如[AWS S3](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html) ）.

您可能希望为备份设置有限的生命周期，以防止使用所有磁盘空间进行常规备份. 下次运行备份任务时，将修剪早于`backup_keep_time`备份.

对于 Omnibus GitLab 软件包：

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    ## Limit backup lifetime to 7 days - 604800 seconds
    gitlab_rails['backup_keep_time'] = 604800 
    ```

2.  [重新配置 GitLab，](../administration/restart_gitlab.html#omnibus-gitlab-reconfigure)以使更改生效.

对于源安装：

1.  Edit `/home/git/gitlab/config/gitlab.yml`:

    ```
    backup:
      ## Limit backup lifetime to 7 days - 604800 seconds
      keep_time: 604800 
    ```

2.  [重新启动 GitLab，](../administration/restart_gitlab.html#installations-from-source)以使更改生效.

## Restore GitLab[](#restore-gitlab "Permalink")

GitLab 提供了一个简单的命令行界面来还原整个安装过程，并且足够灵活，可以满足您的需求.

[还原先决条件部分](#restore-prerequisites)包括关键信息. 在尝试在生产环境中执行还原过程之前，请确保至少阅读并测试整个还原过程一次.

您只能将备份还原到**与**您在其上创建备份的 GitLab **版本和类型（CE / EE）完全相同的**备份，例如 CE 9.1.0.

如果备份的版本与当前安装的版本不同，则在还原备份之前，您需要[降级 GitLab 安装](https://docs.gitlab.com/omnibus/update/README.html) .

### Restore prerequisites[](#restore-prerequisites "Permalink")

您需要先进行有效的 GitLab 安装，然后才能执行还原. 这主要是因为通常不允许执行还原操作（ `git` ）的系统用户创建或删除将数据导入到（ `gitlabhq_production` ）所需的 SQL 数据库. 所有现有数据将被擦除（SQL）或移动到单独的目录（存储库，上载）.

要还原备份，您还需要还原`/etc/gitlab/gitlab-secrets.json` （对于 Omnibus 软件包）或`/home/git/gitlab/.secret` （对于从源安装）. 该文件包含数据库加密密钥， [CI / CD 变量](../ci/variables/README.html#gitlab-cicd-environment-variables)以及用于[两因素身份验证的](../user/profile/account/two_factor_authentication.html)变量. 如果您无法通过应用程序数据备份还原此加密密钥文件，则启用了双重身份验证和 GitLab Runners 的用户将无法访问您的 GitLab 服务器.

您可能还想还原所有 TLS 密钥，证书或[SSH 主机密钥](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079) .

从 GitLab 12.9 开始，如果找到了未取消备份（如使用`SKIP=tar`备份），并且未使用`BACKUP=<timestamp>`选择任何备份，则将使用未取消备份.

根据您的情况，您可能需要使用以下一个或多个选项来运行 restore 命令：

*   `BACKUP=timestamp_of_backup`如果存在多个备份，则为必需. 阅读有关[备份时间戳记的内容](#backup-timestamp) .
*   `force=yes` yes-不询问是否应重新生成 authorized_keys 文件，并假设" yes"以警告将删除数据库表，启用"写入 authorized_keys 文件"设置并更新 LDAP 提供程序.

如果要还原到作为挂载点的目录，则在尝试还原之前，需要确保这些目录为空. 否则，GitLab 将在恢复新数据之前尝试移动这些目录，这将导致错误.

阅读有关[配置 NFS 挂载的](../administration/high_availability/nfs.html)更多信息

### Restore for installation from source[](#restore-for-installation-from-source "Permalink")

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

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 
```

### Restore for Omnibus GitLab installations[](#restore-for-omnibus-gitlab-installations "Permalink")

此过程假定：

*   您已经安装了与创建备份**完全相同**的 GitLab Omnibus **版本和类型（CE / EE）** .
*   您已经至少运行过`sudo gitlab-ctl reconfigure`一次.
*   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 unicorn
sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
# Verify
sudo gitlab-ctl status 
```

接下来，还原备份，并指定要还原的备份的时间戳记：

```
# This command will overwrite the contents of your GitLab database!
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:restore` .**警告：** `gitlab-rake gitlab:backup:restore`没有在您的注册表目录上设置正确的文件系统权限. 这是一个[已知问题](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62759) . 在 GitLab 12.2 或更高版本上，您可以使用`gitlab-backup restore`来避免此问题.

接下来，根据需要如上所述恢复`/etc/gitlab/gitlab-secrets.json` .

重新配置，重启并检查 GitLab：

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

如果您的备份 tar 文件和已安装的 GitLab 版本之间的 GitLab 版本不匹配，则 restore 命令将中止并显示错误. 安装[正确的 GitLab 版本，](https://packages.gitlab.com/gitlab/)然后重试.

**注意**当前存在一个与`pgbouncer`不兼容的还原[问题](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3470) . 为了解决该问题，Rails 节点将需要绕过`pgbouncer`并直接连接到主数据库节点. 这可以通过设置`gitlab_rails['db_host']`和`gitlab_rails['port']`连接到主数据库节点并[重新配置 GitLab 来完成](../administration/restart_gitlab.html#omnibus-gitlab-reconfigure) .

### Restore for Docker image and GitLab Helm chart installations[](#restore-for-docker-image-and-gitlab-helm-chart-installations "Permalink")

对于使用 Kubernetes 集群上的 Docker 映像或 GitLab Helm 图表进行的 GitLab 安装，还原任务期望还原目录为空. 但是，使用 Docker 和 Kubernetes 卷挂载，可能会在卷根目录上创建一些系统级目录，例如 Linux 操作系统中找到的`lost+found`目录. 这些目录通常归`root`拥有，因为 restore Rake 任务以`git`用户身份运行，因此可能导致访问权限错误. 因此，要还原 GitLab 安装，用户必须确认还原目标目录为空.

对于这两种安装类型，备份 tarball 必须在备份位置（默认位置为`/var/opt/gitlab/backups` ）中`/var/opt/gitlab/backups` .

对于 Docker 安装，可以从主机运行还原任务：

```
docker exec -it <name of container> gitlab-backup restore 
```

**注意**对于 GitLab 12.1 和更早版本，请使用`gitlab-rake gitlab:backup:restore` .**警告：** `gitlab-rake gitlab:backup:restore`没有在您的注册表目录上设置正确的文件系统权限. 这是一个[已知问题](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62759) . 在 GitLab 12.2 或更高版本上，您可以使用`gitlab-backup restore`来避免此问题.

GitLab Helm 图表使用不同的过程，在[恢复 GitLab Helm 图表安装中](https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/backup-restore/restore.md)记录了该过程.

### Restoring only one or a few project(s) or group(s) from a backup[](#restoring-only-one-or-a-few-projects-or-groups-from-a-backup "Permalink")

尽管用于还原 GitLab 实例的 Rake 任务不支持还原单个项目或组，但是您可以使用一种解决方法，将备份还原到单独的临时 GitLab 实例，然后从那里导出您的项目或组：

1.  以与要还原的备份实例相同的版本[安装新的 GitLab](../install/README.html)实例.
2.  [将备份还原](#restore-gitlab)到此新实例中，然后导出您的[项目](../user/project/settings/import_export.html)或[组](../user/group/settings/import_export.html) . 确保阅读任一导出功能文档上的**重要说明** ，以了解将导出什么内容，不导出什么内容.
3.  导出完成后，转到旧实例并导入它.
4.  仅在完成所需的项目或组的导入后，您可以删除新的临时 GitLab 实例.

**注意**在[问题＃17517 中](https://gitlab.com/gitlab-org/gitlab/-/issues/17517)讨论了提供直接还原单个项目或组的功能请求.

## Alternative backup strategies[](#alternative-backup-strategies "Permalink")

如果您的 GitLab 服务器包含很多 Git 存储库数据，您可能会发现 GitLab 备份脚本太慢. 在这种情况下，您可以考虑将文件系统快照用作备份策略的一部分.

示例：Amazon EBS

> A GitLab server using Omnibus GitLab hosted on Amazon AWS. An EBS drive containing an ext4 filesystem is mounted at `/var/opt/gitlab`. In this case you could make an application backup by taking an EBS snapshot. The backup includes all repositories, uploads and PostgreSQL data.

示例：LVM 快照+ rsync

> 使用 Omnibus GitLab 的 GitLab 服务器，其 LVM 逻辑卷安装在`/var/opt/gitlab` . 使用 rsync 复制`/var/opt/gitlab`目录将不可靠，因为运行 rsync 时会更改太多文件. 而不是 rsync-ing `/var/opt/gitlab` ，我们创建一个临时 LVM 快照，将其作为只读文件系统安装在`/mnt/gitlab_backup` . 现在，我们可以运行更长的 rsync 作业，它将在远程服务器上创建一致的副本. 副本包括所有存储库，上载和 PostgreSQL 数据.

如果您在虚拟服务器上运行 GitLab，则还可以创建整个 GitLab 服务器的 VM 快照. 但是，VM 快照要求您关闭服务器电源的情况并不少见，因此这种方法的实际使用可能受到限制.

## Additional notes[](#additional-notes "Permalink")

本文档适用于 GitLab 社区和企业版. 我们备份 GitLab.com 并确保您的数据安全，但是您不能使用这些方法自己从 GitLab.com 导出/备份数据.

问题存储在数据库中. 它们不能存储在 Git 本身中.

要使用最新版本的 GitLab 将存储库从一台服务器迁移到另一台服务器，可以使用[import Rake 任务](import.html)来批量导入存储库. 请注意，如果您执行导入 Rake 任务而不是备份还原，则将拥有所有存储库，但没有其他任何数据.

## Troubleshooting[](#troubleshooting "Permalink")

以下是可能的解决方案可能遇到的问题.

### Restoring database backup using Omnibus packages outputs warnings[](#restoring-database-backup-using-omnibus-packages-outputs-warnings "Permalink")

如果使用备份还原过程，则可能会遇到以下警告：

```
psql:/var/opt/gitlab/backups/db/database.sql:22: ERROR:  must be owner of extension plpgsql
psql:/var/opt/gitlab/backups/db/database.sql:2931: WARNING:  no privileges could be revoked for "public" (two occurrences)
psql:/var/opt/gitlab/backups/db/database.sql:2933: WARNING:  no privileges were granted for "public" (two occurrences) 
```

请注意，尽管有这些警告，备份仍成功还原.

Rake 任务以`gitlab`用户身份运行，该用户没有对数据库的超级用户访问权限. 启动还原时，它还将以`gitlab`用户身份运行，但也会尝试更改其无权访问的对象. 这些对象对数据库的备份/还原没有影响，但是它们发出此烦人的警告.

有关更多信息，请参见[此处](https://s0www0postgresql0org.icopy.site/message-id/201110220712.30886.adrian.klaver@gmail.com)和[此处](https://s0www0postgresql0org.icopy.site/message-id/2039.1177339749@sss.pgh.pa.us)有关 PostgreSQL 问题跟踪器的类似问题以及[堆栈溢出](https://stackoverflow.com/questions/4368789/error-must-be-owner-of-language-plpgsql) .

### When the secrets file is lost[](#when-the-secrets-file-is-lost "Permalink")

如果您无法[备份 secrets 文件](#storing-configuration-files) ，则启用 2FA 的用户将无法登录 GitLab. 在这种情况下，您需要[为所有人禁用 2FA](../security/two_factor_authentication.html#disabling-2fa-for-everyone) .

机密文件还负责为包含敏感信息的几列存储加密密钥. 如果密钥丢失，GitLab 将无法解密这些列. 这将破坏广泛的功能，包括（但不限于）：

*   [CI/CD variables](../ci/variables/README.html)
*   [Kubernetes / GCP integration](../user/project/clusters/index.html)
*   [Custom Pages domains](../user/project/pages/custom_domains_ssl_tls_certification/index.html)
*   [Project error tracking](../user/project/operations/error_tracking.html)
*   [Runner authentication](../ci/runners/README.html)
*   [Project mirroring](../user/project/repository/repository_mirroring.html)
*   [Web hooks](../user/project/integrations/webhooks.html)

在 CI / CD 变量和 Runner 身份验证之类的情况下，您可能会遇到一些意外行为，例如：

*   卡住了工作.
*   500 个错误.

您可以使用[Secrets Doctor Rake 任务](../administration/raketasks/doctor.html)检查数据库中是否具有不可解密的值.

在这种情况下，您需要重置 CI / CD 变量和运行程序身份验证的所有令牌，下面将对此进行详细说明. 重置令牌后，您应该能够访问您的项目，并且作业将重新开始运行.

**警告：**使用以下命令需要您自担风险，并确保事先进行了备份.

#### Reset CI/CD variables[](#reset-cicd-variables "Permalink")

1.  输入数据库控制台：

    对于 Omnibus GitLab 软件包：

    ```
    sudo gitlab-rails dbconsole 
    ```

    对于源安装：

    ```
    sudo -u git -H bundle exec rails dbconsole -e production 
    ```

2.  检查`ci_group_variables`和`ci_variables`表：

    ```
    SELECT * FROM public."ci_group_variables";
    SELECT * FROM public."ci_variables"; 
    ```

    这些是您需要删除的变量.

3.  放下桌子：

    ```
    DELETE FROM ci_group_variables;
    DELETE FROM ci_variables; 
    ```

4.  您可能需要重新配置或重新启动 GitLab 才能使更改生效.

#### Reset Runner registration tokens[](#reset-runner-registration-tokens "Permalink")

1.  输入数据库控制台：

    对于 Omnibus GitLab 软件包：

    ```
    sudo gitlab-rails dbconsole 
    ```

    对于源安装：

    ```
    sudo -u git -H bundle exec rails dbconsole -e production 
    ```

2.  清除项目，组和整个实例的所有令牌：

    **Caution:** The last UPDATE operation will stop the runners being able to pick up new jobs. You must register new runners.

    ```
    -- Clear project tokens
    UPDATE projects SET runners_token = null, runners_token_encrypted = null;
    -- Clear group tokens
    UPDATE namespaces SET runners_token = null, runners_token_encrypted = null;
    -- Clear instance tokens
    UPDATE application_settings SET runners_registration_token_encrypted = null;
    -- Clear runner tokens
    UPDATE ci_runners SET token = null, token_encrypted = null; 
    ```

#### Reset pending pipeline jobs[](#reset-pending-pipeline-jobs "Permalink")

1.  输入数据库控制台：

    对于 Omnibus GitLab 软件包：

    ```
    sudo gitlab-rails dbconsole 
    ```

    对于源安装：

    ```
    sudo -u git -H bundle exec rails dbconsole -e production 
    ```

2.  清除所有待处理作业的令牌：

    ```
    -- Clear build tokens
    UPDATE ci_builds SET token = null, token_encrypted = null; 
    ```

其余功能也可以采用类似的策略-通过删除无法解密的数据，GitLab 可以恢复工作状态，并且可以手动替换丢失的数据.

### Container Registry push failures after restoring from a backup[](#container-registry-push-failures-after-restoring-from-a-backup "Permalink")

如果使用[Container Registry](../user/packages/container_registry/index.html) ，则在还原注册表数据后，在 Omnibus GitLab 实例上还原备份后，可能会推送到注册表失败.

这些失败将在注册表日志中提及权限问题，例如：

```
level=error
msg="response completed with error"
err.code=unknown
err.detail="filesystem: mkdir /var/opt/gitlab/gitlab-rails/shared/registry/docker/registry/v2/repositories/...: permission denied"
err.message="unknown error" 
```

这是由于还原以非特权用户`git`身份运行的，该用户在还原期间无法将正确的所有权分配给注册表文件（ [问题 62759](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62759 "还原后对注册表文件系统的权限不正确") ）.

要使您的注册表再次起作用：

```
sudo chown -R registry:registry /var/opt/gitlab/gitlab-rails/shared/registry/docker 
```

**注意：**如果您更改了注册表的默认文件系统位置，则需要对定制位置而不是`/var/opt/gitlab/gitlab-rails/shared/registry/docker`运行`chown` .

### Backup fails to complete with Gzip error[](#backup-fails-to-complete-with-gzip-error "Permalink")

运行备份时，您可能会收到 Gzip 错误：

```
sudo /opt/gitlab/bin/gitlab-backup create
...
Dumping ...
...
gzip: stdout: Input/output error

Backup failed 
```

如果发生这种情况，请检查以下内容：

1.  确认有足够的磁盘空间用于 Gzip 操作.
2.  如果正在使用 NFS，请检查是否设置了安装选项`timeout` . 默认值为`600` ，并将其更改为较小的值会导致此错误.