- 클러스터 상태 확인
- Praefect 로그의 오류
- Praefect 데이터베이스의 높은 CPU 로드
- 주요 Gitaly 노드 결정하기
- 저장소 메타데이터 보기
- 저장소가 동기화되어 있는지 확인하기
- 관계가 존재하지 않는 오류
- 요청이 ‘repository scoped: invalid Repository’ 오류로 실패합니다
- 클라우드 플랫폼에서 Gitaly 클러스터 성능 문제
gitlab-ctl reconfigure
가 Praefect 구성 오류로 실패합니다- 일반적인 복제 오류
Gitaly 클러스터 문제 해결
Gitaly 클러스터(Praefect)를 문제 해결할 때 아래 정보를 참조하세요. Gitaly 문제 해결에 대한 정보는 Gitaly 문제 해결을 참고하세요.
클러스터 상태 확인
check
Praefect 서브 커맨드는 Gitaly 클러스터의 건강 상태를 확인하기 위해 일련의 검사를 실행합니다.
gitlab-ctl praefect check
Praefect 차트를 사용하여 배포된 경우, 바이너리를 직접 실행하세요.
/usr/local/bin/praefect check
다음 섹션에서는 실행되는 검사를 설명합니다.
Praefect 마이그레이션
데이터베이스 마이그레이션이 Praefect가 올바르게 작동하기 위해 최신 상태여야 하므로, Praefect 마이그레이션이 최신 상태인지 확인합니다.
이 검사에 실패할 경우:
- 데이터베이스의
schema_migrations
테이블을 확인하여 어떤 마이그레이션이 실행되었는지 확인합니다. -
praefect sql-migrate
를 실행하여 마이그레이션을 최신 상태로 업데이트합니다.
노드 연결성 및 디스크 접근
Praefect가 모든 Gitaly 노드에 연결할 수 있는지, 각 Gitaly 노드가 모든 저장소에 읽기 및 쓰기 접근이 가능한지 확인합니다.
이 검사에 실패할 경우:
- 네트워크 주소 및 토큰이 정확하게 설정되었는지 확인합니다:
- Praefect 구성에서.
- 각 Gitaly 노드의 구성에서.
- Gitaly 노드에서
gitaly
프로세스가git
으로 실행되고 있는지 확인합니다. Gitaly가 저장소 디렉토리에 접근하지 못하게 하는 권한 문제일 수 있습니다. - Praefect와 Gitaly 노드를 연결하는 네트워크에 문제가 없는지 확인합니다.
데이터베이스 읽기 및 쓰기 접근
Praefect가 데이터베이스에서 읽고 쓸 수 있는지 확인합니다.
이 검사에 실패할 경우:
-
Praefect 데이터베이스가 복구 모드인지 확인합니다. 복구 모드에서는 테이블이 읽기 전용이 될 수 있습니다. 확인하려면 다음을 실행합니다:
select pg_is_in_recovery()
- Praefect가 PostgreSQL에 연결할 때 사용하는 사용자가 데이터베이스에 읽기 및 쓰기 접근이 있는지 확인합니다.
-
데이터베이스가 읽기 전용 모드로 설정되어 있는지 확인합니다. 확인하려면 다음을 실행합니다:
show default_transaction_read_only
접근 불가능한 저장소
기본 할당이 없거나 기본이 사용 불가능하여 접근할 수 없는 저장소의 수를 확인합니다.
이 검사에 실패할 경우:
- Gitaly 노드 중 어떤 것이 다운되어 있는지 확인합니다.
praefect ping-nodes
를 실행하여 확인합니다. - Praefect 데이터베이스에 부하가 큰지 확인합니다. Praefect 데이터베이스의 응답이 느리면, 데이터베이스에 상태 확인이 지속되지 않아 Praefect가 노드가 건강하지 않다고 판단할 수 있습니다.
시계 동기화 확인
Praefect와 Gitaly 서버 간의 인증은 서버 시간이 서로 60초 이내에 있어야 하며, 이로 인해 토큰 확인이 성공할 수 있습니다.
이 검사는 permission denied
의 근본 원인을 식별하는 데 도움이 됩니다
Praefect에서 기록된 오류.
공식 NTP 서버인 pool.ntp.org
에 접근할 수 없는 오프라인 환경의 경우, Praefect check
서브 커맨드는 다음과 유사한 오류 메시지로 검사에 실패합니다:
checking with NTP service at and allowed clock drift 60000ms [correlation_id: <XXX>]
Failed (fatal) error: gitaly node at tcp://[gitlab.example-instance.com]:8075: rpc error: code = DeadlineExceeded desc = context deadline exceeded
이 문제를 해결하려면, 모든 Praefect 서버에서 접근할 수 있는 내부 Network Time Protocol (NTP) 서버를 가리키도록 환경 변수를 설정합니다. 예를 들어:
export NTP_HOST=ntp.example.com
Praefect 로그의 오류
오류가 발생하면 /var/log/gitlab/gitlab-rails/production.log
를 확인하세요.
다음은 일반적인 오류와 잠재적인 원인입니다:
- 500 응답 코드
-
ActionView::Template::Error (7:permission denied)
-
praefect['configuration'][:auth][:token]
과gitlab_rails['gitaly_token']
이 GitLab 서버에서 일치하지 않습니다. -
git_data_dirs
저장소 구성이 Sidekiq 서버에 없습니다.
-
-
Unable to save project. Error: 7:permission denied
- GitLab 서버의
praefect['configuration'][:virtual_storage]
에 있는 비밀 토큰이 하나 이상의 Gitaly 서버의gitaly['auth_token']
값과 일치하지 않습니다.
- GitLab 서버의
-
- 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 metadata
하위 명령어를 사용하세요.
Praefect가 할당한 저장소 ID로 저장소의 메타데이터를 검색할 수 있습니다:
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id <repository-id>
물리적 저장소의 경로가 @cluster
로 시작하면
물리적 경로에서 저장소 ID 찾기를 참조하세요.
가상 저장소와 상대 경로로도 저장소의 메타데이터를 검색할 수 있습니다:
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -virtual-storage <virtual-storage> -relative-path <relative-path>
예시
Praefect가 할당한 저장소 ID가 1인 저장소의 메타데이터를 검색하려면:
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id 1
가상 저장소가 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
이 예시 중 하나는 다음과 같은 메타데이터를 반환합니다:
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 |
저장소의 현재 기본(primary). |
Generation |
Praefect가 저장소 변경 사항을 추적하는 데 사용됨. 저장소 내의 각 기록은 저장소의 세대를 증가시킵니다. |
Replicas |
존재하거나 존재할 것으로 예상되는 복제본의 목록. |
각 복제본에 대해 다음 메타데이터를 사용할 수 있습니다:
Replicas 필드 |
설명 |
---|---|
Storage |
복제본을 포함하는 Gitaly 스토리지의 이름. |
Assigned |
복제본이 스토리지에 존재할 것으로 예상되는지 여부. Gitaly 노드가 클러스터에서 제거되거나 저장소의 복제 인수가 감소한 후 추가 복사본이 포함된 경우 false 일 수 있습니다. |
Generation |
복제본의 최신 확인 세대. 다음을 나타냅니다: - 세대가 저장소의 세대와 일치하면 복제본이 완전히 최신 상태입니다. - 복제본의 세대가 저장소의 세대보다 작으면 복제본이 구식입니다. - 복제본이 스토리지에 아직 생성되지 않은 경우 replica not yet created 입니다. |
Healthy |
이 복제본을 호스팅하는 Gitaly 노드가 Praefect 노드의 합의에 의해 건강하다고 간주되는지 여부. |
Valid Primary |
복제본이 기본 노드로서 적합한지 여부. 저장소의 기본이 유효한 기본이 아닌 경우, 다른 복제본이 유효한 기본이 있는 경우 다음 저장소 기록에서 장애 조치가 발생합니다. 복제본이 유효한 기본이면: - 건강한 Gitaly 노드에 저장됩니다. - 완전히 최신 상태입니다. - 복제 인수를 줄이는 작업에 의해 삭제 대기 중인 항목이 아닙니다. - 할당되었습니다. |
Verified At |
복제본을 검증 작업자에 의해 마지막으로 성공적으로 검증한 시간을 나타냅니다. 복제본이 아직 검증되지 않은 경우, 마지막 성공적인 검증 시간 대신 unverified 가 표시됩니다. GitLab 15.0에서 도입되었습니다. |
명령이 ‘repository not found’로 실패함
-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)
요청이 ‘repository scoped: invalid Repository’ 오류로 실패합니다
이는 Praefect 구성에서 사용된 가상 저장소 이름이
GitLab의 gitaly['configuration'][:storage][<index>][:name]
설정에서 사용된 저장소 이름과 일치하지 않음을 나타냅니다.
이 문제를 해결하려면 Praefect와 GitLab 구성에서 사용된 가상 저장소 이름을 일치시켜야 합니다.
클라우드 플랫폼에서 Gitaly 클러스터 성능 문제
Praefect는 많은 CPU 또는 메모리를 요구하지 않으며, 작은 가상 머신에서도 실행할 수 있습니다.
클라우드 서비스는 작은 VM이 사용할 수 있는 리소스에 대해 디스크 IO 및 네트워크 트래픽과 같은 추가 제한을 둘 수 있습니다.
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']
가 정수가 아닌 문자열로 구성된 경우 발생합니다.
일반적인 복제 오류
다음은 몇 가지 일반적인 복제 오류와 가능한 해결책입니다.
잠금 파일 존재
잠금 파일은 동일한 참조에 대한 여러 업데이트를 방지하기 위해 사용됩니다. 때때로 잠금 파일이 오래되어 Replication이 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 노드 중 하나가 여전히 정상적인 리포지토리의 복사본을 보유하고 있는 한, 이러한 문제는 다음과 같이 해결할 수 있습니다:
- Praefect 데이터베이스에서 리포지토리 제거.
-
Praefect
track-repository
서브커맨드를 사용하여 다시 추적합니다.
이 작업은 권위 있는 Gitaly 노드의 리포지토리 복사본을 사용하여 모든 다른 Gitaly 노드의 복사본을 덮어씁니다.
이러한 명령을 실행하기 전에 리포지토리의 최근 백업이 생성되었는지 확인하십시오.
-
잘못된 리포지토리를 이동합니다:
run `mv <REPOSITORY_PATH> <REPOSITORY_PATH>.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
-
복제를 트리거하기 위해 Praefect 명령을 실행합니다:
# 올바른 리포지토리가 있는지 확인하십시오. 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 # Praefect 추적 데이터베이스에서 리포지토리를 제거하기 위해 '--apply' 플래그로 다시 실행합니다. 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 # 리포지토리를 다시 추적하고 보조 노드를 덮어씁니다. 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 데이터베이스의 불일치로 인해 발생할 수 있습니다. 불일치를 확인하려면:
- Praefect 데이터베이스에 연결합니다.
-
다음 쿼리를 실행합니다:
select * from storage_repositories where relative_path = '<relative-path>';
<relative-path>
를@hashed
로 시작하는 리포지토리 경로로 교체하십시오.
대체 디렉토리가 존재하지 않음
GitLab은 Git alternates 메커니즘을 사용하여 중복 제거를 수행합니다. 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
이 오류의 원인을 조사하려면:
-
Rails 콘솔을 사용하여 프로젝트가 풀의 일부인지 확인하세요:
project = Project.find_by_id(<project id>) project.pool_repository
- 풀 저장소 경로가 디스크에 존재하는지 확인하고 대체(
alternates
) 파일 내용과 일치하는지 확인하세요. - 프로젝트의
objects
디렉토리에서alternates
파일의 경로에 접근할 수 있는지 확인하세요.
이러한 점검을 수행한 후, 수집한 정보를 가지고 GitLab 지원팀에 문의하세요.