ハウスキーピング

GitLabはGitリポジトリのハウスキーピングタスクをサポートし、自動化します。ハウスキーピングタスクには以下が含まれます:

  • Git オブジェクトとリビジョンの圧縮。
  • 到達不可能なオブジェクトの削除。
  • ロックファイルのような古いデータの削除。
  • パフォーマンスを向上させるデータ構造のメンテナー。
  • フォーク間のオブジェクト重複排除を改善するためのオブジェクトプールの更新。
caution
GitLabによって管理されているGitリポジトリでハウスキーピングを行うために手動でGitコマンドを実行しないでください。そうすることで、リポジトリが破損し、データが失われる可能性があります。

ハウスキーピング戦略

Gitalyは、Gitリポジトリのハウスキーピングタスクを2つの方法で実行できます:

  • Eager housekeepingは、リポジトリの状態とは無関係に特定のハウスキーピングタスクを実行します。
  • ヒューリスティックなハウスキーピングは、リポジトリの状態に基づいて実行すべきハウスキーピングタスクを決定するヒューリスティックなセットに基づいて、ハウスキーピングタスクを実行します。

熱心なハウスキーピング

eager “ハウスキーピング戦略は、リポジトリの状態に依存せずにハウスキーピングタスクを実行します。これは手動トリガーやプッシュ型トリガーで使用されるデフォルトの戦略です。

eagerハウスキーピング戦略は、GitLabアプリケーションによって制御されます。ハウスキーピング・ジョブを実行させたトリガーに応じて、GitLabはGitalyに特定のハウスキーピング・タスクを実行するよう依頼します。Gitalyは、リポジトリが最適化された状態であっても、これらのタスクを実行します。その結果、ハウスキーピングタスクの実行に時間がかかるような大規模リポジトリでは、この戦略は非効率になる可能性があります。

ヒューリスティックなハウスキーピング

ヒューリスティック(または「オポチュニスティック」)なハウスキーピング戦略は、リポジトリの状態を分析し、1つ以上のデータ構造が十分に最適化されていないと判断した場合にのみハウスキーピングタスクを実行します。これはスケジュールされたハウスキーピングで使用される戦略です。

ヒューリスティックなハウスキーピングは、実行するタスクを決めるために以下の情報を使用します:

  • ルーズで古いオブジェクトの数。
  • 既に圧縮されたオブジェクトを含むパックファイルの数。
  • 緩い参照の数。
  • コミットグラフの有無。

分析されたデータ構造のいずれかを最適化する必要があるかどうかは、リポジトリのサイズに基づいて決定されます:

  • すべてのオブジェクトの合計サイズが大きくなるほど、オブジェクトは頻繁に再パックされます。
  • リファレンスは、リファレンスの総数が多いほど、リパックされる頻度が低くなります。

Gitalyは、データ構造が大きくなればなるほど、最適化に時間がかかるという事実を相殺するために、このようにしています。大きなモノレポ(多くのトラフィックを受ける)では、頻繁に最適化しすぎないようにすることが特に重要です。

Gitalyにリポジトリの最適化を依頼する頻度を変更することができます。

  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. 左側のサイドバーで、設定 > リポジトリ を選択します。
  4. リポジトリメンテナンスを展開します。
  5. ハウスキーピングセクションで、ハウスキーピングオプションを設定します。
  6. 変更を保存を選択します。
  • リポジトリの自動管理を有効にします:定期的にGitalyにリポジトリ最適化の実行を依頼します。この設定を長い間無効にしておくと、GitLabサーバー上のGitリポジトリへのアクセスが遅くなり、リポジトリがより多くのディスクスペースを使用するようになります。
  • リポジトリの最適化期間:Gitalyにリポジトリの最適化を依頼するGitプッシュの回数。

ハウスキーピングタスクの実行

GitLabがハウスキーピングタスクを実行する方法は様々です:

  • プロジェクトの管理者は、リポジトリのハウスキーピングタスクを手動で起動することができます。
  • GitLabはGitプッシュの回数の後に自動的にハウスキーピングタスクをスケジュールすることができます。
  • GitLabは設定可能な時間枠で全てのリポジトリのハウスキーピングタスクを実行するジョブをスケジュールすることができます。

手動トリガー

リポジトリの管理者は、リポジトリのハウスキーピングタスクを手動でトリガーすることができます。GitLab は自動的にハウスキーピングタスクを実行することを知っているので、一般的にこれは必要ありません。手動トリガーは以下のような場合に便利です:

  • リポジトリがハウスキーピングを必要とすることがわかっているとき。
  • ハウスキーピングタスクの自動化されたプッシュベースのスケジューリングは無効になっています。

ハウスキーピングタスクを手動で起動するには、以下の手順に従います:

  1. 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
  2. 左サイドバーで、設定 > 一般を選択します。
  3. 詳細設定] を展開します。
  4. ハウスキーピングの実行]を選択します。

プロジェクトのリポジトリに対して非同期のバックグラウンドワーカーを開始します。バックグラウンドワーカーはGitalyにいくつかの最適化を実行するよう依頼します。

ハウスキーピングはまた、200 プッシュするたびに、参照されていない LFS ファイルをプロジェクトから削除し、プロジェクトのストレージ領域を解放します。

到達不可能なオブジェクトの削除

到達不可能なオブジェクトは、スケジュールされたハウスキーピングの一部として刈り込まれます。しかし、手動で刈り込むこともできます。例えば、機密情報を含むコミットの削除などです。ハウスキーピングをトリガーすると、2週間の猶予期間をおいて到達不能オブジェクトが刈り込まれます。手動で到達不能オブジェクトの刈り込みをトリガーすると、猶予期間は30分に短縮されます。

caution
並行プロセス(git push など)がオブジェクトを作成したが、まだオブジェクトへの参照を作成していない場合、オブジェクトが削除された後にオブジェクトへの参照が追加されると、リポジトリが破損する可能性があります。猶予期間は、このような競合状態の可能性を減らすために存在します。

到達不可能なオブジェクトを手動で削除するには

  1. 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
  2. 左サイドバーで、設定 > 一般を選択します。
  3. 詳細設定] を展開します。
  4. ハウスキーピングの実行]を選択します。
  5. オペレーションが完了するまで30分待ちます。
  6. ハウスキーピングの実行]を選択したページに戻り、[到達不能なオブジェクトの削除]を選択します。

ハウスキーピングのスケジュール

GitLab はプッシュ数に応じてハウスキーピングタスクを自動的に実行しますが、プッシュをまったく受け取らないリポジトリはメンテナーしません。その結果、アクティブでないリポジトリや読み込みリクエストしか受け取っていないリポジトリは、リポジトリのハウスキーピング戦略の改善の恩恵を受けられない可能性があります。

管理者は、この状況を改善するために、カスタマイズ可能な間隔ですべてのリポジトリのハウスキーピングを実行するバックグラウンドジョブを有効にすることができます。このバックグラウンドジョブは、Gitalyノードがホストするすべてのリポジトリをランダムな順序で処理し、熱心にハウスキーピングタスクを実行します。Gitalyノードは、設定された間隔よりも長い時間がかかる場合、リポジトリの処理を停止します。

スケジュールされたハウスキーピングの設定

Gitalyでは、Gitリポジトリのバックグラウンドメンテナンスを設定することができます。デフォルトでは、Gitalyは毎日正午12時に10分間のバックグラウンドリポジトリメンテナンスを行います。

Gitalyの設定でこのデフォルトを変更することができます。以下のスニペットでは、default ストレージに対して、毎日 23:00 から 1 時間のバックグラウンド・リポジトリ・メンテナンスを有効にしています:

Self-compiled (source)
[daily_maintenance]
start_hour = 23
start_minute = 00
duration = 1h
storages = ["default"]

バックグラウンドでのリポジトリメンテナンスを完全に無効にするには、以下のスニペットを使ってください:

[daily_maintenance]
disabled = true
Linux package (Omnibus)
gitaly['configuration'] = {
  daily_maintenance: {
    disabled: false,
    start_hour: 23,
    start_minute: 00,
    duration: '1h',
    storages: ['default'],
  },
}

バックグラウンドでのリポジトリメンテナンスを完全に無効にするには、以下のスニペットを使ってください:

gitaly['configuration'] = {
  daily_maintenance: {
    disabled: true,
  },
}

オブジェクトプールリポジトリ

オブジェクトプールリポジトリは、GitLabがリポジトリのフォーク間でオブジェクトを重複排除するために使うものです。最初のフォークを作成するときに

  1. フォークしようとしているリポジトリのすべてのオブジェクトを含むオブジェクトプールリポジトリを作成します。
  2. Git の alternates メカニズムを使って、リポジトリをこの新しいオブジェクトプールにリンクします。
  3. オブジェクトプールのオブジェクトを使うようにリポジトリをリパックします。こうすることで、オブジェクトのコピーを削除できるようになります。

このリポジトリのフォークは、オブジェクトプールとリンクできるようになり、プライマリリポジトリから分岐したオブジェクトだけを保持すればよくなりました。

GitLab はオブジェクトプールで特別なハウスキーピングオペレーションを行う必要があります:

  • Gitalyはオブジェクトプールから到達不可能なオブジェクトを削除することはできません。
  • 同じ理由で、Gitalyはすべてのオブジェクトを到達可能な状態に保たなければなりません。そのため、オブジェクト・プールは、到達不可能な “ぶら下がった “オブジェクトへの参照をメンテナーとして保持し、それらが削除されることがないようにしています。
  • GitLab は、プライマリリポジトリに追加された新しいオブジェクトを取り込むために、オブジェクトプールを定期的に更新しなければなりません。そうしないと、オブジェクトプールはオブジェクトの重複排除の効率がどんどん悪くなってしまいます。

これらのハウスキーピングオペレーションは、標準的な Git リポジトリで実行する通常のハウスキーピングタスクと同時に、特別なFetchIntoObjectPool RPC によって実行されます。

オブジェクトプールは、プライマリメンバーがガベージコレクションされるたびに自動的に最適化されます。そのため、プロジェクトの Git GC 周期と同じ周期で設定することができます。

Railsコンソールから手動でRPCを呼び出す必要がある場合は、project.pool_repository.object_pool.fetch。これは長時間実行される可能性のあるタスクですが、Gitalyは約8時間後にタイムアウトします。