Linux 패키지 설치를 위한 PostgreSQL 복제 및 장애 조치 문제 해결

Tier: 프리미엄, 얼티메이트 Offering: Self-managed

PostgreSQL 복제 및 장애 조치 시 다음과 같은 문제가 발생할 수 있습니다.

Consul 및 PostgreSQL 변경 사항이 적용되지 않음

잠재적인 영향으로 인해 gitlab-ctl reconfigure는 Consul과 PostgreSQL을 다시 로드하지만 서비스를 재시작하지는 않습니다. 그러나 모든 변경 사항을 다시 로드로 활성화할 수 없습니다.

하나의 서비스를 재시작하려면 gitlab-ctl restart SERVICE을(를) 실행합니다.

PostgreSQL의 경우, 일반적으로 리더 노드를 기본값으로 재시작하는 것이 안전합니다. 자동 장애 조치는 1분 제한 시간으로 기본값으로 설정됩니다. 데이터베이스가 해당 시간 이전에 반환되면 다른 작업을 수행할 필요가 없습니다.

Consul 서버 노드에서는 중요합니다. Consul 서비스를 제어된 방식으로 다시 시작해야 합니다.

PgBouncer 오류 ERROR: pgbouncer cannot connect to server

gitlab-rake gitlab:db:configure를 실행하거나 PgBouncer 로그 파일에서 해당 오류를 볼 수 있습니다.

PG::ConnectionBad: ERROR:  pgbouncer cannot connect to server

문제는 PgBouncer 노드의 IP 주소가 데이터베이스 노드의 /etc/gitlab/gitlab.rb에 있는 trust_auth_cidr_addresses 설정에 포함되지 않은 것일 수 있습니다.

이 문제를 해결하려면 /etc/gitlab/gitlab.rb에 IP 주소를 추가합니다.

postgresql['trust_auth_cidr_addresses'] = %w(123.123.123.123/32 <other_cidrs>)

변경 사항이 적용되려면 GitLab을 다시 구성해야 합니다.

PgBouncer 오류 Error running command: GitlabCtl::Errors::ExecutionErrorERROR: database gitlabhq_production is not paused

GitLab 16.5.0 이전 버전에 영향을 주는 알려진 이슈로 인해 PgBouncer 노드의 자동 장애 조치가 Patroni switchover 후에 발생하지 않을 수 있습니다. 이 예에서는 GitLab이 일시 중지된 데이터베이스를 감지하지 못하고 일시 중단되지 않은 데이터베이스를 RESUME하려고 시도했습니다.

INFO -- : Running: gitlab-ctl pgb-notify --pg-database gitlabhq_production --newhost database7.example.com --user pgbouncer --hostuser gitlab-consul
ERROR -- : STDERR: Error running command: GitlabCtl::Errors::ExecutionError
ERROR -- : STDERR: ERROR: ERROR:  database gitlabhq_production is not paused

Patroni switchover가 성공하도록 하려면 모든 PgBouncer 노드에서 다음 명령을 사용하여 PgBouncer 서비스를 수동으로 다시 시작해야 합니다.

gitlab-ctl restart pgbouncer

복제본 다시 초기화

복제본이 시작되지 않거나 클러스터에 다시 참가하지 못하거나 뒤처지고 따라잡을 수 없는 경우 복제본을 다시 초기화해야 할 수 있습니다.

  1. 복제 상태 확인를(을) 통해 다시 초기화해야 할 서버를 확인합니다. 예를 들어:

    + Cluster: postgresql-ha (6970678148837286213) ------+---------+--------------+----+-----------+
    | Member                              | Host         | Role    | State        | TL | Lag in MB |
    +-------------------------------------+--------------+---------+--------------+----+-----------+
    | gitlab-database-1.example.com       | 172.18.0.111 | 복제본  | 실행 중     | 55 |         0 |
    | gitlab-database-2.example.com       | 172.18.0.112 | 복제본  | 시작 실패   |    |   알 수 없음 |
    | gitlab-database-3.example.com       | 172.18.0.113 | 리더    | 실행 중     | 55 |           |
    +-------------------------------------+--------------+---------+--------------+----+-----------+
    
  2. 손상된 서버에 로그인하여 데이터베이스와 복제를 다시 초기화합니다. Patroni는 해당 서버에서 PostgreSQL을 종료하고 데이터 디렉토리를 제거한 다음 처음부터 다시 초기화합니다:

    sudo gitlab-ctl patroni reinitialize-replica --member gitlab-database-2.example.com
    

    이 작업은 어느 Patroni 노드에서든 실행할 수 있지만 sudo gitlab-ctl patroni reinitialize-replica--member 없이 사용하면 실행 중인 서버를 다시 시작합니다. 이렇게 하면 의도하지 않은 데이터 손실의 위험을 줄이기 위해 손상된 서버에서 로컬로 실행해야 합니다.

  3. 로그를 모니터링합니다:

    sudo gitlab-ctl tail patroni
    

Patroni 상태를 Consul에서 재설정

경고: Consul에서 Patroni 상태를 재설정하는 것은 잠재적으로 파괴적인 프로세스입니다. 먼저 건강한 데이터베이스 백업이 있는지 확인하세요.

마지간 수단으로, Consul에서 Patroni 상태를 완전히 재설정할 수 있습니다.

이것은 Patroni 클러스터가 알 수 없거나 나쁜 상태에 있고 어떤 노드도 시작할 수 없는 경우에 필요할 수 있습니다:

+ Cluster: postgresql-ha (6970678148837286213) ------+---------+---------+----+-----------+
| Member                              | Host         | Role    | State   | TL | Lag in MB |
+-------------------------------------+--------------+---------+---------+----+-----------+
| gitlab-database-1.example.com       | 172.18.0.111 | Replica | stopped |    |   unknown |
| gitlab-database-2.example.com       | 172.18.0.112 | Replica | stopped |    |   unknown |
| gitlab-database-3.example.com       | 172.18.0.113 | Replica | stopped |    |   unknown |
+-------------------------------------+--------------+---------+---------+----+-----------+

Consul에서 Patroni 상태를 삭제하기 전에, Patroni 노드에서 gitlab-ctl 오류를 해결해 보세요.

이 프로세스는 첫 번째 Patroni 노드가 시작될 때 재설정된 Patroni 클러스터로 결과가 나타납니다.

Consul에서 Patroni 상태를 재설정하려면:

  1. 지도록하십시오. Patroni 노드 중에서 리더였거나 애플리케이션이 현재 리더로 생각하는 노드:
    • /var/opt/gitlab/consul/databases.ini의 PgBouncer 노드를 확인하십시오. 이곳에 현재 리더의 호스트명이 포함되어 있습니다.
    • 클러스터에서 가장 최근에 리더로 식별된 서버를 확인하기 위해 모든 데이터베이스 노드의 Patroni 로그 /var/log/gitlab/patroni/current (또는 이전에 로테이션되고 압축된 로그 /var/log/gitlab/patroni/@40000*)를 확인하십시오.

      INFO: no action. I am a secondary (database1.local) and following a leader (database2.local)
      
  2. 모든 노드에서 Patroni를 중지합니다:

    sudo gitlab-ctl stop patroni
    
  3. Consul에서 상태를 재설정합니다:

    /opt/gitlab/embedded/bin/consul kv delete -recurse /service/postgresql-ha/
    
  4. Patroni 클러스터를 리더로 선출하도록 하는 하나의 Patroni 노드를 시작합니다. 가능하면 (첫 번째 단계에서 표시된 리더) 이전 리더를 시작하는 것이 매우 권장되며, 그래야만 복구되지 않은 기존 쓰기들을 잃지 않을 수 있습니다.
    • 복구되지 않은 쓰기들로 인해 복구되지 못했을 수도 있는 존재하는 쓰기들을 잃지 않게 하기 위해 이전 리더를 시작하는 것이 매우 권장됩니다.
    sudo gitlab-ctl start patroni
    
  5. 나머지 Patroni 노드를 시작하여 Patroni 클러스터에 레플리카로 참여하도록 합니다:

    sudo gitlab-ctl start patroni
    

여전히 문제가 있는 경우, 다음 단계는 마지막 건강한 백업을 복원하는 것입니다.

Patroni 로그에 ‘127.0.0.1’에 대한 ‘pg_hba.conf’ 항목 오류

Patroni 로그에 있는 다음과 같은 로그 항목은 복제가 작동하지 않고 구성 변경이 필요함을 나타냅니다:

FATAL:  no pg_hba.conf entry for replication connection from host "127.0.0.1", user "gitlab_replicator"

문제를 해결하려면 루프백 인터페이스가 CIDR 주소 목록에 포함되어 있는지 확인하세요:

  1. /etc/gitlab/gitlab.rb를 편집합니다:

    postgresql['trust_auth_cidr_addresses'] = %w(<other_cidrs> 127.0.0.1/32)
    
  2. 변경 사항이 적용되게 하려면 GitLab을 다시 구성합니다.
  3. 모든 레플리카가 동기화되었는지 확인합니다.

Patroni 로그에 있는 ‘요청된 시작 지점이 Write Ahead Log (WAL) 플러시 위치를 앞서고 있음’ 오류

이 오류는 데이터베이스가 복제되지 않았음을 나타냅니다:

FATAL:  could not receive data from WAL stream: ERROR:  requested starting point 0/5000000 is ahead of the WAL flush position of this server 0/4000388

이 예제 오류는 초기에 잘못 구성된 레플리카에서 나온 것으로, 한 번도 복제되지 않았습니다.

레플리카를 다시 초기화하여 문제를 해결합니다.

Patroni가 ‘MemoryError’와 함께 시작하지 못하는 문제

Patroni가 시작되지 못하고 오류 및 스택 트레이스를 기록할 수 있습니다:

MemoryError
Traceback (most recent call last):
  File "/opt/gitlab/embedded/bin/patroni", line 8, in <module>
    sys.exit(main())
[..]
  File "/opt/gitlab/embedded/lib/python3.7/ctypes/__init__.py", line 273, in _reset_cache
    CFUNCTYPE(c_int)(lambda: None)

스택 트레이스가 CFUNCTYPE(c_int)(lambda: None)로 끝난다면, 이 코드는 Linux 서버가 보안을 위해 강화되었다면 MemoryError를 트리거합니다.

해결책: - /tmp/var/tmp과 같은 파일 시스템의 마운트 옵션에서 noexec를 제거하십시오. - SELinux가 강제 적용된 경우, 이러한 작업을 방지할 수 있습니다. SELinux를 퍼미시브로 설정하여 문제가 해결되었는지 확인하십시오.

Patroni는 GitLab 13.1용 Linux 패키지와 함께 처음으로 제공되었으며, Python 3.7 빌드와 함께 제공되었습니다. 이 문제를 유발하는 코드는 Python 3.8에서 제거되었습니다. 이 수정은 GitLab 14.3용 Linux 패키지와 이후에 제공되어, 워크어라운드가 필요하지 않게 되었습니다.

gitlab-ctl 실행 중 오류가 발생하는 경우

Patroni 노드는 gitlab-ctl 명령이 실패하고 gitlab-ctl reconfigure로 노드를 수정할 수 없는 상태가 될 수 있습니다.

이것이 PostgreSQL 버전 업그레이드와 일치하는 경우에는 다른 절차를 따르세요

한 가지 흔한 증상은 데이터베이스 서버가 시작되지 않으면 gitlab-ctl이 설치에 필요한 정보를 결정할 수 없는 것입니다:

/opt/gitlab/embedded/nodes/<HOSTNAME>.json에서 발견된 구성 JSON 파일이 잘못되었습니다.
이는 일반적으로 마지막 `gitlab-ctl reconfigure` 실행이 성공적으로 완료되지 않았을 때 발생합니다.
현재 노드에서 레플리카를 다시 초기화하는 중 오류: /opt/gitlab/embedded/nodes/<HOSTNAME>.json에서 속성을 찾을 수 없습니다. reconfigure가 이미 실행되었나요?

이와 유사하게, 노드 파일(/opt/gitlab/embedded/nodes/<HOSTNAME>.json)은 많은 정보를 포함해야 하지만, 아래와 같이 생성될 수 있습니다:

{
  "name": "<HOSTNAME>"
}

이를 수정하기 위한 다음 프로세스에는 이 레플리카를 다시 초기화하는 과정이 포함되어 있습니다: 현재 PostgreSQL 상태를 해당 노드에서 삭제합니다:

  1. Patroni 및 (있는 경우) PostgreSQL 서비스를 종료합니다:

    sudo gitlab-ctl status
    sudo gitlab-ctl stop patroni
    sudo gitlab-ctl stop postgresql
    
  2. PostgreSQL이 시작되지 않도록 /var/opt/gitlab/postgresql/data를 제거합니다.

    cd /var/opt/gitlab/postgresql
    sudo rm -rf data
    

    이 단계를 주의해서 진행하여 데이터 손실을 방지하십시오. 이 작업은 data/ 이름을 바꾸어 수행할 수도 있습니다: 기본 데이터베이스의 새 복사본을 위해 충분한 디스크 여유 공간이 있는지 확인하고, 레플리카가 수정되면 추가 디렉터리를 제거하십시오.

  3. PostgreSQL이 실행되지 않을 때, 노드 파일은 이제 성공적으로 생성됩니다:

    sudo gitlab-ctl reconfigure
    
  4. Patroni를 시작합니다:

    sudo gitlab-ctl start patroni
    
  5. 로그를 모니터하고 클러스터 상태를 확인합니다:

    sudo gitlab-ctl tail patroni
    sudo gitlab-ctl patroni members
    
  6. 다시 reconfigure를 실행합니다:

    sudo gitlab-ctl reconfigure
    
  7. gitlab-ctl patroni members가 이를 필요로 하는지 표시하는 경우, 레플리카를 다시 초기화합니다:

    sudo gitlab-ctl patroni reinitialize-replica
    

이 절차가 작동하지 않거나 클러스터가 리더를 선출하지 못하는 경우에는 마지막 수단으로 사용해야 할 다른 수정이 있습니다.

Patroni 레플리카에서 PostgreSQL 주 버전 업그레이드가 실패하는 경우

Patroni 레플리카gitlab-ctl pg-upgrade 중에 루프에 갇힐 수 있으며 업그레이드에 실패할 수 있습니다.

다음은 예시 증상 집합입니다:

  1. postgresql 서비스가 정의되어 있으며, 일반적으로 Patroni 노드에는 존재해서는 안되지만, gitlab-ctl pg-upgrade가 새로운 빈 데이터베이스를 만들기 위해 이를 추가했기 때문에 존재합니다:

    run: patroni: (pid 1972) 1919초; run: log: (pid 1971) 1919초
    down: postgresql: 1초, 정상적으로 실행됨, 실행됨 원함; run: log: (pid 1973) 1919초
    
  2. PostgreSQL이 /var/opt/gitlab/postgresql/data를 다시 초기화하는 일환으로 제거하면서, /var/log/gitlab/postgresql/currentPANIC 로그 항목이 생성됩니다:

    DETAIL:  파일 "pg_xact/0000"을 열 수 없습니다: 파일 또는 디렉터리가 없습니다.
    WARNING:  다른 서버 프로세스의 충돌로 연결을 종료합니다
    LOG:  모든 서버 프로세스가 종료됨; 다시 초기화 중
    PANIC:  파일 "global/pg_control"을 열 수 없습니다: 파일 또는 디렉터리가 없습니다
    
  3. /var/log/gitlab/patroni/current에 다음과 같이 로깅됩니다. 지역 PostgreSQL 버전이 클러스터 리더와 다릅니다:

    INFO: 리더 'HOSTNAME'에서 부트스트랩을 시도합니다
    pg_basebackup: 호환되지 않는 서버 버전 12.6
    pg_basebackup: 데이터 디렉토리 "/var/opt/gitlab/postgresql/data"를 제거하는 중
    ERROR: 백업 검색 중 오류 발생: pg_basebackup가 코드=1로 종료되었습니다
    

중요: 본 해결책은 Patroni 클러스터가 다음 상태인 경우에 적용됩니다:

본 해결책은 Patroni 레플리카에서 PostgreSQL 업그레이드를 완료시켜줍니다. 그 새로운 PostgreSQL 버전을 사용하도록 노드를 설정하고, 리더가 업그레이드될 때 생성된 새 클러스터에서 레플리카로서 다시 초기화합니다:

  1. 리더가 어디인지 확인하고 레플리카가 어떤 상태인지 확인하기 위해 모든 노드에서 클러스터 상태를 확인하세요

    sudo gitlab-ctl patroni members
    
  2. 레플리카: 활성 PostgreSQL 버전이 무엇인지 확인하세요:

    sudo ls -al /opt/gitlab/embedded/bin | grep postgres
    
  3. 레플리카: 레플리카에서 어떠한 gitlab-ctl도 실행할 수 없거나 레플리카가 이러한 오류를 가지고 있다면 gitlab-ctl을 실행하는 중 오류가 발생하는 경우를 확인하고 수정해주세요:

    sudo gitlab-ctl stop patroni
    sudo gitlab-ctl reconfigure
    
  4. 레플리카: 호환되지 않는 서버 버전 오류를 수정하기 위해 PostgreSQL 바이너리를 필요로 하는 버전으로 다시 링크하세요:

    1. /etc/gitlab/gitlab.rb를 편집하고 필요한 버전을 지정하세요:

      postgresql['version'] = 13
      
    2. GitLab을 재구성하세요:

      sudo gitlab-ctl reconfigure
      
    3. 바이너리가 다시 링크되었는지 확인하세요. 주요 릴리스 간에 배포된 바이너리는 다양하며, 일반적으로 일부 잘못된 심볼릭 링크가 있을 수 있습니다:

      sudo ls -al /opt/gitlab/embedded/bin | grep postgres
      
  5. 레플리카: 지정된 버전으로 PostgreSQL이 완전히 다시 초기화되었는지 확인하세요:

    cd /var/opt/gitlab/postgresql
    sudo rm -rf data
    sudo gitlab-ctl reconfigure
    
  6. 레플리카: 필요한 경우 데이터베이스를 두 가지 추가 터미널 세션에서 모니터링합니다:

    • pg_basebackup를 실행하는 동안 디스크 사용량이 증가합니다. 초기화 상황을 추적하려면 다음 명령어로 진행 상황을 확인하세요:

      cd /var/opt/gitlab/postgresql
      watch du -sh data
      
    • 로그에서 프로세스를 모니터링합니다:

      sudo gitlab-ctl tail patroni
      
  7. 레플리카: 레플리카를 다시 초기화하기 위해 Patroni를 시작하세요:

    sudo gitlab-ctl start patroni
    
  8. 레플리카: 완료되면 /etc/gitlab/gitlab.rb에서 하드코딩된 버전을 제거하세요:

    1. /etc/gitlab/gitlab.rb를 편집하고 postgresql['version']를 제거하세요.
    2. GitLab을 다시 구성하세요:

      sudo gitlab-ctl reconfigure
      
    3. 올바른 바이너리가 링크되었는지 확인하세요:

      sudo ls -al /opt/gitlab/embedded/bin | grep postgres
      
  9. 모든 노드에서 클러스터 상태를 확인하세요:

    sudo gitlab-ctl patroni members
    

필요한 경우 다른 레플리카에서 이 절차를 반복하세요.

다른 구성 요소의 문제점

만약 여기에 기술되지 않은 다른 구성 요소에 문제가 발생한다면, 반드시 해당 문서 페이지의 troubleshooting 섹션을 확인해보세요: