Geo 복제 문제 해결

Tier: Premium, Ultimate Offering: Self-Managed

PostgreSQL 데이터베이스 복제 오류 수정

다음 섹션에서는 복제 오류 메시지를 해결하기 위한 문제 해결 단계에 대해 설명합니다(Database replication working? ... no를 나타내는 복제 오류 메시지)geo:check 출력.

지침은 대부분 단일 노드 Geo Linux 패키지 배포를 가정하고 있으며, 다른 환경에 맞게 조정해야 할 수 있습니다.

비활성 복제 슬롯 제거

복제 슬롯은 복제 클라이언트(보조 사이트)가 슬롯에 연결을 끊을 때 ‘비활성’으로 표시됩니다. 비활성 복제 슬롯은 다시 연결되면 그것으로부터 WAL 파일이 보류되어, 슬롯이 다시 활성 상태가 되면 클라이언트로 전송됩니다. 보조 사이트가 다시 연결할 수 없는 경우 해당 비활성 복제 슬롯을 제거하기 위해 다음 단계를 사용하십시오:

  1. Geo 주 사이트의 데이터베이스 노드에서 PostgreSQL 콘솔 세션을 시작합니다:

    sudo gitlab-psql -d gitlabhq_production
    

    참고: 관리 복제 슬롯에 대한 슈퍼유저 권한이 필요하기 때문에 gitlab-rails dbconsole을 사용할 수 없습니다.

  2. 복제 슬롯을 보고 비활성 상태인 경우 제거합니다:

    SELECT * FROM pg_replication_slots;
    

    activef인 슬롯은 비활성입니다.

    • 이 슬롯이 활성이어야 하는 경우에는 그 슬롯을 사용하여 보조 사이트를 구성했다면, 보조 사이트의 PostgreSQL 로그를 확인하여 복제가 실행되지 않는 이유를 확인하세요.
    • 이 슬롯을 더 이상 사용하지 않는 경우(예: 더 이상 Geo가 활성화되지 않은 경우) 또는 보조 사이트가 다시 연결할 수 없는 경우, PostgreSQL 콘솔 세션을 사용하여 제거해야 합니다:

      SELECT pg_drop_replication_slot('<name_of_inactive_slot>');
      
  3. 더 이상 필요하지 않은 경우 해당 Geo 사이트를 제거하거나, 복제 슬롯을 올바르게 다시 만드는 복제 프로세스를 다시 시작하세요.

메시지: WARNING: oldest xmin is far in the pastpg_wal 크기 증가

복제 슬롯이 비활성인 경우, 해당 슬롯에 해당하는 pg_wal 로그가 영원히 예약되어 있습니다(또는 슬롯이 다시 활성 상태가 될 때까지). 이로 인해 지속적인 디스크 사용량이 증가하고 PostgreSQL 로그에 다음과 같은 메시지가 반복적으로 나타납니다:

WARNING: oldest xmin is far in the past
HINT: Close open transactions soon to avoid wraparound problems.
You might also need to commit or roll back old prepared transactions, or drop stale replication slots.

이를 해결하려면 비활성 복제 슬롯을 제거하고 복제를 다시 시작해야 합니다.

메시지: ERROR: replication slots can only be used if max_replication_slots > 0?

이는 max_replication_slots PostgreSQL 변수가 데이터베이스에 설정되어야 한다는 것을 의미합니다. 이 설정의 기본값은 1입니다. 보조 사이트가 더 많은 경우 이 값을 증가해야 할 수 있습니다.

이 설정이 적용되려면 PostgreSQL을 다시 시작해야 합니다. 자세한 내용은 PostgreSQL 복제 설정 가이드를 참조하세요.

메시지: replication slot "geo_secondary_my_domain_com" does not exist

이 오류는 PostgreSQL에 해당 이름의 보조 사이트를 위한 복제 슬롯이 없는 경우에 발생합니다:

FATAL:  could not start WAL streaming: ERROR:  replication slot "geo_secondary_my_domain_com" does not exist

보조 사이트에서 복제 프로세스를 다시 실행할 수 있습니다.

메시지: “Command exceeded allowed execution time” when setting up replication?

이는 보조 사이트에서 복제 프로세스를 시작하는 동안 초기 데이터 집합이 기본 제한 시간(30분) 내에 복제될 수 없을 때 발생할 수 있습니다.

gitlab-ctl replicate-geo-database을 다시 실행하되, --backup-timeout에 보다 큰 값을 포함하여 설정하세요.

sudo gitlab-ctl \
   replicate-geo-database \
   --host=<primary_node_hostname> \
   --slot-name=<secondary_slot_name> \
   --backup-timeout=21600

기본 30분이 아닌 최대 6시간 동안 초기 복제를 완료하도록 하여 설정합니다. 설치에 맞게 조정하세요.

메시지: “PANIC: could not write to file pg_xlog/xlogtemp.123: No space left on device”

데이터베이스에 사용되지 않는 복제 슬롯이 있는지 확인하세요. 이로 인해 pg_xlog에 대량의 로그 데이터가 축적될 수 있습니다.

비활성 슬롯을 제거하면 pg_xlog에서 사용되는 공간을 줄일 수 있습니다.

메시지: “ERROR: canceling statement due to conflict with recovery”

이 오류 메시지는 일반적인 사용에서는 드물게 발생하며 시스템은 복구하기 위해 충분히 강인합니다.

그러나 특정 조건에서 보조 사이트의 일부 데이터베이스 쿼리가 과도하게 오래 실행될 수 있으며, 이로 인해 이 오류 메시지가 더 자주 발생할 수 있습니다. 이는 일반적으로 일부 쿼리가 모든 복제에서 취소되어 완료되지 않는 상황으로 이어질 수 있습니다.

이러한 장기 실행 쿼리는 향후 제거될 예정입니다 but as a workaround, we recommend enabling hot_standby_feedback. 이렇게 하면 사이트에서 VACUUM이 최근에 종료된 행을 제거하지 못하게 되어 이로 인한 블로핏이 발생할 가능성이 높아지지만, GitLab.com에서는 성공적으로 사용되어 왔습니다.

hot_standby_feedback을 사용하려면 보조 사이트의 /etc/gitlab/gitlab.rb에 다음을 추가하세요:

postgresql['hot_standby_feedback'] = 'on'

그런 다음 GitLab을 다시 구성하세요:

sudo gitlab-ctl reconfigure

이 문제를 해결하는 데 도움이 필요하면 이 이슈에 댓글을 남겨주세요.

### 메시지: "PostgreSQL"의 서버 인증서가 호스트 이름과 일치하지 않습니다

이 오류가 표시되면:

```plaintext
심각함:  기본 서버에 연결할 수 없음: 서버 인증서가 호스트 이름과 일치하지 않습니다

이는 리플리케이션이 다른 호스트에 연결하려고 하고 GitLab이 기본적으로 verify-full SSL 모드를 사용하려고 시도하기 때문에 발생합니다.

이 문제를 해결하려면 다음 중 하나를 수행할 수 있습니다:

  • replicate-geo-database 명령과 함께 --sslmode=verify-ca 인수를 사용합니다.
  • 이미 복제된 데이터베이스의 경우 /var/opt/gitlab/postgresql/data/gitlab-geo.conf 내의 sslmode=verify-fullsslmode=verify-ca로 변경한 후 gitlab-ctl restart postgresql을 실행합니다.
  • PostgreSQL을 위한 SSL 구성을 사용하여 호스트 이름을 포함한 사용자 정의 인증서(예: CN 또는 SAN에 사용된 호스트 이름)를 사용합니다.

메시지: 주소에서 잘못된 형식의 CIDR 마스크가 발견되었습니다

이 문제는 postgresql['md5_auth_cidr_addresses']에 잘못된 형식의 주소로 발생합니다.

2020-03-20_23:59:57.60499 LOG:  주소의 잘못된 CIDR 마스크: "***"
2020-03-20_23:59:57.60501 CONTEXT:  구성 파일 "/var/opt/gitlab/postgresql/data/pg_hba.conf"의 74번째 줄"

이를 해결하려면 /etc/gitlab/gitlab.rbpostgresql['md5_auth_cidr_addresses']에서 IP 주소를 CIDR 형식으로 업데이트하여 조정하십시오 (예: 10.0.0.1/32).

메시지: IP 마스크 “md5”이(가) 잘못된 것으로 나타남: 이름 또는 서비스를 알 수 없음

이 문제는 postgresql['md5_auth_cidr_addresses']에 서브넷 마스크 없이 IP 주소를 추가한 경우에 발생합니다.

2020-03-21_00:23:01.97353 LOG:  IP 마스크 "md5"이(가) 잘못된 것으로 나타남: 이름 또는 서비스를 알 수 없음
2020-03-21_00:23:01.97354 CONTEXT:  구성 파일 "/var/opt/gitlab/postgresql/data/pg_hba.conf"의 75번째 줄"

이를 해결하려면 /etc/gitlab/gitlab.rbpostgresql['md5_auth_cidr_addresses']에 서브넷 마스크를 추가하여 CIDR 형식을 준수하십시오 (예: 10.0.0.1/32).

메시지: gitlabhq_production 데이터베이스에서 데이터가 발견되었습니다

gitlab-ctl replicate-geo-database를 실행할 때 gitlabhq_production 데이터베이스에서 데이터가 발견되었습니다! 오류가 발생하면, projects 테이블에서 데이터가 감지된 것입니다. 하나 이상의 프로젝트가 감지되면 실수로 데이터 손실을 방지하기 위해 작업이 중단됩니다. 이 메시지를 우회하려면 명령에 --force 옵션을 전달하십시오.

메시지: 심각함: 익명의 공유 메모리를 매핑할 수 없음: 메모리를 할당할 수 없음

이 메시지가 표시되면, 이는 보조 사이트의 PostgreSQL이 사용 가능한 메모리보다 높은 메모리를 요청하려고 시도했다는 것을 의미합니다. 이 문제를 추적하는 문제가 있습니다.

Linux 패키지 설치의 경우 Patroni 로그(위치: /var/log/gitlab/patroni/current)에 있는 예시 오류 메시지:

2023-11-21_23:55:18.63727 심각함:  익명의 공유 메모리를 매핑할 수 없음: 메모리를 할당할 수 없음
2023-11-21_23:55:18.63729 힌트:  이 오류는 보통 PostgreSQL의 공유 메모리 세그먼트 요청이 사용 가능한 메모리, 스왑 공간 또는 대형 페이지를 초과한다는 것을 의미합니다. 현재 요청 크기(현재 17035526144 바이트)를 줄이려면 shared_buffers 또는 max_connections를 줄이는 등 PostgreSQL의 공유 메모리 사용량을 줄일 수 있습니다.

해결책은 보조 사이트의 PostgreSQL 노드에 사용 가능한 메모리를 증가시켜 기본 사이트의 PostgreSQL 노드의 메모리 요구 사항과 일치시키는 것입니다.

PostgreSQL 복제 실패 수정

Admin > Geo > Sites 또는 Sync status Rake task에서 복제 실패를 발견하면 다음과 같은 일반적인 단계로 실패를 해결할 수 있습니다:

  1. Geo는 실패를 자동으로 다시 시도합니다. 실패가 새로 발생했거나 그 수가 적거나 루트 원인이 이미 해결된 것으로 의심된다면, 실패가 사라지는지 기다릴 수 있습니다.
  2. 실패가 오랜 시간 동안 존재했다면 이미 많은 다시 시도가 발생했고 자동 다시 시도 간격이 실패 종류에 따라 최대 4시간까지 증가했습니다. 루트 원인이 이미 해결된 것으로 의심된다면 복제 또는 확인을 수동으로 다시 시도할 수 있습니다.
  3. 계속해서 실패가 지속되면 다음 섹션을 사용하여 해결을 시도할 수 있습니다.

복제 또는 확인을 수동으로 다시 시도

Geo 데이터 유형은 GitLab 기능 중 하나 이상에서 관련 정보를 저장하는 데 필요한 특정 데이터 유형입니다. 이러한 Geo 데이터 유형이 있습니다:

  • Blob 유형:
    • Ci::JobArtifact
    • Ci::PipelineArtifact
    • Ci::SecureFile
    • LfsObject
    • MergeRequestDiff
    • Packages::PackageFile
    • PagesDeployment
    • Terraform::StateVersion
    • Upload
    • DependencyProxy::Manifest
    • DependencyProxy::Blob
  • Git 저장소 유형:
    • DesignManagement::Repository
    • ProjectRepository
    • ProjectWikiRepository
    • SnippetRepository
    • GroupWikiRepository
  • 기타 유형:
    • ContainerRepository

주요 클래스는 레지스트리, 모델 및 복제기입니다. 이러한 클래스의 인스턴스가 있는 경우 다른 인스턴스를 가져올 수 있습니다. 레지스트리 및 모델은 주로 PostgreSQL DB 상태를 관리합니다. 복제기는 복제/확인하는 방법을 알고 있습니다(또는 서비스를 호출하여 그 작업을 수행할 수 있습니다):

model_record = Packages::PackageFile.last
model_record.replicator.registry.replicator.model_record # 이러한 메서드가 존재하는 것만 보여주는 것

이 모든 정보를 바탕으로 다음을 수행할 수 있습니다:

개별 구성 요소 다시 동기화 및 재검증

UI를 사용하여 개별 항목을 다시 동기화하고 재검증할 수 있습니다 자체 서비스 프레임워크로 관리되는 모든 구성 요소 유형에 대해 Secondary 사이트에서 Admin > Geo > Replication을 방문하세요.

그러나 이 방법이 작동하지 않으면 Rails 콘솔을 사용하여 동일한 작업을 수행할 수 있습니다. 다음 섹션에서는 레일즈 콘솔에서 내부 응용프로그램 명령을 사용하여 개별 레코드의 동기화 또는 검증을 동기적 또는 비동기적으로 유발하는 방법을 설명합니다.

경고: 데이터를 변경하는 명령은 올바르게 실행되지 않거나 올바른 조건 하에서 실행되지 않을 경우 피해를 줄 수 있습니다. 항상 먼저 테스트 환경에서 명령을 실행하고 복원할 수 있는 백업 인스턴스를 준비하세요.

레일즈 콘솔 세션을 시작합니다 아래와 같은 기본적인 문제 해결 단계를 수행하세요:

  • Blob 유형의 경우 (예: Packages::PackageFile 구성 요소 사용)

    • 동기화에 실패한 레지스트리 레코드 찾기:

      Geo::PackageFileRegistry.failed
      

      이 경우 레지스트리 레코드는 Geo 추적 데이터베이스의 레지스트리 테이블을 의미합니다. 각 레코드 또는 행은 주된 GitLab 데이터베이스에서 복제 가능한 단일 항목(예: LFS 파일 또는 프로젝트 Git 저장소)을 추적합니다. 아래는 위와 같이 질의할 수 있는 다른 Geo 레지스트리 테이블에 해당하는 레일즈 모델입니다.

      CiSecureFileRegistry
      ContainerRepositoryRegistry
      DependencyProxyBlobRegistry
      DependencyProxyManifestRegistry
      JobArtifactRegistry
      LfsObjectRegistry
      MergeRequestDiffRegistry
      PackageFileRegistry
      PagesDeploymentRegistry
      PipelineArtifactRegistry
      ProjectWikiRepositoryRegistry
      SnippetRepositoryRegistry
      TerraformStateVersionRegistry
      UploadRegistry
      
    • 주 사이트에서 누락된 레지스트리 레코드 찾기:

      Geo::PackageFileRegistry.where(last_sync_failure: 'The file is missing on the Geo primary site')
      
    • ID를 제공하여 패키지 파일을 동기적으로 다시 동기화:

      model_record = Packages::PackageFile.find(id)
      model_record.replicator.sync
      
    • 레지스트리 ID를 제공하여 패키지 파일을 동기적으로 다시 동기화:

      registry = Geo::PackageFileRegistry.find(registry_id)
      registry.replicator.sync
      
    • 레지스트리 ID를 제공하여 패키지 파일을 비동기적으로 다시 동기화합니다. GitLab 16.2부터 컴포넌트는 다음과 같이 비동기적으로 복제될 수 있습니다:

      registry = Geo::PackageFileRegistry.find(registry_id)
      registry.replicator.enqueue_sync
      
    • 레지스트리 ID를 제공하여 패키지 파일을 비동기적으로 재검증합니다. GitLab 16.2부터 컴포넌트는 다음과 같이 비동기적으로 재검증될 수 있습니다:

      registry = Geo::PackageFileRegistry.find(registry_id)
      registry.replicator.verify_async
      
  • 저장소 유형의 경우 (예: SnippetRepository 구성 요소 사용)

    • ID를 제공하여 스니펫 저장소를 동기적으로 다시 동기화:

      model_record = Geo::SnippetRepositoryRegistry.find(id)
      model_record.replicator.sync
      
    • 레지스트리 ID를 제공하여 스니펫 저장소를 동기적으로 다시 동기화:

      registry = Geo::SnippetRepositoryRegistry.find(registry_id)
      registry.replicator.sync
      
    • 레지스트리 ID를 제공하여 스니펫 저장소를 비동기적으로 다시 동기화합니다. GitLab 16.2부터 컴포넌트는 다음과 같이 비동기적으로 복제될 수 있습니다:

      registry = Geo::SnippetRepositoryRegistry.find(registry_id)
      registry.replicator.enqueue_sync
      
    • 레지스트리 ID를 제공하여 스니펫 저장소를 비동기적으로 재검증합니다. GitLab 16.2부터 컴포넌트는 다음과 같이 비동기적으로 재검증될 수 있습니다:

      registry = Geo::SnippetRepositoryRegistry.find(registry_id)
      registry.replicator.verify_async
      

다중 구성 요소 동기화 및 재검증

참고: Admin 영역 UI에 이 기능을 구현하기 위한 이슈가 있습니다.

경고: 데이터를 변경하는 명령은 올바르게 실행되지 않거나 올바른 조건 하에서 실행되지 않을 경우 피해를 줄 수 있습니다. 항상 먼저 테스트 환경에서 명령을 실행하고 복원할 수 있는 백업 인스턴스를 준비하세요.

아래 섹션에서는 레일즈 콘솔에서 내부 응용프로그램 명령을 사용하여 대량 복제 또는 검증을 유발하는 방법을 설명합니다.

모든 구성 요소(또는 검증을 지원하는 모든 SSF 데이터 유형) 다시 검증

GitLab 16.4 이전:

  1. Primary Geo 사이트의 GitLab Rails 노드에 SSH로 로그인합니다.
  2. 레일즈 콘솔을 엽니다.
  3. 모든 업로드를 대기 중인 검증으로 표시합니다:

    Upload.verification_state_table_class.each_batch do |relation|
      relation.update_all(verification_state: 0)
    
  4. 이로 인해 Primary가 모든 업로드를 체크섬하는 작업이 시작됩니다.
  5. Primary가 레코드의 체크섬을 성공적으로 체크섬하는 경우 모든 Secondary가 체크섬을 다시 계산하고 그 값을 비교합니다.

다른 SSF 데이터 유형의 경우 위의 명령에서 Upload를 원하는 모델 클래스로 바꿉니다.

Secondary에서 Blob 파일 수동으로 확인

보조 사이트에서 모든 패키지 파일을 반복하여 데이터베이스에 저장된 verification_checksum(주 사이트에서 가져옴)을 확인하고 이 값을 Secondary에서 계산하여 일치 여부를 확인합니다. 이 작업은 UI에서 아무것도 변경하지 않습니다.

# Secondary에서 실행
status = {}

Packages::PackageFile.find_each do |package_file|
  primary_checksum = package_file.verification_checksum
  secondary_checksum = Packages::PackageFile.sha256_hexdigest(package_file.file.path)
  verification_status = (primary_checksum == secondary_checksum)

  status[verification_status.to_s] ||= []
  status[verification_status.to_s] << package_file.id
end

# 받은 값의 갯수 세기
status.keys.each {|key| puts "#{key} 갯수: #{status[key].count}"}

# 전체 출력 확인
status

Primary Geo 사이트에서 업로드의 검증 실패

일부 업로드의 검증이 Primary Geo 사이트에서 verification_checksum = nilverification_failure = Error during verification: undefined method `underscore' for NilClass:Class와 같이 실패하는 경우, 이는 고아 업로드 때문일 수 있습니다. 업로드를 소유하는 상위 레코드(업로드의 모델)가 어떤 방식으로 삭제되었지만 업로드 레코드는 여전히 존재하는 경우입니다. 이러한 검증 실패는 잘못된 것입니다.

이러한 오류는 Primary Geo 사이트의 geo.log 파일에서 확인할 수 있습니다.

모델 레코드가 누락되었는지 확인하려면 Primary Geo 사이트에서 Rake 태스크를 실행할 수 있습니다:

sudo gitlab-rake gitlab:uploads:check

다음 레일즈 콘솔에서 다음 스크립트를 실행하여 이러한 실패를 제거하려면 Primary Geo 사이트에서 이 스크립트를 실행하세요:

# 검증 오류가 있는 업로드 찾기
# 또는 자신의 영향을 받는 ID로 편집
uploads = Geo::UploadState.where(
  verification_checksum: nil,
  verification_state: 3,
  verification_failure: "Error during verification: undefined method  `underscore' for NilClass:Class"
).pluck(:upload_id)

uploads_deleted = 0
begin
    uploads.each do |upload|
    u = Upload.find upload
    rescue => e
        puts "upload #{u.id} 검사 실패: #{e.message}"
      else
        uploads_deleted=uploads_deleted + 1
        p u                            ### 삭제 전 허용 검증
        # p u.destroy!                 ### 실제로 삭제하려면 주석 해제
  end
end
p "#{uploads_deleted} 원격 객체가 삭제되었습니다."

오류: Error syncing repository: 13:fatal: could not read Username

last_sync_failure 오류 Error syncing repository: 13:fatal: could not read Username for 'https://gitlab.example.com': terminal prompts disabled 에서 JWT 인증이 Geo 복제 또는 가져오기 요청 중에 실패하는 것을 나타냅니다. 더 많은 정보는 Geo (개발) > Authentication을 확인하세요.

먼저, 시스템 시계가 동기화되어 있는지 확인하세요. Health check Rake task를 실행하거나 보조 사이트의 모든 Sidekiq 노드 및 주 사이트의 모든 Puma 노드에서 수동으로 date를 확인하세요.

시스템 시계가 동기화되어 있다면, JWT 토큰이 두 개의 별도 HTTP 요청 간의 Git 가져오기 중에 만료될 수 있습니다. 모든 GitLab 버전에 존재하던 issue 464101을 확인하세요. GitLab 17.1.0, 17.0.5 및 16.11.7에서 수정될 때까지 적용되었습니다.

이 문제를 겪고 있는지 확인하려면:

  1. Rails console에서 코드를 수정하여 토큰의 유효 기간을 1분에서 10분으로 늘리세요. 보조 사이트의 Rails 콘솔에서 다음을 실행하세요:

    module Gitlab; module Geo; class BaseRequest
      private
      def geo_auth_token(message)
        signed_data = Gitlab::Geo::SignedData.new(geo_node: requesting_node, validity_period: 10.minutes).sign_and_encode_data(message)
    
        "#{GITLAB_GEO_AUTH_TOKEN_TYPE} #{signed_data}"
      end
    end;end;end
    
  2. 동일한 Rails 콘솔에서 영향받는 프로젝트를 다시 동기화하세요:

    Project.find_by_full_path('mygroup/mysubgroup/myproject').replicator.resync
    
  3. 동기화 상태 확인:

    Project.find_by_full_path('mygroup/mysubgroup/myproject').replicator.registry
    
  4. last_sync_failure에 더 이상 fatal: could not read Username 오류가 포함되어 있지 않다면, 이 문제가 발생한 것입니다. 상태는 지금 “2”이어야 하며 이는 “동기화됨”을 의미합니다. 그렇다면 수정된 GitLab 버전으로 업그레이드해야 합니다. 또한 issue 466681에 투표 또는 의견을 추가할 수 있습니다.

이 문제를 해결하려면, 보조 사이트의 모든 Sidekiq 노드에 JWT 만료 시간을 연장해야 합니다:

  1. /opt/gitlab/embedded/service/gitlab-rails/ee/lib/gitlab/geo/signed_data.rb를 편집하세요.
  2. Gitlab::Geo::SignedData.new(geo_node: requesting_node)를 찾고 validity_period: 10.minutes를 추가하세요:

    - Gitlab::Geo::SignedData.new(geo_node: requesting_node)
    + Gitlab::Geo::SignedData.new(geo_node: requesting_node, validity_period: 10.minutes)
    
  3. Sidekiq를 재시작하세요:

    sudo gitlab-ctl restart sidekiq
    
  4. 수정된 버전으로 업그레이드하지 않는 한, 이 workaround를 모든 GitLab 업그레이드 후에 반복해야 합니다.

오류: fetch remote: signal: terminated: context deadline exceeded 정확히 3시간 후에

Git 가져오기가 정확히 3시간 후에 실패하면:

  1. /etc/gitlab/gitlab.rb를 편집하여 기본 10800초에서 Git 타임아웃을 늘리세요:

    # Git 타임아웃 (초)
    gitlab_rails['gitlab_shell_git_timeout'] = 21600
    
  2. GitLab을 다시 구성하세요:

    sudo gitlab-ctl reconfigure
    

오류 Failed to open TCP connection to localhost:5000 보조에서 레지스트리 복제 구성 시

보조 사이트에서 컨테이너 레지스트리 복제를 구성하는 중 다음 오류가 발생할 수 있습니다:

Failed to open TCP connection to localhost:5000 (Connection refused - connect(2) for \"localhost\" port 5000)"

이는 컨테이너 레지스트리가 보조 사이트에서 활성화되지 않았을 경우 발생합니다. 이를 해결하려면, 컨테이너 레지스트리가 보조 사이트에서 활성화되었는지 확인하세요. 또한, Let’s Encrypt 통합이 비활성화되어 있다면 컨테이너 레지스트리도 비활성화되므로 수동으로 구성해야 합니다.

데이터베이스 복제 랙의 원인 조사

sudo gitlab-rake geo:status 명령어의 출력이 시간이 지날수록 Database replication lag가 여전히 상당히 높음을 보여주면, 데이터베이스 복제에 대한 주요 노드에서 검사할 수 있습니다. 이 값들은 write_lag, flush_lag, 및 replay_lag로 알려져 있습니다. 더 많은 정보는 공식 PostgreSQL 문서를 확인하세요.

다음 명령어를 주요 Geo 노드의 데이터베이스에서 실행하여 관련된 결과를 제공하세요:

gitlab-psql -xc 'SELECT write_lag,flush_lag,replay_lag FROM pg_stat_replication;'

-[ RECORD 1 ]---------------
write_lag  | 00:00:00.072392
flush_lag  | 00:00:00.108168
replay_lag | 00:00:00.108283

이 값 중 하나 이상이 상당히 높다면, 이는 문제를 나타낼 수 있으며 더 조사해야 합니다. 원인을 확인할 때 고려해야 할 사항은:

  • write_lag는 기본에서 보내진 WAL 바이트가 보조로 받아졌지만 아직 flush되지 않거나 적용되지 않은 시간을 나타냅니다.
  • 높은 write_lag 값은 주 및 보조 노드 간의 네트워크 성능이 저하되었거나 충분하지 않은 네트워크 속도를 나타낼 수 있습니다.
  • 높은 flush_lag 값은 보조 노드의 저장 장치에서 디스크 I/O 성능이 저하되거나 최적화되지 않았을 수 있습니다.
  • 높은 replay_lag 값은 PostgreSQL에서 긴 실행되는 트랜잭션 또는 CPU와 같은 필요한 리소스의 포화를 나타내는 경우가 있습니다.
  • write_lagflush_lag 사이의 시간 차이는 WAL 바이트가 기본 저장 시스템에 보내졌으나 아직 flush되지 않았음을 나타냅니다. 이 데이터는 아마도 영구 저장소에 완전히 작성되지 않았을 가능성이 있으며 아마도 일종의 휘발성 쓰기 캐시에 보유되어 있을 가능성이 큽니다.
  • flush_lagreplay_lag 사이의 차이는 스토리지에 성공적으로 유지된 WAL 바이트이지만 데이터베이스 시스템에서 재생되지 않았음을 나타냅니다.

Geo secondary 사이트 복제 재설정

secondary 사이트가 손상된 상태로 되어 있고 복제 상태를 처음부터 다시 시작하려면 몇 가지 단계를 수행할 수 있습니다.

  1. Sidekiq 및 Geo 로그 커서를 중지합니다.

    Sidekiq를 우아하게 중지하고 새 작업을 받지 않고 기존 작업이 처리를 완료할 때까지 기다리도록 만들 수 있습니다.

    첫 번째 단계에는 SIGTSTP 킬 신호를 보내고, 모든 작업이 완료된 후 SIGTERM을 보내야 합니다. 그렇지 않으면 gitlab-ctl stop 명령을 사용하십시오.

    gitlab-ctl status sidekiq
    # run: sidekiq: (pid 10180) <- 이것이 사용할 PID입니다
    kill -TSTP 10180 # 올바른 PID로 변경
    
    gitlab-ctl stop sidekiq
    gitlab-ctl stop geo-logcursor
    

    Sidekiq 작업 처리가 완료되었는지 확인하려면 Sidekiq 로그를 확인할 수 있습니다.

    gitlab-ctl tail sidekiq
    
  2. Gitaly/Gitaly 클러스터 데이터를 지웁니다.

    Gitaly
    mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old
    sudo gitlab-ctl reconfigure
    
    Gitaly 클러스터
    1. 선택 사항: Praefect 내부 로드 밸런서를 비활성화합니다.
    2. 각 Praefect 서버에서 Praefect를 중지합니다.

      sudo gitlab-ctl stop praefect
      
    3. Praefect 데이터베이스를 재설정합니다.

      sudo /opt/gitlab/embedded/bin/psql -U praefect -d template1 -h localhost -c "DROP DATABASE praefect_production WITH (FORCE);"
      sudo /opt/gitlab/embedded/bin/psql -U praefect -d template1 -h localhost -c "CREATE DATABASE praefect_production WITH OWNER=praefect ENCODING=UTF8;"
      
    4. 각 Gitaly 노드에서 저장소 데이터의 이름을 바꾸거나 삭제합니다.

      sudo mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old
      sudo gitlab-ctl reconfigure
      
    5. Praefect 배포 노드에서 데이터베이스를 설정하도록 reconfigure를 실행합니다.

      sudo gitlab-ctl reconfigure
      
    6. 각 Praefect 서버에서 Praefect를 시작합니다.

      sudo gitlab-ctl start praefect
      
    7. 선택 사항: 비활성화한 경우 Praefect 내부 로드 밸런서를 다시 활성화합니다.

    참고: 미래에 Secondary 사이트에서 더 이상 필요하지 않다고 확인되면 /var/opt/gitlab/git-data/repositories.old를 제거하여 디스크 공간을 절약할 수 있습니다.

  3. 선택 사항: 다른 데이터 폴더의 이름을 바꾸고 새로 만듭니다.

    경고: Primary 사이트에서 제거되었지만 secondary 사이트에는 아직 반영되지 않은 파일이 있을 수 있습니다. 이 단계를 건너 뛰면 이러한 파일이 Geo secondary 사이트에서 제거되지 않습니다.

    파일 첨부, 아바타 또는 LFS 객체와 같은 모든 업로드된 콘텐츠는 다음 경로 중 하나의 하위 폴더에 저장됩니다.

    • /var/opt/gitlab/gitlab-rails/shared
    • /var/opt/gitlab/gitlab-rails/uploads

    이들을 모두 이름을 바꾸려면:

    gitlab-ctl stop
    
    mv /var/opt/gitlab/gitlab-rails/shared /var/opt/gitlab/gitlab-rails/shared.old
    mkdir -p /var/opt/gitlab/gitlab-rails/shared
    
    mv /var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/uploads.old
    mkdir -p /var/opt/gitlab/gitlab-rails/uploads
    
    gitlab-ctl start postgresql
    gitlab-ctl start geo-postgresql
    

    폴더를 다시 생성하고 권한과 소유권이 올바른지 확인하려면 reconfigure를 실행합니다.

    gitlab-ctl reconfigure
    
  4. 추적 데이터베이스를 재설정합니다.

    경고: 선택 사항 3단계를 건너 뛴 경우 geo-postgresqlpostgresql 서비스가 실행 중인지 확인하십시오.

    gitlab-rake db:drop:geo DISABLE_DATABASE_ENVIRONMENT_CHECK=1   # secondary 앱 노드에서 실행
    gitlab-ctl reconfigure     # 추적 데이터베이스 노드에서 실행
    gitlab-rake db:migrate:geo # secondary 앱 노드에서 실행
    
  5. 이전에 중지한 서비스를 다시 시작합니다.

    gitlab-ctl start