仓库存储

极狐GitLab 将仓库存储在仓库存储中。仓库存储是:

  • gitaly_address,指向一个 Gitaly 节点
  • path,它直接指向存储存储库的目录。此方法在 14.0 版本中已弃用并计划删除。极狐GitLab 应配置为通过 gitaly_address 访问 GitLab 仓库。
caution 仓库存储可以被配置为 path,其直接指向存储存储库的目录。极狐GitLab 直接访问包含仓库的目录功能已经被弃用。您应该配置来通过物理或虚拟存储来访问仓库。

更多信息:

哈希存储

  • 支持传统存储,基于项目路径来生成仓库路径的传统存储已经在极狐GitLab 14.0 中被移除。
  • 在极狐GitLab 16.3 中,Gitaly 存储名称 被重命名为 存储名称Gitaly 相对路径 被重命名为 相对路径

哈希存储将项目存储在基于项目 ID 哈希值的磁盘路径下。这能够确保文件夹结构的不可变性,并且无需将状态从 URL 同步到磁盘结构。这意味着,重命名群组、用户或项目会:

  • 仅需花费数据库事务的成本。
  • 立即生效。

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

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

# 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. 定位至 相对路径 字段。该值类似于:

    "@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/,其中哈希值的前 4 个字符是 @hashed 路径下的前两个目录。例如,在默认的 Linux 软件包安装中,哈希值为 b17eb17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9*.git 目录路径会是 /var/opt/gitlab/git-data/repositories/@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git
  2. 打开 config 文件并在 [gitlab] 部分中找到 fullpath= 键。

哈希对象池

对象池是一种仓库,用于对公共和内部项目的派生项目进行重复数据删除。 它包含源项目中的对象。源项目及其派生项目通过 objects/info/alternates 使用对象池来存储共享对象。更多信息,请参阅 Git 对象重复数据消除在 GitLab 中的工作原理

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

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

转换哈希对象池存储路径

使用 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
    
    # Get more details about the 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。

比如:

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

Gitaly 集群存储

如果使用了 Gitaly 集群,Praefect 会管理存储位置。Praefect 使用的仓库内部路径和哈希路径是不同的。更多信息,可以查看 Praefect 生成的副本路径

对象存储支持

此表展示了哪些可存储对象可存储于每种存储类型中:

可存储的对象 哈希存储 S3 兼容
仓库 Yes -
附件 Yes -
头像 No -
Pages No -
容器镜像 No -
CI/CD 作业日志 No -
CI/CD 产物 No Yes
CI/CD 缓存 No Yes
LFS 对象 Similar Yes
仓库池 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 兼容的

配置新仓库的存储位置

配置多个仓库存储路径后,您可以选择存储新仓库的位置:

  1. 在左侧导航栏,底部,选择 管理员
  2. 在左侧边栏中,选择 设置 > 仓库 并展开 仓库存储 部分。
  3. 新仓库的存储节点 字段中输入值。
  4. 选择 保存更改

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

给定仓库存储路径相对于其他仓库存储路径的权重越高,选择它的频率就越高。公式为:(storage weight) / (sum of all weights) * 100 = chance %

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

  • default 的权重为 100
  • 所有其它存储的权重为 0
note 如果所有存储权重均为 0(例如,当 default 不存在时),GitLab 会尝试在 default 上创建新的仓库,无论配置如何或是否存在 default

移动仓库

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