InfoGrab Docs

Gitaly 클러스터(Praefect) 문제 해결

요약

Gitaly 클러스터(Praefect) 문제를 해결할 때 아래 정보를 참조하십시오. check Praefect 하위 명령은 Gitaly 클러스터(Praefect)의 상태를 확인하기 위한 일련의 검사를 실행합니다. Praefect가 Praefect 차트를 사용하여 배포된 경우 바이너리를 직접 실행합니다.

Gitaly 클러스터(Praefect) 문제를 해결할 때 아래 정보를 참조하십시오. Gitaly 문제 해결에 대한 정보는 Gitaly 문제 해결을 참조하십시오.

사전 요건#

관리자 액세스가 있어야 합니다.

클러스터 상태 확인#

check Praefect 하위 명령은 Gitaly 클러스터(Praefect)의 상태를 확인하기 위한 일련의 검사를 실행합니다.

gitlab-ctl praefect check

Praefect가 Praefect 차트를 사용하여 배포된 경우 바이너리를 직접 실행합니다.

/usr/local/bin/praefect check

다음 섹션에서는 실행되는 검사를 설명합니다.

Praefect 마이그레이션#

Praefect가 올바르게 작동하려면 데이터베이스 마이그레이션이 최신 상태여야 하므로 Praefect 마이그레이션이 최신 상태인지 확인합니다.

이 검사가 실패하면:

  1. 실행된 마이그레이션을 확인하기 위해 데이터베이스의 schema_migrations 테이블을 참조합니다.
  2. praefect sql-migrate를 실행하여 마이그레이션을 최신 상태로 만듭니다.

노드 연결 및 디스크 액세스#

Praefect가 모든 Gitaly 노드에 도달할 수 있는지, 그리고 각 Gitaly 노드가 모든 스토리지에 대한 읽기 및 쓰기 액세스 권한이 있는지 확인합니다.

이 검사가 실패하면:

  1. 네트워크 주소와 토큰이 올바르게 설정되어 있는지 확인합니다:
    • Praefect 구성에서.
    • 각 Gitaly 노드의 구성에서.
  2. Gitaly 노드에서 gitaly 프로세스가 git으로 실행되고 있는지 확인합니다. Gitaly가 스토리지 디렉토리에 액세스하지 못하게 하는 권한 문제가 있을 수 있습니다.
  3. Praefect를 Gitaly 노드에 연결하는 네트워크에 문제가 없는지 확인합니다.

데이터베이스 읽기 및 쓰기 액세스#

Praefect가 데이터베이스를 읽고 쓸 수 있는지 확인합니다.

이 검사가 실패하면:

  1. Praefect 데이터베이스가 복구 모드인지 확인합니다. 복구 모드에서는 테이블이 읽기 전용일 수 있습니다. 확인하려면 다음을 실행합니다:

    select pg_is_in_recovery()
    
  2. Praefect가 PostgreSQL에 연결하는 데 사용하는 사용자가 데이터베이스에 대한 읽기 및 쓰기 액세스 권한이 있는지 확인합니다.

  3. 데이터베이스가 읽기 전용 모드로 설정되었는지 확인합니다. 확인하려면 다음을 실행합니다:

    show default_transaction_read_only
    

액세스 불가능한 저장소#

프라이머리 할당이 없거나 프라이머리를 사용할 수 없어 액세스할 수 없는 저장소 수를 확인합니다.

이 검사가 실패하면:

  1. Gitaly 노드가 다운되었는지 확인합니다. 확인하려면 praefect ping-nodes를 실행합니다.
  2. Praefect 데이터베이스에 높은 부하가 있는지 확인합니다. Praefect 데이터베이스 응답이 느리면 상태 확인이 데이터베이스에 유지되지 않아 Praefect가 노드가 비정상적이라고 생각하게 됩니다.

로그에서 Praefect 오류#

오류가 발생하면 /var/log/gitlab/gitlab-rails/production.log를 확인합니다.

다음은 일반적인 오류 및 잠재적 원인입니다:

  • 500 응답 코드
    • ActionView::Template::Error (7:permission denied)
      • GitLab 서버에서 praefect['configuration'][:auth][:token]gitlab_rails['gitaly_token']이 일치하지 않습니다.
      • Sidekiq 서버에서 gitlab_rails['repositories_storages'] 스토리지 구성이 누락되어 있습니다.
    • Unable to save project. Error: 7:permission denied
      • GitLab 서버의 praefect['configuration'][:virtual_storage]에 있는 시크릿 토큰이 하나 이상의 Gitaly 서버의 gitaly['auth_token'] 값과 일치하지 않습니다.
  • 503 응답 코드
    • GRPC::Unavailable (14:failed to connect to all addresses)
      • GitLab이 Praefect에 도달할 수 없었습니다.
    • GRPC::Unavailable (14:all SubCons are in TransientFailure...)
      • Praefect가 하나 이상의 자식 Gitaly 노드에 도달할 수 없습니다. Praefect 연결 검사기를 실행하여 진단을 시도합니다.

Praefect 데이터베이스의 높은 CPU 부하#

Praefect 데이터베이스에 높은 CPU 사용률이 발생하는 일반적인 이유 중 일부:

  • 비용이 많이 드는 쿼리를 실행하는 Prometheus 메트릭 스크레이프. gitlab.rb에서 praefect['configuration'][:prometheus_exclude_database_from_default_metrics] = true를 설정합니다.
  • 읽기 분산 캐싱이 비활성화되어 사용자 트래픽이 높을 때 데이터베이스에 대한 쿼리 수가 증가합니다. 읽기 분산 캐싱이 활성화되어 있는지 확인합니다.

프라이머리 Gitaly 노드 확인#

저장소의 프라이머리 노드를 확인하려면 praefect metadata 하위 명령을 사용합니다.

저장소 메타데이터 보기#

Gitaly 클러스터(Praefect)는 클러스터에 저장된 저장소에 대한 정보가 포함된 메타데이터 데이터베이스를 유지합니다. praefect metadata 하위 명령을 사용하여 문제 해결을 위한 메타데이터를 검사합니다.

다음 중 하나로 저장소의 메타데이터를 검색할 수 있습니다:

가상 스토리지와 상대 경로로 저장소 메타데이터를 검색하려면:

  1. 오른쪽 상단에서 관리자를 선택합니다.

  2. 왼쪽 사이드바에서 개요 > 프로젝트를 선택하고 프로젝트를 선택합니다.

  3. 프로젝트의 스토리지 이름상대 경로 값을 기록합니다.

  4. 이 값을 사용하여 다음 명령을 실행합니다:

    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -virtual-storage <virtual-storage> -relative-path <relative-path>
    
Note

저장소 ID는 프로젝트 ID와 동일하지 않습니다.

Praefect 할당 저장소 ID로 저장소 메타데이터를 검색하려면:

  1. 저장소 레플리카 경로의 마지막 구성 요소를 기록합니다. 예를 들어 @cluster/repositories/6f/96/54771의 경우 저장소 ID는 54771입니다.

  2. 해당 값을 사용하여 다음 명령을 실행합니다:

    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id <repository-id>
    

예시#

가상 스토리지 default와 상대 경로 @hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git를 사용하여 저장소 메타데이터를 검색하려면:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -virtual-storage default -relative-path @hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git

Praefect 할당 저장소 ID가 1인 저장소 메타데이터를 검색하려면:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id 1

이 예시 중 어느 것도 예시 저장소의 다음 메타데이터를 검색합니다:

Repository ID: 54771
Virtual Storage: "default"
Relative Path: "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"
Replica Path: "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"
Primary: "gitaly-1"
Generation: 1
Replicas:
- Storage: "gitaly-1"
  Assigned: true
  Generation: 1, fully up to date
  Healthy: true
  Valid Primary: true
  Verified At: 2021-04-01 10:04:20 +0000 UTC
- Storage: "gitaly-2"
  Assigned: true
  Generation: 0, behind by 1 changes
  Healthy: true
  Valid Primary: false
  Verified At: unverified
- Storage: "gitaly-3"
  Assigned: true
  Generation: replica not yet created
  Healthy: false
  Valid Primary: false
  Verified At: unverified

사용 가능한 메타데이터#

praefect metadata로 검색된 메타데이터는 다음 표의 필드를 포함합니다.

필드 설명
Repository ID Praefect에 의해 저장소에 할당된 영구적인 고유 ID. GitLab이 저장소에 사용하는 ID와 다릅니다.
Virtual Storage 저장소가 저장된 가상 스토리지의 이름.
Relative Path 가상 스토리지에서 저장소의 경로.
Replica Path Gitaly 노드 디스크에서 저장소 레플리카가 저장되는 위치.
Primary 저장소의 현재 프라이머리.
Generation 저장소 변경 사항을 추적하기 위해 Praefect에서 사용됩니다. 저장소의 각 쓰기는 저장소의 세대를 증가시킵니다.
Replicas 존재하거나 존재해야 하는 레플리카 목록.

각 레플리카에 대해 다음 메타데이터를 사용할 수 있습니다:

Replicas 필드 설명
Storage 레플리카가 포함된 Gitaly 스토리지의 이름.
Assigned 레플리카가 스토리지에 존재해야 하는지 여부를 나타냅니다. Gitaly 노드가 클러스터에서 제거되거나 저장소의 복제 계수가 감소된 후 스토리지에 추가 복사본이 있는 경우 false일 수 있습니다.
Generation 레플리카의 최신 확인된 세대. 다음을 나타냅니다:

- 세대가 저장소의 세대와 일치하면 레플리카가 완전히 최신 상태입니다.
- 레플리카의 세대가 저장소의 세대보다 낮으면 레플리카가 오래된 것입니다.
- 레플리카가 스토리지에 아직 전혀 존재하지 않으면 replica not yet created입니다.
Healthy 이 레플리카를 호스팅하는 Gitaly 노드가 Praefect 노드의 합의에 의해 정상적으로 간주되는지 여부를 나타냅니다.
Valid Primary 레플리카가 프라이머리 노드로 서비스할 수 있는지 여부를 나타냅니다. 저장소의 프라이머리가 유효한 프라이머리가 아닌 경우 유효한 프라이머리인 다른 레플리카가 있으면 저장소에 대한 다음 번 쓰기 시 페일오버가 발생합니다. 레플리카가 유효한 프라이머리인 경우:

- 정상적인 Gitaly 노드에 저장되어 있습니다.
- 완전히 최신 상태입니다.
- 복제 계수 감소로 인한 보류 중인 삭제 잡의 대상이 아닙니다.
- 할당되어 있습니다.
Verified At 검증 작업자에 의한 레플리카의 마지막 성공적인 검증을 나타냅니다. 레플리카가 아직 검증되지 않은 경우 마지막 성공적인 검증 시간 대신 unverified가 표시됩니다.

'저장소를 찾을 수 없음'으로 명령 실패#

-virtual-storage에 제공된 값이 올바르지 않으면 명령은 다음 오류를 반환합니다:

get metadata: rpc error: code = NotFound desc = repository not found

문서화된 예시는 -virtual-storage default를 지정합니다. /etc/gitlab/gitlab.rb에서 Praefect 서버 설정 praefect['configuration'][:virtual_storage]를 확인합니다.

저장소가 동기화되어 있는지 확인#

일부 경우 Praefect 데이터베이스가 기본 Gitaly 노드와 동기화되지 않을 수 있습니다. 특정 저장소가 모든 노드에서 완전히 동기화되었는지 확인하려면 Rails 노드에서 gitlab:praefect:replicas Rake 작업을 실행합니다. 이 Rake 작업은 모든 Gitaly 노드에서 저장소의 체크섬을 계산합니다.

Praefect dataloss 명령은 Praefect 데이터베이스에서 저장소 상태만 확인하며 이 시나리오에서 동기화 문제를 감지하는 데 의존할 수 없습니다.

dataloss 명령에서 @failed-geo-sync 저장소가 동기화되지 않음으로 표시#

@failed-geo-sync는 GitLab 16.1 이하에서 프로젝트 동기화가 실패했을 때 Geo에서 사용한 레거시 경로로 더 이상 사용되지 않습니다.

GitLab 16.2 이상에서는 이 경로를 안전하게 삭제할 수 있습니다. @failed-geo-sync 디렉토리는 Gitaly 노드의 저장소 경로 아래에 있습니다.

관계가 존재하지 않음 오류#

기본적으로 Praefect 데이터베이스 테이블은 gitlab-ctl reconfigure 작업에 의해 자동으로 생성됩니다.

그러나 Praefect 데이터베이스 테이블은 초기 재구성 시 생성되지 않으며 다음과 같은 경우 관계가 존재하지 않는다는 오류가 발생할 수 있습니다:

  • gitlab-ctl reconfigure 명령이 실행되지 않습니다.
  • 실행 중 오류가 발생합니다.

예를 들어:

  • ERROR: relation "node_status" does not exist at character 13

  • ERROR: relation "replication_queue_lock" does not exist at character 40

  • 다음 오류:

    {"level":"error","msg":"Error updating node: pq: relation \"node_status\" does not exist","pid":210882,"praefectName":"gitlab1x4m:0.0.0.0:2305","time":"2021-04-01T19:26:19.473Z","virtual_storage":"praefect-cluster-1"}
    

이를 해결하기 위해 praefect 명령의 sql-migrate 하위 명령을 사용하여 데이터베이스 스키마 마이그레이션을 수행할 수 있습니다:

$ sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate
praefect sql-migrate: OK (applied 21 migrations)

'저장소 범위: 잘못된 저장소' 오류로 요청 실패#

이는 Praefect 구성에서 사용된 가상 스토리지 이름이 GitLab의 gitaly['configuration'][:storage][<index>][:name] 설정에서 사용된 스토리지 이름과 일치하지 않음을 나타냅니다.

Praefect와 GitLab 구성에서 사용된 가상 스토리지 이름을 일치시켜 이를 해결합니다.

클라우드 플랫폼에서 Gitaly 클러스터(Praefect) 성능 문제#

Praefect는 많은 CPU 또는 메모리가 필요하지 않으며 소형 가상 머신에서 실행할 수 있습니다. 클라우드 서비스는 디스크 IO 및 네트워크 트래픽과 같이 소형 VM이 사용할 수 있는 리소스에 다른 제한을 부과할 수 있습니다.

Praefect 노드는 많은 네트워크 트래픽을 생성합니다. 클라우드 서비스에 의해 네트워크 대역폭이 제한된 경우 다음 증상이 관찰될 수 있습니다:

  • Git 작업의 성능 저하.
  • 높은 네트워크 지연 시간.
  • Praefect의 높은 메모리 사용량.

가능한 해결책:

  • 더 큰 VM을 프로비저닝하여 더 많은 네트워크 트래픽 허용량에 액세스합니다.
  • 클라우드 서비스의 모니터링 및 로깅을 사용하여 Praefect 노드가 트래픽 허용량을 소진하지 않는지 확인합니다.

gitlab-ctl reconfigure가 Praefect 구성 오류로 실패#

gitlab-ctl reconfigure가 실패하면 다음 오류가 표시될 수 있습니다:

STDOUT: praefect: configuration error: error reading config file: toml: cannot store TOML string into a Go int

이 오류는 praefect['database_port'] 또는 praefect['database_direct_port']가 정수 대신 문자열로 구성된 경우 발생합니다.

일반적인 복제 오류#

다음은 가능한 해결책과 함께 일반적인 복제 오류입니다.

잠금 파일 존재#

잠금 파일은 동일한 ref에 대한 여러 업데이트를 방지하는 데 사용됩니다. 때로는 잠금 파일이 오래되어 복제가 error: cannot lock ref 오류와 함께 실패합니다.

오래된 *.lock 파일을 지우려면 Rails 콘솔에서 OptimizeRepositoryRequest를 트리거할 수 있습니다:

p = Project.find <Project ID>
client = Gitlab::GitalyClient::RepositoryService.new(p.repository)
client.optimize_repository

OptimizeRepositoryRequest를 트리거해도 작동하지 않으면 파일을 수동으로 검사하여 생성 날짜를 확인하고 *.lock 파일을 수동으로 제거할 수 있는지 결정합니다. 24시간 이상 전에 생성된 잠금 파일은 안전하게 제거할 수 있습니다.

Git fsck 오류#

잘못된 객체가 있는 Gitaly 저장소는 다음과 같은 Gitaly 로그 오류와 함께 복제 실패를 초래할 수 있습니다:

  • exit status 128, stderr: "fatal: git upload-pack: not our ref".
  • "fatal: bad object 58....e0f... ssh://gitaly/internal.git did not send all necessary objects.

Gitaly 노드 중 하나에 저장소의 정상적인 복사본이 있는 한 이러한 문제는 다음을 통해 수정할 수 있습니다:

  1. Praefect 데이터베이스에서 저장소 제거.
  2. Praefect track-repository 하위 명령을 사용하여 다시 추적합니다.

이렇게 하면 신뢰할 수 있는 Gitaly 노드의 저장소 복사본을 사용하여 다른 모든 Gitaly 노드의 복사본을 덮어씁니다. 이 명령을 실행하기 전에 저장소의 최근 백업이 만들어졌는지 확인합니다.

  1. 잘못된 저장소를 이동합니다:

    run `mv  .backup`
    

    예를 들어:

    mv /var/opt/gitlab/git-data/repositories/@cluster/repositories/de/74/2335 /var/opt/gitlab/git-data/repositories/@cluster/repositories/de/74/2335.backup
    
  2. 복제를 트리거하기 위한 Praefect 명령을 실행합니다:

    # Validate you have the correct repository.
    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage gitaly -relative-path '<relative_path>' -db-only
    
    # Run again with '--apply' flag to remove repository from the Praefect tracking database
    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage gitaly -relative-path '<relative_path>' -db-only --apply
    
    # Re-track the repository, overwriting the secondary nodes
    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repository -virtual-storage gitaly -authoritative-storage '<healthy_gitaly>' -relative-path '<relative_path>' -replica-path '<replica_path>'-replicate-immediately
    

복제가 자동으로 실패#

Praefect dataloss부분적으로 사용 불가능한 저장소를 표시하고 accept-dataloss 명령이 로그에 오류 없이 저장소 동기화에 실패하면 storage_repositories 테이블의 repository_id 필드에서 Praefect 데이터베이스 불일치로 인한 것일 수 있습니다. 불일치를 확인하려면:

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

  2. 다음 쿼리를 실행합니다:

    select * from storage_repositories where relative_path = '<relative-path>';
    

    <relative-path>@hashed로 시작하는 저장소 경로로 교체합니다.

대체 디렉토리가 존재하지 않음#

GitLab은 중복 제거를 위해 Git 대체 메커니즘을 사용합니다. alternates는 객체를 가져오기 위해 @pool 저장소의 objects 디렉토리를 가리키는 텍스트 파일입니다. 이 파일이 잘못된 경로를 가리키면 다음 오류 중 하나와 함께 복제가 실패할 수 있습니다:

  • "error":"no alternates directory exists", "warning","msg":"alternates file does not point to valid git repository"
  • "error":"unexpected alternates content:
  • remote: error: unable to normalize alternate object path

이 오류의 원인을 조사하려면:

  1. Rails 콘솔을 사용하여 프로젝트가 풀의 일부인지 확인합니다:

    project = Project.find_by_id(<project id>)
    project.pool_repository
    
  2. 풀 저장소 경로가 디스크에 존재하고 alternates 파일 내용과 일치하는지 확인합니다.

  3. alternates 파일의 경로가 프로젝트의 objects 디렉토리에서 도달 가능한지 확인합니다.

이러한 확인을 수행한 후 수집된 정보와 함께 GitLab 지원에 문의합니다.

실패한 저장소 스토리지 이동 후 프로젝트가 읽기 전용 상태로 고착#

Sidekiq 파드와 함께 수평 파드 자동 확장기(HPA)를 사용할 때 저장소 스토리지 이동이 파드 확장 중에 자동으로 실패할 수 있습니다. 이 문제로 인해 저장소 스토리지 이동이 실패한 경우 실패한 프로젝트가 읽기 전용 상태로 고착될 수 있습니다.

영향받은 저장소를 복구하려면:

  1. 영향받은 프로젝트를 읽기-쓰기 상태로 재설정합니다.
  2. Sidekiq 파드에 대한 HPA를 비활성화합니다.
  3. 개별 프로젝트에 대해 REST API를 사용하여 스토리지 이동을 다시 실행합니다.
  4. 마이그레이션이 완료된 후 HPA 구성을 복원합니다.

Gitaly 클러스터(Praefect) 문제 해결

Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기
요약

Gitaly 클러스터(Praefect) 문제를 해결할 때 아래 정보를 참조하십시오. check Praefect 하위 명령은 Gitaly 클러스터(Praefect)의 상태를 확인하기 위한 일련의 검사를 실행합니다. Praefect가 Praefect 차트를 사용하여 배포된 경우 바이너리를 직접 실행합니다.

Gitaly 클러스터(Praefect) 문제를 해결할 때 아래 정보를 참조하십시오. Gitaly 문제 해결에 대한 정보는 Gitaly 문제 해결을 참조하십시오.

사전 요건#

관리자 액세스가 있어야 합니다.

클러스터 상태 확인#

check Praefect 하위 명령은 Gitaly 클러스터(Praefect)의 상태를 확인하기 위한 일련의 검사를 실행합니다.

gitlab-ctl praefect check

Praefect가 Praefect 차트를 사용하여 배포된 경우 바이너리를 직접 실행합니다.

/usr/local/bin/praefect check

다음 섹션에서는 실행되는 검사를 설명합니다.

Praefect 마이그레이션#

Praefect가 올바르게 작동하려면 데이터베이스 마이그레이션이 최신 상태여야 하므로 Praefect 마이그레이션이 최신 상태인지 확인합니다.

이 검사가 실패하면:

  1. 실행된 마이그레이션을 확인하기 위해 데이터베이스의 schema_migrations 테이블을 참조합니다.
  2. praefect sql-migrate를 실행하여 마이그레이션을 최신 상태로 만듭니다.

노드 연결 및 디스크 액세스#

Praefect가 모든 Gitaly 노드에 도달할 수 있는지, 그리고 각 Gitaly 노드가 모든 스토리지에 대한 읽기 및 쓰기 액세스 권한이 있는지 확인합니다.

이 검사가 실패하면:

  1. 네트워크 주소와 토큰이 올바르게 설정되어 있는지 확인합니다:
    • Praefect 구성에서.
    • 각 Gitaly 노드의 구성에서.
  2. Gitaly 노드에서 gitaly 프로세스가 git으로 실행되고 있는지 확인합니다. Gitaly가 스토리지 디렉토리에 액세스하지 못하게 하는 권한 문제가 있을 수 있습니다.
  3. Praefect를 Gitaly 노드에 연결하는 네트워크에 문제가 없는지 확인합니다.

데이터베이스 읽기 및 쓰기 액세스#

Praefect가 데이터베이스를 읽고 쓸 수 있는지 확인합니다.

이 검사가 실패하면:

  1. Praefect 데이터베이스가 복구 모드인지 확인합니다. 복구 모드에서는 테이블이 읽기 전용일 수 있습니다. 확인하려면 다음을 실행합니다:

    select pg_is_in_recovery()
    
  2. Praefect가 PostgreSQL에 연결하는 데 사용하는 사용자가 데이터베이스에 대한 읽기 및 쓰기 액세스 권한이 있는지 확인합니다.

  3. 데이터베이스가 읽기 전용 모드로 설정되었는지 확인합니다. 확인하려면 다음을 실행합니다:

    show default_transaction_read_only
    

액세스 불가능한 저장소#

프라이머리 할당이 없거나 프라이머리를 사용할 수 없어 액세스할 수 없는 저장소 수를 확인합니다.

이 검사가 실패하면:

  1. Gitaly 노드가 다운되었는지 확인합니다. 확인하려면 praefect ping-nodes를 실행합니다.
  2. Praefect 데이터베이스에 높은 부하가 있는지 확인합니다. Praefect 데이터베이스 응답이 느리면 상태 확인이 데이터베이스에 유지되지 않아 Praefect가 노드가 비정상적이라고 생각하게 됩니다.

로그에서 Praefect 오류#

오류가 발생하면 /var/log/gitlab/gitlab-rails/production.log를 확인합니다.

다음은 일반적인 오류 및 잠재적 원인입니다:

  • 500 응답 코드
    • ActionView::Template::Error (7:permission denied)
      • GitLab 서버에서 praefect['configuration'][:auth][:token]gitlab_rails['gitaly_token']이 일치하지 않습니다.
      • Sidekiq 서버에서 gitlab_rails['repositories_storages'] 스토리지 구성이 누락되어 있습니다.
    • Unable to save project. Error: 7:permission denied
      • GitLab 서버의 praefect['configuration'][:virtual_storage]에 있는 시크릿 토큰이 하나 이상의 Gitaly 서버의 gitaly['auth_token'] 값과 일치하지 않습니다.
  • 503 응답 코드
    • GRPC::Unavailable (14:failed to connect to all addresses)
      • GitLab이 Praefect에 도달할 수 없었습니다.
    • GRPC::Unavailable (14:all SubCons are in TransientFailure...)
      • Praefect가 하나 이상의 자식 Gitaly 노드에 도달할 수 없습니다. Praefect 연결 검사기를 실행하여 진단을 시도합니다.

Praefect 데이터베이스의 높은 CPU 부하#

Praefect 데이터베이스에 높은 CPU 사용률이 발생하는 일반적인 이유 중 일부:

  • 비용이 많이 드는 쿼리를 실행하는 Prometheus 메트릭 스크레이프. gitlab.rb에서 praefect['configuration'][:prometheus_exclude_database_from_default_metrics] = true를 설정합니다.
  • 읽기 분산 캐싱이 비활성화되어 사용자 트래픽이 높을 때 데이터베이스에 대한 쿼리 수가 증가합니다. 읽기 분산 캐싱이 활성화되어 있는지 확인합니다.

프라이머리 Gitaly 노드 확인#

저장소의 프라이머리 노드를 확인하려면 praefect metadata 하위 명령을 사용합니다.

저장소 메타데이터 보기#

Gitaly 클러스터(Praefect)는 클러스터에 저장된 저장소에 대한 정보가 포함된 메타데이터 데이터베이스를 유지합니다. praefect metadata 하위 명령을 사용하여 문제 해결을 위한 메타데이터를 검사합니다.

다음 중 하나로 저장소의 메타데이터를 검색할 수 있습니다:

가상 스토리지와 상대 경로로 저장소 메타데이터를 검색하려면:

  1. 오른쪽 상단에서 관리자를 선택합니다.

  2. 왼쪽 사이드바에서 개요 > 프로젝트를 선택하고 프로젝트를 선택합니다.

  3. 프로젝트의 스토리지 이름상대 경로 값을 기록합니다.

  4. 이 값을 사용하여 다음 명령을 실행합니다:

    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -virtual-storage <virtual-storage> -relative-path <relative-path>
    
Note

저장소 ID는 프로젝트 ID와 동일하지 않습니다.

Praefect 할당 저장소 ID로 저장소 메타데이터를 검색하려면:

  1. 저장소 레플리카 경로의 마지막 구성 요소를 기록합니다. 예를 들어 @cluster/repositories/6f/96/54771의 경우 저장소 ID는 54771입니다.

  2. 해당 값을 사용하여 다음 명령을 실행합니다:

    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id <repository-id>
    

예시#

가상 스토리지 default와 상대 경로 @hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git를 사용하여 저장소 메타데이터를 검색하려면:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -virtual-storage default -relative-path @hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git

Praefect 할당 저장소 ID가 1인 저장소 메타데이터를 검색하려면:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id 1

이 예시 중 어느 것도 예시 저장소의 다음 메타데이터를 검색합니다:

Repository ID: 54771
Virtual Storage: "default"
Relative Path: "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"
Replica Path: "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"
Primary: "gitaly-1"
Generation: 1
Replicas:
- Storage: "gitaly-1"
  Assigned: true
  Generation: 1, fully up to date
  Healthy: true
  Valid Primary: true
  Verified At: 2021-04-01 10:04:20 +0000 UTC
- Storage: "gitaly-2"
  Assigned: true
  Generation: 0, behind by 1 changes
  Healthy: true
  Valid Primary: false
  Verified At: unverified
- Storage: "gitaly-3"
  Assigned: true
  Generation: replica not yet created
  Healthy: false
  Valid Primary: false
  Verified At: unverified

사용 가능한 메타데이터#

praefect metadata로 검색된 메타데이터는 다음 표의 필드를 포함합니다.

필드 설명
Repository ID Praefect에 의해 저장소에 할당된 영구적인 고유 ID. GitLab이 저장소에 사용하는 ID와 다릅니다.
Virtual Storage 저장소가 저장된 가상 스토리지의 이름.
Relative Path 가상 스토리지에서 저장소의 경로.
Replica Path Gitaly 노드 디스크에서 저장소 레플리카가 저장되는 위치.
Primary 저장소의 현재 프라이머리.
Generation 저장소 변경 사항을 추적하기 위해 Praefect에서 사용됩니다. 저장소의 각 쓰기는 저장소의 세대를 증가시킵니다.
Replicas 존재하거나 존재해야 하는 레플리카 목록.

각 레플리카에 대해 다음 메타데이터를 사용할 수 있습니다:

Replicas 필드 설명
Storage 레플리카가 포함된 Gitaly 스토리지의 이름.
Assigned 레플리카가 스토리지에 존재해야 하는지 여부를 나타냅니다. Gitaly 노드가 클러스터에서 제거되거나 저장소의 복제 계수가 감소된 후 스토리지에 추가 복사본이 있는 경우 false일 수 있습니다.
Generation 레플리카의 최신 확인된 세대. 다음을 나타냅니다:

- 세대가 저장소의 세대와 일치하면 레플리카가 완전히 최신 상태입니다.
- 레플리카의 세대가 저장소의 세대보다 낮으면 레플리카가 오래된 것입니다.
- 레플리카가 스토리지에 아직 전혀 존재하지 않으면 replica not yet created입니다.
Healthy 이 레플리카를 호스팅하는 Gitaly 노드가 Praefect 노드의 합의에 의해 정상적으로 간주되는지 여부를 나타냅니다.
Valid Primary 레플리카가 프라이머리 노드로 서비스할 수 있는지 여부를 나타냅니다. 저장소의 프라이머리가 유효한 프라이머리가 아닌 경우 유효한 프라이머리인 다른 레플리카가 있으면 저장소에 대한 다음 번 쓰기 시 페일오버가 발생합니다. 레플리카가 유효한 프라이머리인 경우:

- 정상적인 Gitaly 노드에 저장되어 있습니다.
- 완전히 최신 상태입니다.
- 복제 계수 감소로 인한 보류 중인 삭제 잡의 대상이 아닙니다.
- 할당되어 있습니다.
Verified At 검증 작업자에 의한 레플리카의 마지막 성공적인 검증을 나타냅니다. 레플리카가 아직 검증되지 않은 경우 마지막 성공적인 검증 시간 대신 unverified가 표시됩니다.

'저장소를 찾을 수 없음'으로 명령 실패#

-virtual-storage에 제공된 값이 올바르지 않으면 명령은 다음 오류를 반환합니다:

get metadata: rpc error: code = NotFound desc = repository not found

문서화된 예시는 -virtual-storage default를 지정합니다. /etc/gitlab/gitlab.rb에서 Praefect 서버 설정 praefect['configuration'][:virtual_storage]를 확인합니다.

저장소가 동기화되어 있는지 확인#

일부 경우 Praefect 데이터베이스가 기본 Gitaly 노드와 동기화되지 않을 수 있습니다. 특정 저장소가 모든 노드에서 완전히 동기화되었는지 확인하려면 Rails 노드에서 gitlab:praefect:replicas Rake 작업을 실행합니다. 이 Rake 작업은 모든 Gitaly 노드에서 저장소의 체크섬을 계산합니다.

Praefect dataloss 명령은 Praefect 데이터베이스에서 저장소 상태만 확인하며 이 시나리오에서 동기화 문제를 감지하는 데 의존할 수 없습니다.

dataloss 명령에서 @failed-geo-sync 저장소가 동기화되지 않음으로 표시#

@failed-geo-sync는 GitLab 16.1 이하에서 프로젝트 동기화가 실패했을 때 Geo에서 사용한 레거시 경로로 더 이상 사용되지 않습니다.

GitLab 16.2 이상에서는 이 경로를 안전하게 삭제할 수 있습니다. @failed-geo-sync 디렉토리는 Gitaly 노드의 저장소 경로 아래에 있습니다.

관계가 존재하지 않음 오류#

기본적으로 Praefect 데이터베이스 테이블은 gitlab-ctl reconfigure 작업에 의해 자동으로 생성됩니다.

그러나 Praefect 데이터베이스 테이블은 초기 재구성 시 생성되지 않으며 다음과 같은 경우 관계가 존재하지 않는다는 오류가 발생할 수 있습니다:

  • gitlab-ctl reconfigure 명령이 실행되지 않습니다.
  • 실행 중 오류가 발생합니다.

예를 들어:

  • ERROR: relation "node_status" does not exist at character 13

  • ERROR: relation "replication_queue_lock" does not exist at character 40

  • 다음 오류:

    {"level":"error","msg":"Error updating node: pq: relation \"node_status\" does not exist","pid":210882,"praefectName":"gitlab1x4m:0.0.0.0:2305","time":"2021-04-01T19:26:19.473Z","virtual_storage":"praefect-cluster-1"}
    

이를 해결하기 위해 praefect 명령의 sql-migrate 하위 명령을 사용하여 데이터베이스 스키마 마이그레이션을 수행할 수 있습니다:

$ sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate
praefect sql-migrate: OK (applied 21 migrations)

'저장소 범위: 잘못된 저장소' 오류로 요청 실패#

이는 Praefect 구성에서 사용된 가상 스토리지 이름이 GitLab의 gitaly['configuration'][:storage][<index>][:name] 설정에서 사용된 스토리지 이름과 일치하지 않음을 나타냅니다.

Praefect와 GitLab 구성에서 사용된 가상 스토리지 이름을 일치시켜 이를 해결합니다.

클라우드 플랫폼에서 Gitaly 클러스터(Praefect) 성능 문제#

Praefect는 많은 CPU 또는 메모리가 필요하지 않으며 소형 가상 머신에서 실행할 수 있습니다. 클라우드 서비스는 디스크 IO 및 네트워크 트래픽과 같이 소형 VM이 사용할 수 있는 리소스에 다른 제한을 부과할 수 있습니다.

Praefect 노드는 많은 네트워크 트래픽을 생성합니다. 클라우드 서비스에 의해 네트워크 대역폭이 제한된 경우 다음 증상이 관찰될 수 있습니다:

  • Git 작업의 성능 저하.
  • 높은 네트워크 지연 시간.
  • Praefect의 높은 메모리 사용량.

가능한 해결책:

  • 더 큰 VM을 프로비저닝하여 더 많은 네트워크 트래픽 허용량에 액세스합니다.
  • 클라우드 서비스의 모니터링 및 로깅을 사용하여 Praefect 노드가 트래픽 허용량을 소진하지 않는지 확인합니다.

gitlab-ctl reconfigure가 Praefect 구성 오류로 실패#

gitlab-ctl reconfigure가 실패하면 다음 오류가 표시될 수 있습니다:

STDOUT: praefect: configuration error: error reading config file: toml: cannot store TOML string into a Go int

이 오류는 praefect['database_port'] 또는 praefect['database_direct_port']가 정수 대신 문자열로 구성된 경우 발생합니다.

일반적인 복제 오류#

다음은 가능한 해결책과 함께 일반적인 복제 오류입니다.

잠금 파일 존재#

잠금 파일은 동일한 ref에 대한 여러 업데이트를 방지하는 데 사용됩니다. 때로는 잠금 파일이 오래되어 복제가 error: cannot lock ref 오류와 함께 실패합니다.

오래된 *.lock 파일을 지우려면 Rails 콘솔에서 OptimizeRepositoryRequest를 트리거할 수 있습니다:

p = Project.find <Project ID>
client = Gitlab::GitalyClient::RepositoryService.new(p.repository)
client.optimize_repository

OptimizeRepositoryRequest를 트리거해도 작동하지 않으면 파일을 수동으로 검사하여 생성 날짜를 확인하고 *.lock 파일을 수동으로 제거할 수 있는지 결정합니다. 24시간 이상 전에 생성된 잠금 파일은 안전하게 제거할 수 있습니다.

Git fsck 오류#

잘못된 객체가 있는 Gitaly 저장소는 다음과 같은 Gitaly 로그 오류와 함께 복제 실패를 초래할 수 있습니다:

  • exit status 128, stderr: "fatal: git upload-pack: not our ref".
  • "fatal: bad object 58....e0f... ssh://gitaly/internal.git did not send all necessary objects.

Gitaly 노드 중 하나에 저장소의 정상적인 복사본이 있는 한 이러한 문제는 다음을 통해 수정할 수 있습니다:

  1. Praefect 데이터베이스에서 저장소 제거.
  2. Praefect track-repository 하위 명령을 사용하여 다시 추적합니다.

이렇게 하면 신뢰할 수 있는 Gitaly 노드의 저장소 복사본을 사용하여 다른 모든 Gitaly 노드의 복사본을 덮어씁니다. 이 명령을 실행하기 전에 저장소의 최근 백업이 만들어졌는지 확인합니다.

  1. 잘못된 저장소를 이동합니다:

    run `mv  .backup`
    

    예를 들어:

    mv /var/opt/gitlab/git-data/repositories/@cluster/repositories/de/74/2335 /var/opt/gitlab/git-data/repositories/@cluster/repositories/de/74/2335.backup
    
  2. 복제를 트리거하기 위한 Praefect 명령을 실행합니다:

    # Validate you have the correct repository.
    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage gitaly -relative-path '<relative_path>' -db-only
    
    # Run again with '--apply' flag to remove repository from the Praefect tracking database
    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage gitaly -relative-path '<relative_path>' -db-only --apply
    
    # Re-track the repository, overwriting the secondary nodes
    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repository -virtual-storage gitaly -authoritative-storage '<healthy_gitaly>' -relative-path '<relative_path>' -replica-path '<replica_path>'-replicate-immediately
    

복제가 자동으로 실패#

Praefect dataloss부분적으로 사용 불가능한 저장소를 표시하고 accept-dataloss 명령이 로그에 오류 없이 저장소 동기화에 실패하면 storage_repositories 테이블의 repository_id 필드에서 Praefect 데이터베이스 불일치로 인한 것일 수 있습니다. 불일치를 확인하려면:

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

  2. 다음 쿼리를 실행합니다:

    select * from storage_repositories where relative_path = '<relative-path>';
    

    <relative-path>@hashed로 시작하는 저장소 경로로 교체합니다.

대체 디렉토리가 존재하지 않음#

GitLab은 중복 제거를 위해 Git 대체 메커니즘을 사용합니다. alternates는 객체를 가져오기 위해 @pool 저장소의 objects 디렉토리를 가리키는 텍스트 파일입니다. 이 파일이 잘못된 경로를 가리키면 다음 오류 중 하나와 함께 복제가 실패할 수 있습니다:

  • "error":"no alternates directory exists", "warning","msg":"alternates file does not point to valid git repository"
  • "error":"unexpected alternates content:
  • remote: error: unable to normalize alternate object path

이 오류의 원인을 조사하려면:

  1. Rails 콘솔을 사용하여 프로젝트가 풀의 일부인지 확인합니다:

    project = Project.find_by_id(<project id>)
    project.pool_repository
    
  2. 풀 저장소 경로가 디스크에 존재하고 alternates 파일 내용과 일치하는지 확인합니다.

  3. alternates 파일의 경로가 프로젝트의 objects 디렉토리에서 도달 가능한지 확인합니다.

이러한 확인을 수행한 후 수집된 정보와 함께 GitLab 지원에 문의합니다.

실패한 저장소 스토리지 이동 후 프로젝트가 읽기 전용 상태로 고착#

Sidekiq 파드와 함께 수평 파드 자동 확장기(HPA)를 사용할 때 저장소 스토리지 이동이 파드 확장 중에 자동으로 실패할 수 있습니다. 이 문제로 인해 저장소 스토리지 이동이 실패한 경우 실패한 프로젝트가 읽기 전용 상태로 고착될 수 있습니다.

영향받은 저장소를 복구하려면:

  1. 영향받은 프로젝트를 읽기-쓰기 상태로 재설정합니다.
  2. Sidekiq 파드에 대한 HPA를 비활성화합니다.
  3. 개별 프로젝트에 대해 REST API를 사용하여 스토리지 이동을 다시 실행합니다.
  4. 마이그레이션이 완료된 후 HPA 구성을 복원합니다.