Help us learn about your current experience with the documentation. Take the survey.

合并请求差异存储

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab Self-Managed

合并请求差异是关联到合并请求的差异副本,其大小有限制。当查看合并请求时,为优化性能,系统会优先从这些副本中读取差异。

默认情况下,GitLab 将合并请求差异存储在数据库的 merge_request_diff_files 表中。对于规模较大的安装,此表可能会变得过大,此时您应该切换到外部存储。

合并请求差异可以存储在:

使用外部存储

  1. 编辑 /etc/gitlab/gitlab.rb 文件并添加以下行:

    gitlab_rails['external_diffs_enabled'] = true
  2. 外部差异默认存储在 /var/opt/gitlab/gitlab-rails/shared/external-diffs 目录中。如需更改路径,例如更改为 /mnt/storage/external-diffs,请编辑 /etc/gitlab/gitlab.rb 文件并添加以下行:

    gitlab_rails['external_diffs_storage_path'] = "/mnt/storage/external-diffs"
  3. 保存文件并重新配置 GitLab 以使更改生效。 随后,GitLab 会将您现有的合并请求差异迁移到外部存储。

  1. 编辑 /home/git/gitlab/config/gitlab.yml 文件,添加或修改以下行:

    external_diffs:
      enabled: true
  2. 外部差异默认存储在 /home/git/gitlab/shared/external-diffs 目录中。如需更改路径,例如更改为 /mnt/storage/external-diffs,请编辑 /home/git/gitlab/config/gitlab.yml 文件并添加或修改以下行:

    external_diffs:
      enabled: true
      storage_path: /mnt/storage/external-diffs
  3. 保存文件并重启 GitLab 以使更改生效。 随后,GitLab 会将您现有的合并请求差异迁移到外部存储。

使用对象存储

迁移到对象存储的操作不可逆。

我们建议使用对象存储(如 AWS S3)来替代将外部差异存储在磁盘上。此配置依赖于已预先配置的有效 AWS 凭据。

  1. 编辑 /etc/gitlab/gitlab.rb 文件并添加以下行:

    gitlab_rails['external_diffs_enabled'] = true
  2. 设置对象存储配置

  3. 保存文件并重新配置 GitLab 以使更改生效。 随后,GitLab 会将您现有的合并请求差异迁移到外部存储。

  1. 编辑 /home/git/gitlab/config/gitlab.yml 文件,添加或修改以下行:

    external_diffs:
      enabled: true
  2. 设置对象存储配置

  3. 保存文件并重启 GitLab 以使更改生效。 随后,GitLab 会将您现有的合并请求差异迁移到外部存储。

阅读更多关于在 GitLab 中使用对象存储的信息

对象存储配置

您应该使用统一的对象存储配置

替代方案:数据库内存储

启用外部差异可能会降低合并请求的性能,因为差异必须通过与其他数据分离的操作来获取。一种折中方案是:仅将过时的差异存储在外部,而将当前差异保留在数据库中。

要启用此功能,请执行以下步骤:

  1. 编辑 /etc/gitlab/gitlab.rb 文件并添加以下行:

    gitlab_rails['external_diffs_when'] = 'outdated'
  2. 保存文件并重新配置 GitLab 以使更改生效。

  1. 编辑 /home/git/gitlab/config/gitlab.yml 文件,添加或修改以下行:

    external_diffs:
      enabled: true
      when: outdated
  2. 保存文件并重启 GitLab 以使更改生效。

启用此功能后,差异最初会存储在数据库中,而不是外部存储。当满足以下任一条件时,它们将被移动到外部存储:

  • 存在更新版本的合并请求差异
  • 合并请求已合并超过七天
  • 合并请求已关闭超过七天

这些规则通过仅将频繁访问的差异存储在数据库中,从而在空间和性能之间取得了平衡。那些不太可能被访问的差异则被移动到外部存储。

从外部存储切换到对象存储

自动迁移只会移动存储在数据库中的差异,不会在不同存储类型之间移动差异。要从外部存储切换到对象存储:

  1. 手动将存储在本地或 NFS 存储上的文件移动到对象存储。

  2. 运行此 Rake 任务以在数据库中更新它们的位置。

    对于 Linux 包安装:

    sudo gitlab-rake gitlab:external_diffs:force_object_storage

    对于源码编译安装:

    sudo -u git -H bundle exec rake gitlab:external_diffs:force_object_storage RAILS_ENV=production

    默认情况下,sudo 不会保留现有的环境变量。您应该将它们追加到命令末尾,而不是放在前面,如下所示:

    sudo gitlab-rake gitlab:external_diffs:force_object_storage START_ID=59946109 END_ID=59946109 UPDATE_DELAY=5

这些环境变量会修改 Rake 任务的行为:

名称 默认值 用途
ANSI true 使用 ANSI 转义代码使输出更易于理解。
BATCH_SIZE 1000 按此大小的批次遍历表。
START_ID nil 如果设置,则从此 ID 开始扫描。
END_ID nil 如果设置,则在此 ID 停止扫描。
UPDATE_DELAY 1 每次更新之间休眠的秒数。
  • START_IDEND_ID 可用于并行运行更新,方法是为不同进程分配表的不同部分。
  • BATCH_SIZEUPDATE_DELAY 可以在迁移速度与对表的并发访问之间进行权衡。
  • 如果您的终端不支持 ANSI 转义代码,应将 ANSI 设置为 false

要检查外部差异在对象存储和本地存储之间的分布情况,请使用以下 SQL 查询:

gitlabhq_production=# SELECT count(*) AS total,
  SUM(CASE
    WHEN external_diff_store = '1' THEN 1
    ELSE 0
  END) AS filesystem,
  SUM(CASE
    WHEN external_diff_store = '2' THEN 1
    ELSE 0
  END) AS objectstg
FROM merge_request_diffs;