仓库存储类型

极狐GitLab 可以配置为使用一个或多个仓库存储。这些存储可以是:

  • 通过 Gitaly 访问,可选择在其自己的服务器上访问。
  • 挂载到本地磁盘。此方法在 14.0 版本中已弃用并计划删除。
  • 作为 NFS 共享卷公开。此方法在 14.0 版本中已弃用并计划删除。

在极狐GitLab 中:

  • 存储库存储配置为:
    • /etc/gitlab/gitlab.rbgit_data_dirs({}) 配置哈希用于 Linux 软件包安装。
    • gitlab.ymlrepositories.storages 键用于从源代码安装。
  • default 仓库存储可用于任何未对其进行自定义的安装。默认情况下,它指向一个 Gitaly 节点。

此处记录的仓库存储类型适用于在 git_data_dirs({})repositories.storages 中定义的任何仓库存储。

哈希存储

哈希存储将项目存储在磁盘上基于项目 ID 哈希的位置。哈希存储与 legacy 存储不同,其中项目存储基于:

  • 项目的 URL。
  • 仓库存储在磁盘上的文件夹结构。

这使得文件夹结构不可变,并且无需将状态从 URL 同步到磁盘结构。这意味着重命名组、用户或项目:

  • 仅花费数据库事务。
  • 立即生效。

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

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

# Project's repository:
"@hashed/#{hash[0..1]}/#{hash[2..3]}/#{hash}.git"

# Wiki's repository:
"@hashed/#{hash[0..1]}/#{hash[2..3]}/#{hash}.wiki.git"

转换哈希存储路径

对 Git 仓库的问题进行故障排除、添加钩子和其它任务,需要您在可读的项目名称和哈希存储路径之间进行转换。您可以转换:

项目名称到哈希路径

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

要在管理中心查找项目的哈希路径:

  1. 在左侧边栏中,选择 搜索或转到
  2. 选择 管理中心
  3. 在左侧边栏中,选择 概览 > 项目 并选择项目。

Gitaly 相对路径 显示在那里,类似于:

"@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>

要使用 *.git 目录中的 config 文件查找项目名称:

  1. 定位到 *.git 目录。该目录位于 /var/opt/gitlab/git-data/repositories/@hashed/,其中 hash 的前四个字符是 @hashed/ 下路径中的前两个目录。例如,在默认 Linux 软件包安装实例的 *.git 目录中的哈希 b17eb17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9 应为 /var/opt/gitlab/git-data/repositories/@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git
  2. 打开 config 文件,找到 [gitlab] 下的 fullpath= 键。

哈希对象池

对象池是用于对公共和内部项目的复刻进行重复数据删除,并包含源项目中的对象的仓库。使用 objects/info/alternates,源项目和分支使用共享对象的对象池。

在源项目上运行 housekeeping 时,对象从源项目移动到对象池。对象池仓库类似于常规仓库,存储在名为@pools 而不是@hashed 的目录中

# object pool paths
"@pools/#{hash[0..1]}/#{hash[2..3]}/#{hash}.git"
caution 不要在存储在 @pools 目录中的对象池仓库中运行 git prunegit gc。这可能会导致依赖于对象池的常规仓库中的数据丢失。

群组 wiki 存储

引入于 13.5 版本。

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

例如:

# group wiki paths
"@groups/#{hash[0..1]}/#{hash[2..3]}/#{hash}.wiki.git"

Gitaly 集群存储

如果使用 Gitaly Cluster,Praefect 会管理存储位置。

对象存储支持

下表显示了每种存储类型中可存储哪些可存储对象:

可存储对象 Legacy 存储 哈希存储 S3 兼容
Repository Yes Yes -
Attachments Yes Yes -
Avatars Yes No -
Pages Yes No -
Docker Registry Yes No -
CI/CD job logs No No -
CI/CD artifacts No No Yes
CI/CD cache No No Yes
LFS objects Yes Similar Yes
Repository pools No Yes -

存储在 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]}"

# Based on object `oid`: `8909029eb962194cfb326259411b22ae3f4a814b5be4f80651735aeef9f3229c`, path will be:
"shared/lfs-objects/89/09/029eb962194cfb326259411b22ae3f4a814b5be4f80651735aeef9f3229c"

LFS 对象也是 S3 兼容的

Legacy 存储

caution 在 13.0 版本中,legacy 存储已被弃用。如果您还没有迁移到哈希存储,请查看迁移说明。在 14.0 版本中计划删除 legacy 存储支持。在 13.0 及更高版本中,无法将新项目切换到 legacy 存储。在管理中心,选择哈希存储和 legacy 存储的选项被禁用。

legacy 存储是之前的存储行为。由于历史原因,GitLab 从项目 URL 中复制了相同的映射结构:

  • 项目的仓库:#{namespace}/#{project_name}.git
  • 项目的维基:#{namespace}/#{project_name}.wiki.git

这种结构使您能够从现有解决方案迁移到 GitLab,并使管理员能够找到仓库的存储位置。这种方法也有一些缺点:

  • 存储位置集中了大量的顶级命名空间。多个存储库存储路径可以减少影响。
  • 因为备份是同一个 URL 映射的快照,如果您试图恢复一个非常旧的备份,您需要验证是否有任何项目取代了共享相同 URL 的旧的已删除或重命名的项目。这意味着您备份中的 mygroup/myproject 可能与今天位于同一 URL 的原始项目不同。
  • 旧存储是 GitLab 10.0 版本之前的存储行为。由于历史原因,GitLab 从项目 URL 中复制了相同的映射结构:

  • 项目的存储库:#{namespace}/#{project_name}.git
  • 项目的维基:#{namespace}/#{project_name}.wiki.git

这种结构使您能够从现有解决方案迁移到 GitLab,并使管理员能够找到存储库的存储位置。这种方法也有一些缺点:

  • 存储位置集中了大量的顶级命名空间。 多个存储库存储路径 可以减少影响。
  • 因为备份是同一个 URL 映射的快照,如果您试图恢复一个非常旧的备份,您需要验证是否有任何项目取代了共享相同 URL 的旧的已删除或重命名的项目。这意味着您备份中的“mygroup/myproject”可能与今天位于同一 URL 的原始项目不同。
  • 重命名群组、用户或项目时,需要在磁盘上反映 URL 中的任何更改。这可能会在大型安装中增加大量负载,尤其是在使用任何类型的基于网络的文件系统时。