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

代码库存储

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

GitLab 将 代码库 存储在代码库存储中。代码库存储可以是:

  • 物理存储:通过配置 gitaly_address 指向一个 Gitaly 节点
  • 虚拟存储:在 Gitaly 集群(Praefect)上存储代码库。

代码库存储可以配置为直接指向存储代码库目录的 path。GitLab 直接访问包含代码库的目录已被弃用。您应该配置 GitLab 通过物理或虚拟存储访问代码库。

有关更多信息,请参阅:

哈希存储

哈希存储根据项目 ID 的哈希值在磁盘上存储项目。这使得文件夹结构不可变,并且消除了从 URL 同步状态到磁盘结构的需要。这意味着重命名一个组、用户或项目:

  • 只需数据库事务。
  • 立即生效。

哈希还有助于更均匀地分布磁盘上的代码库。顶级目录包含的文件夹数量少于顶级命名空间的总数。

哈希格式基于 SHA256 的十六进制表示,使用 SHA256(project.id) 计算。顶级文件夹使用前两个字符,接着是下一个两个字符的文件夹。它们都存储在特殊的 @hashed 文件夹中,以便与现有的旧版存储项目共存。例如:

# 项目的代码库:
"@hashed/#{hash[0..1]}/#{hash[2..3]}/#{hash}.git"

# Wiki 的代码库:
"@hashed/#{hash[0..1]}/#{hash[2..3]}/#{hash}.wiki.git"

转换哈希存储路径

解决 Git 代码库问题、添加钩子和其他任务需要您在人类可读的项目名称和哈希存储路径之间进行转换。您可以转换:

从项目名称到哈希路径

管理员可以使用以下方法从项目名称或 ID 查找项目的哈希路径:

Admin 区域查找项目的哈希路径:

  1. 在左侧边栏底部,选择 Admin

  2. 选择 概览 > 项目,然后选择项目。

  3. 找到 相对路径 字段。其值类似于:

    "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"

使用 Rails 控制台查找项目的哈希路径:

  1. 启动 Rails 控制台

  2. 运行类似以下示例的命令(使用项目的 ID 或名称):

    Project.find(16).disk_path
    Project.find_by_full_path('group/project').disk_path

从哈希路径到项目名称

管理员可以使用以下方法从项目的哈希相对路径查找项目名称:

  • Rails 控制台。
  • *.git 目录中的 config 文件。

使用 Rails 控制台查找项目名称:

  1. 启动 Rails 控制台

  2. 运行类似以下示例的命令:

    ProjectRepository.find_by(disk_path: '@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9').project

该命令中的引号字符串是您可以在 GitLab 服务器上找到的目录树。例如,在默认的 Linux 包安装中,这将是 /var/opt/gitlab/git-data/repositories/@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git,其中目录名称末尾的 .git 被移除。

输出包括项目 ID 和项目名称。例如:

=> #<Project id:16 it/supportteam/ticketsystem>

哈希对象池

对象池是用于去重 公共和内部项目的分支 并包含源项目对象的代码库。使用 objects/info/alternates,源项目和分支使用对象池来共享对象。有关更多信息,请参阅 GitLab 开发文档中的 Git 对象去重信息。

当在源项目上运行维护时,对象会从源项目移动到对象池。对象池代码库存储方式与常规代码库类似,但存储在名为 @pools 的目录中,而不是 @hashed

# 对象池路径
"@pools/#{hash[0..1]}/#{hash[2..3]}/#{hash}.git"

不要在存储在 @pools 目录中的对象池代码库中运行 git prunegit gc。这可能导致依赖对象池的常规代码库数据丢失。

转换哈希对象池存储路径

使用 Rails 控制台查找项目的对象池:

  1. 启动 Rails 控制台

  2. 运行类似以下示例的命令:

    project_id = 1
    pool_repository = Project.find(project_id).pool_repository
    pool_repository = Project.find_by_full_path('group/project').pool_repository
    
    # 获取对象池代码库的更多详细信息
    pool_repository.source_project
    pool_repository.member_projects
    pool_repository.shard
    pool_repository.disk_path

组 Wiki 存储

与存储在 @hashed 目录中的项目 Wiki 不同,组 Wiki 存储在名为 @groups 的目录中。与项目 Wiki 一样,组 Wiki 遵循哈希存储文件夹约定,但使用组 ID 的哈希值而不是项目 ID。

例如:

# 组 Wiki 路径
"@groups/#{hash[0..1]}/#{hash[2..3]}/#{hash}.wiki.git"

Gitaly 集群(Praefect)存储

如果使用 Gitaly 集群(Praefect),Praefect 管理存储位置。Praefect 用于代码库的内部路径与哈希路径不同。有关更多信息,请参阅 Praefect 生成的副本路径

代码库文件归档缓存

用户可以通过以下方式下载代码库的 .zip.tar.gz 格式归档:

GitLab 将此归档存储在 GitLab 服务器上的目录中的缓存中。

在 Sidekiq 上运行的后台作业会定期清理此目录中的过期归档。因此,此目录必须可被 Sidekiq 和 GitLab Workhorse 服务访问。如果 Sidekiq 无法访问 GitLab Workhorse 使用的同一目录,包含该目录的磁盘将填满

如果您不想为 Sidekiq 和 GitLab Workhorse 使用共享挂载,您可以改为配置单独的 cron 作业来删除此目录中的文件。

文件归档缓存的默认目录是 /var/opt/gitlab/gitlab-rails/shared/cache/archive。您可以在 /etc/gitlab/gitlab.rb 中使用 gitlab_rails['gitlab_repository_downloads_path'] 设置进行配置。

要禁用缓存:

  1. 在所有运行 Puma 的节点上设置 WORKHORSE_ARCHIVE_CACHE_DISABLED 环境变量:

    sudo -e /etc/gitlab/gitlab.rb
    gitlab_rails['env'] = { 'WORKHORSE_ARCHIVE_CACHE_DISABLED' => '1' }
  2. 重新配置更新的节点以使更改生效:

    sudo gitlab-ctl reconfigure

Helm chart 将缓存存储在 /srv/gitlab/shared/cache/archive。 该目录无法配置。

要禁用缓存,您可以使用 --set gitlab.webservice.extraEnv.WORKHORSE_ARCHIVE_CACHE_DISABLED="1",或在您的 values 文件中指定以下内容:

gitlab:
  webservice:
    extraEnv:
      WORKHORSE_ARCHIVE_CACHE_DISABLED: "1"

对象存储支持

下表显示了每种存储类型可存储的对象:

可存储对象 哈希存储 S3 兼容
代码库 -
附件 -
头像 -
Pages -
Docker Registry -
CI/CD 作业日志 -
CI/CD 工件
CI/CD 缓存
LFS 对象 类似
代码库池 -

存储在 S3 兼容端点中的文件可以具有与 哈希存储 相同的优势,只要它们不以 #{namespace}/#{project_name} 为前缀。这对于 CI/CD 缓存和 LFS 对象也是如此。

头像

每个文件都存储在与其在数据库中分配的 id 匹配的目录中。用户头像的文件名始终为 avatar.png。当头像被替换时,Upload 模型被销毁,一个新的模型会以不同的 id 取而代之。

CI/CD 工件

CI/CD 工件是 S3 兼容的。

LFS 对象

GitLab 中的 LFS 对象 实现了类似的存储模式,使用两个字符和两级文件夹,遵循 Git 实现:

"shared/lfs-objects/#{oid[0..1}/#{oid[2..3]}/#{oid[4..-1]}"

# 基于对象 `oid`: `8909029eb962194cfb326259411b22ae3f4a814b5be4f80651735aeef9f3229c`,路径将是:
"shared/lfs-objects/89/09/029eb962194cfb326259411b22ae3f4a814b5be4f80651735aeef9f3229c"

LFS 对象也是 S3 兼容的

配置新代码库的存储位置

在您 配置多个代码库存储 后,您可以选择新代码库的存储位置:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 设置 > 代码库
  3. 展开 代码库存储
  4. 新代码库的存储节点 字段中输入值。
  5. 选择 保存更改

每个代码库存储路径可以分配 0-100 的权重。当创建新项目时,这些权重用于确定代码库的存储位置。

相对于其他代码库存储路径,给定代码库存储路径的权重越高,被选择的频率就越高((存储权重) / (所有权重总和) * 100 = 机会 %)。

默认情况下,如果之前未配置代码库权重:

  • default 权重为 100
  • 所有其他存储权重为 0

如果所有存储权重都为 0(例如,当 default 不存在时),GitLab 会尝试在 default 上创建新代码库,无论配置如何或 default 是否存在。 有关更多信息,请参阅 跟踪问题

移动代码库

要将代码库移动到不同的代码库存储(例如,从 defaultstorage2),使用与 迁移到 Gitaly 集群(Praefect) 相同的流程。