リポジトリ保存タイプ

GitLabは1つまたは複数のリポジトリストレージを使うように設定できます。これらのストレージには、以下のどちらかの方法でアクセスします:

GitLab:

  • リポジトリストレージの設定は
    • /etc/gitlab/gitlab.rb Linux パッケージインストール用のgit_data_dirs({}) 設定ハッシュによって設定されます。
    • gitlab.yml セルフコンパイルインストールの場合は、repositories.storages キーで指定します。
  • default リポジトリストレージは、カスタマイズしていないすべてのインストールで利用可能です。デフォルトでは、Gitalyノードを指しています。

ここで説明するリポジトリストレージの種類は、git_data_dirs({}) またはrepositories.storages で定義されているリポジトリストレージに適用されます。

ハッシュストレージ

GitLab16.3でストレージ名フィールドがGitalyストレージ名から相対パスフィールドがGitaly相対パスから名称 変更されました。

ハッシュストレージはプロジェクトのIDのハッシュに基づいた場所にプロジェクトをディスク上に保存します。これにより、フォルダ構造が不変になり、URLからディスク構造への状態の同期が不要になりました。つまり、グループ、ユーザー、プロジェクトの名前を変更できます:

  • データベースのトランザクションにのみコストがかかります。
  • すぐに有効になります。

また、ハッシュを使用すると、リポジトリがディスク上に均等に分散されます。トップレベル・ディレクトリに含まれるフォルダの数は、トップレベル・ネームスペースの総数よりも少なくなります。

ハッシュ形式は、SHA256(project.id) で計算される SHA256 の 16 進表現に基づいています。トップレベルのフォルダは最初の2文字を使用し、次の2文字を別のフォルダが使用します。これらは両方とも特別な@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. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. 左サイドバーで、「概要」>「プロジェクト」を選択し、プロジェクトを選択します。
  4. 相対パス・フィールドを探します。値は似ています:

    "@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 パッケージインストールでは、ディレクトリ名の末尾から.git を取り除いた/var/opt/gitlab/git-data/repositories/@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git となります。

出力には、プロジェクト ID とプロジェクト名が含まれます。例えば

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

*.git ディレクトリにあるconfig ファイルを使ってプロジェクト名を調べるには:

  1. *.git ディレクトリを探します。このディレクトリは/var/opt/gitlab/git-data/repositories/@hashed/ にあり、ハッシュの最初の 4 文字は@hashed/ 以下のパスの最初の 2 つのディレクトリです。例えば、デフォルトの Linux パッケージインストールでは、ハッシュb17eb17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9*.git ディレクトリは/var/opt/gitlab/git-data/repositories/@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.gitになります。
  2. config ファイルを開き、[gitlab] の下にあるfullpath= キーを探します。

ハッシュされたオブジェクト・プール

オブジェクトプールは、公開プロジェクトと内部プロジェクトのフォークを重複排除するために使用されるリポジトリで、ソースプロジェクトのオブジェクトが格納されています。objects/info/alternates を使うと、ソースプロジェクトとフォークはオブジェクトプールを使ってオブジェクトを共有します。詳しくは、GitLabのGitオブジェクト重複排除の仕組みをご覧ください。

オブジェクトは、ソース・プロジェクトでハウスキーピングが実行されると、ソース・プロジェクトからオブジェクト・プールに移動します。オブジェクトプールリポジトリは通常のリポジトリと同様に、@pools というディレクトリに格納されます。@hashed

# object pool paths
"@pools/#{hash[0..1]}/#{hash[2..3]}/#{hash}.git"
caution
@pools ディレクトリに格納されるオブジェクト・プール・リポジトリでは、git prune またはgit gc を実行しないでください。オブジェクト・プールに依存する通常のリポジトリでデータが失われる可能性があります。

グループWikiストレージ

@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はストレージの場所を管理します。Praefectがリポジトリに使用する内部パスは、ハッシュ化されたパスとは異なります。詳細については、Praefectが生成するレプリカパスを参照してください。

オブジェクトストレージのサポート

この表は、各ストレージタイプでどのオブジェクトが保存可能かを示しています:

保存可能なオブジェクトハッシュストレージS3互換
リポジトリはい-
添付ファイルはい-
アバターなし-
Pagesなし-
Dockerレジストリなし-
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の実装に従って、2つの文字と2つのレベルのフォルダを使った同様のストレージパターンを実装しています:

"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とも互換性があります。