Gitaly 클러스터 복구 옵션 및 도구

Gitaly 클러스터는 주 노드 장애 및 사용 불가능한 저장소에서 복구할 수 있습니다. Gitaly 클러스터는 데이터 복구를 수행하며 Praefect 추적 데이터베이스 도구를 보유하고 있습니다.

Gitaly 클러스터에서 Gitaly 노드 관리

Gitaly 클러스터에서 Gitaly 노드를 추가하고 교체할 수 있습니다.

새 Gitaly 노드 추가

새 Gitaly 노드를 추가하려면 다음을 수행하세요:

  1. 문서를 따라 새 Gitaly 노드를 설치합니다.
  2. praefect['virtual_storages'] 하위에 새 노드를 추가합니다.
  3. 다음 명령을 실행하여 Praefect를 다시 구성하고 재시작합니다.

    gitlab-ctl reconfigure
    gitlab-ctl restart praefect
    

복제 동작은 복제 팩터 설정에 따라 달라집니다.

사용자 정의 복제 팩터

사용자 지정 복제 팩터가 설정된 경우 Praefect는 기존 저장소를 자동으로 새 Gitaly 노드로 복제하지 않습니다. set-replication-factor Praefect 명령을 사용하여 각 저장소의 복제 팩터를 설정해야 합니다. 새 저장소는 복제 팩터에 따라 복제됩니다.

기본 복제 팩터

기본 복제 팩터를 사용하는 경우 Praefect는 설정에 새 Gitaly 노드를 추가하여 복제 팩터를 유지합니다.

기존 Gitaly 노드 교체

기존 Gitaly 노드를 동일한 이름 또는 다른 이름을 가진 새 노드로 교체할 수 있습니다. 이전 노드를 제거하기 전에:

  • 복제 팩터가 설정된 경우 데이터 유실을 방지하기 위해 팩터가 1보다 커야 합니다.
  • 복제 팩터가 설정되지 않은 경우, 저장소는 가상 저장소의 모든 노드에서 복제됩니다.

동일한 이름을 가진 노드로

교체 노드에 동일한 이름을 사용하려면 저장소 확인 도구를 사용하여 저장소를 스캔하고 불필요한 메타데이터 레코드를 제거하세요. 교체 저장소의 검증을 수동으로 우선순위 지정하여 프로세스를 가속화하세요.

다른 이름을 가진 노드로

Gitaly 클러스터의 교체 노드를 다른 이름으로 사용하는 단계는 복제 팩터에 따라 달라집니다.

복제 팩터 설정

사용자 정의 복제 팩터가 설정된 경우 praefect set-replication-factor를 사용하여 새 저장소가 할당되도록 복제 팩터를 다시 설정하세요.

예를 들어, 가상 저장소의 두 노드가 복제 팩터 2를 갖고 새 노드(gitaly-3)가 추가되는 경우, 복제 팩터를 3으로 증가해야 합니다.

$ sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage default -relative-path @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git -replication-factor 3

현재 할당: gitaly-1, gitaly-2, gitaly-3

이렇게 하면 새 노드로 저장소가 복제되고 repository_assignments 테이블이 새 Gitaly 노드의 이름으로 업데이트됩니다.

기본 복제 팩터가 설정된 경우, 새 노드는 자동으로 복제에 포함되지 않습니다. 위에서 설명한 단계를 따라야 합니다.

새 노드로 저장소가 성공적으로 복제되었는지 확인한 후:

  1. praefect['virtual_storages'] 하위에서 gitaly-1 노드를 제거합니다.
  2. Praefect를 다시 구성하고 재시작합니다:

    gitlab-ctl reconfigure
    gitlab-ctl restart praefect
    

이전 Gitaly 노드를 참조하는 데이터베이스 상태를 무시할 수 있습니다.

새로운 Gitaly 노드를 구성한 후 이전 저장소에서 모든 저장소를 새로운 저장소로 다시 할당할 수도 있습니다:

  1. Praefect 데이터베이스에 연결합니다.

    /opt/gitlab/embedded/bin/psql -h <psql 호스트> -U <사용자> -d <데이터베이스 이름>
    
  2. repository_assignments 테이블을 업데이트하여 이전 Gitaly 노드 이름(예: old-gitaly)을 새 Gitaly 노드 이름(예: new-gitaly)으로 교체합니다.

    UPDATE repository_assignments SET storage='new-gitaly' WHERE storage='old-gitaly';
    

이렇게 하면 시스템을 원하는 상태로 되돌리는 데 필요한 적절한 복제 작업이 트리거됩니다.

주 노드 장애

Gitaly 클러스터는 실패한 주 Gitaly 노드를 건강한 보조 노드로 승격시켜 새로운 주로 복구합니다. Gitaly 클러스터는 다음을 수행합니다:

  • 저장소의 완전히 최신 복사본이 있는 건강한 보조 노드를 새 주로 선출합니다.
  • 완전히 최신 보조가 사용 가능하지 않은 경우, 주로부터 가장 최소한의 복제되지 않은 쓰기가 있는 보조를 새로운 주로 선출합니다.
  • 건강한 보조에 저장소의 완전히 최신 복사본이 없는 경우 저장소는 사용 불가능해집니다. Praefect dataloss 하위 명령을 사용하여 이를 감지하세요.

사용 불가능한 저장소

저장소는 최신 복제본이 모두 사용 불가능한 경우에는 저장소가 사용 불가능합니다. 사용 불가능한 저장소는 자동화된 도구의 실행을 방해할 수 있는 오래된 데이터를 제공하지 않도록 Praefect를 통해 접근할 수 없습니다.

데이터 손실 확인

Praefect dataloss 하위 명령을 사용하여 사용 불가능한 저장소를 식별합니다. 이를 통해 잠재적인 데이터 손실과 더 이상 접근할 수 없는 저장소를 확인할 수 있습니다.

다음 매개변수를 사용할 수 있습니다:

  • -virtual-storage: 어떤 가상 저장소를 확인해야 하는지 지정합니다. 관리자 개입이 필요할 수 있으므로 기본 동작은 사용 불가능한 저장소를 표시하는 것입니다.
  • -부분적으로-사용-불가능: 사용 가능하지만 일부 할당된 복사본이 사용 불가능한 저장소를 출력에 포함해야 하는지 여부를 지정합니다.

참고: dataloss는 아직 베타 상태이며 출력 형식이 변경될 수 있습니다.

오래된 주 또는 사용 불가능한 저장소를 확인하려면 다음을 실행하세요:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss [-virtual-storage <가상-저장소>]

지정된 것이 없으면 모든 구성된 가상 저장소를 확인합니다:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss

출력에 사용 불가능한 저장소가 표시됩니다. 각 저장소에 대해 다음 정보가 인쇄됩니다:

  • 저장소의 저장소 디렉토리에 대한 상대 경로는 각 저장소를 식별하고 관련 정보를 그룹화합니다.
  • 저장소가 사용 불가능한 경우 디스크 경로 옆에 (unavailable)이 인쇄됩니다.
  • primary 필드는 저장소의 현재 주를 나열합니다. 저장소에 주가 없으면 No Primary가 표시됩니다.
  • In-Sync Storages에는 최신 성공적인 쓰기와 그 이전의 모든 쓰기를 복제한 복제본이 나열됩니다.
  • Outdated Storages에는 저장소의 오래된 복사본이 포함됩니다. 복사본이 없어야 할 저장소가 여기에 나열됩니다. 복제본이 누락된 최대 변경 수가 복제본 옆에 나열됩니다. 오래된 복제본은 완전히 최신이거나 나중에 변경되었을 수 있지만 Praefect가 보장할 수 없는 중요한 사실입니다.

추가 정보는 다음을 포함합니다:

  • 저장소를 호스트하도록 할당된 노드 여부를 각 노드의 상태와 함께 나열합니다. 저장소를 저장하도록 할당된 노드 옆에 assigned host가 인쇄됩니다. 노드에 저장소의 복사본이 있지만 저장소를 저장할당된 노드가 아닌 경우 텍스트가 생략됩니다. 이러한 복사본은 Praefect에 의해 동기화되지 않지만 할당된 복사본을 최신 상태로 유지하는 복제원으로 작동할 수 있습니다.
  • unhealthy가 건강하지 않은 Gitaly 노드에 있는 복사본 옆에 인쇄됩니다.

출력 예시:

가상 저장소: default
  오래된 저장소:
    @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git (사용 불가능):
      Primary: gitaly-1
      In-Sync Storages:
        gitaly-2, assigned host, unhealthy
      Outdated Storages:
        gitaly-1은 3개 이하의 변경에 뒤처져 있음, assigned host
        gitaly-3은 3개 이하의 변경에 뒤처져 있음

모든 저장소가 사용 가능한 경우 확인 메시지가 출력됩니다. 예:

가상 저장소: default
  모든 저장소가 사용 가능합니다!

이용 불가능한 보조 복제본들의 이용 가능 저장소

일부 할당된 노드에서 이용 불가능하지만 사용 가능한 저장소의 정보도 나열하려면 -partially-unavailable 플래그를 사용하세요.

최신 상태이고 건강한 복제본이 있는 경우 저장소는 사용 가능합니다. 일부 할당된 보조 복제본은 최신 변경 사항을 복제하는 동안 일시적으로 접근할 수 없는 상태일 수 있습니다.

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss [-virtual-storage <virtual-storage>] [-partially-unavailable]

예시 출력:

가상 저장소: 기본
  최신 상태가 아닌 저장소:
    @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git:
      기본: gitaly-1
      동기화된 저장소:
        gitaly-1, 할당된 호스트
      최신 상태가 아닌 저장소:
        gitaly-2가 3개 이하의 변경으로 뒤쳐져 있음, 할당된 호스트
        gitaly-3가 3개 이하의 변경으로 뒤쳐져 있음

-partially-unavailable 플래그가 설정된 경우, 모든 할당된 복제본이 완전히 최신 상태이고 건강한 경우 확인 메시지가 출력됩니다.

예시:

가상 저장소: 기본
  모든 저장소가 모든 할당된 저장소에서 완전히 이용 가능합니다!

저장소 체크섬 확인

특정 프로젝트의 저장소 체크섬을 모든 Gitaly 노드에서 확인하려면, 주요 GitLab 노드에서 복제본 Rake 작업을 실행하세요.

데이터 손실 수용

경고: accept-dataloss는 저장소의 다른 버전을 덮어쓰는 것으로 영구적인 데이터 손실을 초래합니다. 데이터를 사용하기 전에 데이터 복구 작업을 수행해야 합니다.

최신 상태의 복제본을 다시 온라인으로 가져올 수 없는 경우 데이터 손실을 수용해야 할 수 있습니다. 데이터 손실을 수용하면 Praefect는 선택한 저장소 복제본을 최신 버전으로 표시하고 다른 할당된 Gitaly 노드로 복제합니다. 이 과정에서 저장소의 다른 버전은 덮어씌워지므로 주의가 필요합니다.

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml accept-dataloss
-virtual-storage <virtual-storage> -relative-path <relative-path> -authoritative-storage <storage-name>

쓰기 활성화 또는 데이터 손실 수용

경고: accept-dataloss는 저장소의 다른 버전을 덮어쓰는 것으로 영구적인 데이터 손실을 초래합니다. 데이터를 사용하기 전에 데이터 복구 작업을 수행해야 합니다.

Praefect는 다음과 같은 하위명령을 제공하여 쓰기를 다시 활성화하거나 데이터 손실을 수용할 수 있습니다. 최신 상태의 노드 중 하나를 다시 온라인으로 가져올 수 없는 경우 데이터 손실을 수용해야 할 수 있습니다.

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml accept-dataloss -virtual-storage <virtual-storage> -relative-path <relative-path> -authoritative-storage <storage-name>

데이터 손실을 수용할 때 Praefect는 다음을 수행합니다:

  1. 선택한 복제본을 저장소의 최신 버전으로 표시합니다.
  2. 복사본을 다른 할당된 Gitaly 노드로 복제합니다.

    이 과정에서 저장소의 다른 복사본은 덮어씌워지므로 주의가 필요합니다.

데이터 복구

어떤 이유로 Gitaly 노드가 복제 작업에 실패하면 해당 저장소의 오래된 버전을 호스팅하게 됩니다. Praefect는 자동 조정을 위한 도구를 제공합니다. 이 도구들은 오래된 저장소를 완전히 최신 상태로 조정합니다.

Praefect는 최신 상태가 아닌 저장소를 자동으로 조정합니다. 기본적으로 이 작업은 5분마다 수행됩니다. 건강한 Gitaly 노드의 각 오래된 저장소에 대해 Praefect는 다른 건강한 Gitaly 노드의 완전히 최신 상태의 복제본을 무작위로 선택하여 복제합니다. 대상 저장소에 대기 중인 다른 복제 작업이 없는 경우에만 복제 작업이 예약됩니다.

조정 빈도는 구성을 통해 변경할 수 있습니다. 값은 모든 유효한 Go 상대값이 될 수 있습니다. 0 이하의 값은 기능을 비활성화합니다.

예시:

praefect['configuration'] = {
   # ...
   reconciliation: {
      # ...
      scheduling_interval: '5m', # 기본값
   },
}
praefect['configuration'] = {
   # ...
   reconciliation: {
      # ...
      scheduling_interval: '30s', # 30초마다 조정
   },
}
praefect['configuration'] = {
   # ...
   reconciliation: {
      # ...
      scheduling_interval: '0', # 기능 비활성화
   },
}

저장소 수동 제거

  • GitLab 15.3에서 소개, Praefect 추적 데이터베이스에서 저장소를 제거하는 지원이 추가되었습니다.

remove-repository Praefect 하위 명령은 저장소를 Gitaly 클러스터에서 제거하고 다음과 관련된 모든 상태를 제거합니다:

  • 모든 관련 Gitaly 노드의 온디스크 저장소
  • Praefect가 추적하는 데이터베이스 상태

명령은 기본적으로 드라이런 모드에서 작동합니다. 예를 들어:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage <virtual-storage> -relative-path <repository>
  • <virtual-storage>를 저장소를 포함하는 가상 저장소의 이름으로 대체합니다.
  • <repository>를 제거할 저장소의 상대 경로로 대체합니다.
  • GitLab 15.3 이상에서는 -db-only를 추가하여 온디스크 저장소를 제거하지 않고 Praefect 추적 데이터베이스 항목만 제거할 수 있습니다. 유효한 저장소가 실수로 지정된 경우 데이터베이스 항목을 삭제하여 온디스크 저장소 데이터를 보호할 수 있습니다. 데이터베이스 항목이 실수로 삭제된 경우 track-repository 명령을 사용하여 저장소를 다시 추적합니다.
  • 저장소를 제거하고 싶지 않은 경우 -apply를 추가하여 드라이런 모드 밖에서 명령을 실행하고 저장소를 제거할 수 있습니다. 예를 들어:

    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage <virtual-storage> -relative-path <repository> -apply
    
  • -virtual-storage는 저장소가 위치한 가상 저장소입니다. 가상 저장소는 /etc/gitlab/gitlab.rb에서 praefect['configuration']['virtual_storage]에 구성되며 다음과 같습니다:

    praefect['configuration'] = {
      # ...
      virtual_storage: [
        {
          # ...
          name: 'default',
        },
        {
          # ...
          name: 'storage-1',
        },
      ],
    }
    

    이 예에서 가상 저장소 이름은 default 또는 storage-1입니다.

  • -repository는 저장소의 해시 저장소 경로에서 시작하는 상대 경로입니다. 예:

    @hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git
    

remove-repository를 실행한 후에도 저장소의 일부 부분이 계속 존재할 수 있습니다. 이는 다음과 같은 이유 때문일 수 있습니다:

  • 삭제 오류
  • 저장소를 대상으로 한 진행 중인 RPC 호출

이럴 경우, remove-repository를 다시 실행하세요.

Praefect 추적 데이터베이스 유지 관리

Praefect 추적 데이터베이스의 일반 유지 관리 작업은 이 섹션에 문서화되어 있습니다.

추적되지 않는 저장소 목록

  • older-than 옵션은 GitLab 15.0에 추가되었습니다.

list-untracked-repositories Praefect 하위 명령은 다음을 모두 포함하는 Gitaly 클러스터의 저장소 목록을 나열합니다.

  • 적어도 한 개의 Gitaly 저장소에 존재합니다.
  • Praefect 추적 데이터베이스에서 추적되지 않습니다.

-older-than 옵션을 추가하여 다음과 같은 저장소가 표시되지 않도록합니다:

  • 생성이 진행 중인 경우
  • Praefect 추적 데이터베이스에 아직 레코드가 없는 경우

<duration>을 시간 간격으로 바꿉니다 (예: 5초, 10분, 또는 1시간). 기본값은 6시간입니다.

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml list-untracked-repositories -older-than <duration>

지정된 기간 전에 생성된 저장소만 고려됩니다.

명령은 다음을 출력합니다:

  • STDOUT에 대한 결과 및 명령의 로그
  • STDERR에 대한 오류

각 항목은 뉴라인으로 종료된 완전한 JSON 문자열입니다 (-delimiter 플래그를 사용하여 구성 가능). 예를 들어:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml list-untracked-repositories
{"virtual_storage":"default","storage":"gitaly-1","relative_path":"@hashed/ab/cd/abcd123456789012345678901234567890123456789012345678901234567890.git"}
{"virtual_storage":"default","storage":"gitaly-1","relative_path":"@hashed/ab/cd/abcd123456789012345678901234567890123456789012345678901234567891.git"}

단일 저장소를 추적 데이터베이스에 수동으로 추가

경고: 알려진 문제로 인해, Praefect 생성된 복제 경로(@cluster)로는 저장소를 Praefect 추적 데이터베이스에 추가할 수 없습니다. 이러한 저장소에는 GitLab에서 사용하는 저장소 경로와 관련이 없으며 접근할 수 없습니다.

track-repository Praefect 하위 명령은 디스크의 저장소를 Praefect 추적 데이터베이스에 추적을 위해 추가합니다.

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repository -virtual-storage <virtual-storage> -authoritative-storage <storage-name> -relative-path <repository> -replica-path <disk_path> -replicate-immediately
  • -virtual-storage는 저장소가 위치한 가상 저장소입니다. 가상 저장소는 /etc/gitlab/gitlab.rbpraefect['configuration'][:virtual_storage]에 구성되어 있으며 다음과 같습니다:

    praefect['configuration'] = {
      # ...
      virtual_storage: [
        {
          # ...
          name: 'default',
        },
        {
          # ...
          name: 'storage-1',
        },
      ],
    }
    

    이 예에서 지정할 가상 저장소는 default 또는 storage-1입니다.

  • -relative-path는 가상 저장소의 상대 경로입니다. 일반적으로 @hashed로 시작합니다. 예를 들어:

    @hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git
    
  • -replica-path는 물리적 저장소의 상대 경로입니다. @cluster로 시작하거나 relative_path와 일치할 수 있습니다.
  • -authoritative-storage는 Praefect가 기본으로 처리해야하는 저장소입니다. 저장소 당 복제가 복제 전략으로 설정된 경우 필요합니다.
  • -replicate-immediately는 명령이 저장소를 즉시 복제하도록합니다. 그렇지 않으면 복제 작업이 데이터베이스에서 실행을 예약하고 Praefect 백그라운드 프로세스에서 선택됩니다.

명령은 다음을 출력합니다:

  • 결과를 STDOUT 및 명령의 로그
  • STDERR에 대한 오류

이 명령은 다음과 같은 경우에 실패합니다:

  • 이미 Praefect 추적 데이터베이스에서 추적 중인 저장소인 경우
  • 디스크에 저장소가 존재하지 않는 경우.

다수의 저장소를 추적 데이터베이스에 수동으로 추가

경고: 알려진 문제로 인해, Praefect 생성된 복제 경로(@cluster)로는 저장소를 Praefect 추적 데이터베이스에 추가할 수 없습니다. 이러한 저장소에는 GitLab에서 사용하는 저장소 경로와 관련이 없으며 접근할 수 없습니다.

API를 사용하여 마이그레이션하는 경우 Praefect 추적 데이터베이스에 자동으로 저장소가 추가됩니다.

대신 기존 인프라에서 수동으로 저장소를 복사하는 경우 track-repositories Praefect 하위 명령을 사용할 수 있습니다. 이 하위 명령은 디스크의 대량 저장소를 Praefect 추적 데이터베이스에 추가합니다.

# Omnibus GitLab 설치
sudo gitlab-ctl praefect track-repositories --input-path /path/to/input.json

# 소스 설치
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repositories -input-path /path/to/input.json

명령은 모든 항목이 다음을 검증합니다:

  • 올바르게 서식이 지정되어 있으며 필수 필드가 포함되어 있는지 확인합니다.
  • 유효한 Git 저장소에 해당하는지 확인합니다.
  • Praefect 추적 데이터베이스에 추적되지 않는지 확인합니다.

이러한 확인을 실패하면, 저장소를 추적하기 전에 명령이 중단됩니다.

  • input-path는 개행으로 구분된 JSON 객체로 구성된 저장소 목록이 포함된 파일의 경로입니다. 객체에는 다음과 같은 키가 있어야 합니다:
    • relative_path: track-repositoryrepository와 일치하는 상대 경로입니다.
    • authoritative-storage: Praefect가 기본으로 처리해야하는 저장소입니다.
    • virtual-storage: 저장소가 위치한 가상 저장소입니다.

      예를 들어:

      {"relative_path":"@hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git","replica_path":"@cluster/fe/d3/1","authoritative_storage":"gitaly-1","virtual_storage":"default"}
      {"relative_path":"@hashed/f8/9f/f89f8d0e735a91c5269ab08d72fa27670d000e7561698d6e664e7b603f5c4e40.git","replica_path":"@cluster/7b/28/2","authoritative_storage":"gitaly-2","virtual_storage":"default"}
      
  • -replicate-immediately, 명령이 저장소를 즉시 복제하도록합니다. 그렇지 않으면 복제 작업이 데이터베이스에서 실행을 예약하고 Praefect 백그라운드 프로세스에서 선택됩니다.

가상 저장소 세부 정보 목록

list-storages Praefect 하위 명령어는 가상 저장소와 해당 저장소 노드를 나열합니다. 가상 저장소가:

  • -virtual-storage를 사용하여 지정된 경우 지정된 가상 저장소에 대한 저장소 노드만 나열합니다.
  • 지정되지 않은 경우 모든 가상 저장소와 해당 저장소 노드가 테이블 형식으로 나열됩니다.
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml list-storages -virtual-storage <virtual_storage_name>

이 명령어는 다음을 출력합니다:

  • STDOUT 및 명령의 로그에 대한 결과.
  • STDERR에 대한 오류.