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


Tier: Premium, Ultimate
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.rbtrust_auth_cidr_addresses 설정에 포함되지 않은 경우입니다.

데이터베이스 노드의 PostgreSQL 로그를 확인하여 이 문제가 있는지 확인할 수 있습니다. 다음과 같은 오류가 표시되는 경우 trust_auth_cidr_addresses가 문제이므로 확인할 수 있습니다.

2018-03-29_13:59:12.11776 FATAL:  no pg_hba.conf entry for host "123.123.123.123", user "pgbouncer", database "gitlabhq_production", SSL off

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

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

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

Patroni 스위트오버 후 PgBouncer 노드가 장애 조치되지 않음

GitLab 16.5.0 이전 버전에 영향을 미치는 알려진 이슈로 인해 Patroni 스위트오버 후 PgBouncer 노드의 자동 장애 조치가 발생하지 않을 수 있습니다. 이 예에서 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 스위트오버를 보장하기 위해 PgBouncer 노드의 서비스를 수동으로 다시 시작해야 합니다. shell 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 | Replica | running      | 55 |         0 |
    | gitlab-database-2.example.com       | 172.18.0.112 | Replica | start failed |    |   unknown |
    | gitlab-database-3.example.com       | 172.18.0.113 | Leader  | running      | 55 |           |
    +-------------------------------------+--------------+---------+--------------+----+-----------+
    
  2. 손상된 서버에 로그인하여 데이터베이스와 복제를 재초기화합니다. Patroni는 해당 서버에서 PostgreSQL을 중지하고 데이터 디렉터리를 제거한 후 처음부터 다시 초기화합니다.

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

    이 명령을 실행할 수 있지만, sudo gitlab-ctl patroni reinitialize-replica--member 없이 실행하면 실행 중인 서버를 다시 시작합니다. 의도치 않은 데이터 손실 위험을 줄이기 위해 손상된 서버에서 로컬로 실행해야 합니다.

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

    sudo gitlab-ctl tail patroni
    

Consul에서 Patroni 상태 재설정

경고:
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 노드를 복제로 클러스터에 가입합니다.

    sudo gitlab-ctl start patroni
    

만약 문제가 계속되는 경우 다음 단계는 마지막으로 안전한 백업을 복원하는 것입니다.

pg_hba.conf127.0.0.1 항목에 대한 Patroni 로그 오류

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. 모든 복제본이 동기화되었는지 확인

오류: 요청된 시작 지점이 Write Ahead Log(WAL) 플러시 위치 앞에 있음

Patroni 로그의 이 오류는 데이터베이스가 복제되지 않는 것을 나타냅니다:

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를 유발합니다.

이 코드는 Python이 임시 실행 파일을 작성하도록 유도하는데, 이를 수행할 파일 시스템을 찾을 수 없는 경우, 예를 들어 /tmp 파일 시스템에 noexec가 설정된 경우 MemoryError가 발생합니다 (이슈에서 더 읽기).

gitlab-ctl 실행 중 오류 발생

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

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

gitlab-ctl가 데이터베이스 서버 시작에 실패하는 경우 필요한 정보를 결정할 수 없습니다:

Malformed configuration JSON file found at /opt/gitlab/embedded/nodes/<HOSTNAME>.json.
This usually happens when your last run of `gitlab-ctl reconfigure` didn't complete successfully.
Error while reinitializing replica on the current node: Attributes not found in
/opt/gitlab/embedded/nodes/<HOSTNAME>.json, has reconfigure been run yet?

비슷하게, 노드 파일(/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) 1919s; run: log: (pid 1971) 1919s
    down: postgresql: 1s, normally up, want up; run: log: (pid 1973) 1919s
    
  2. PostgreSQL은 레플리카를 다시 초기화하는 일환으로 /var/opt/gitlab/postgresql/data를 제거하는 동안 /var/log/gitlab/postgresql/currentPANIC 로그 항목을 생성합니다:

    DETAIL:  Could not open file "pg_xact/0000": No such file or directory.
    WARNING:  terminating connection because of crash of another server process
    LOG:  all server processes terminated; reinitializing
    PANIC:  could not open file "global/pg_control": No such file or directory
    
  3. /var/log/gitlab/patroni/current에서 Patroni는 다음과 같은 항목을 기록합니다. 로컬 PostgreSQL 버전이 클러스터 리더와 다릅니다:

    INFO: trying to bootstrap from leader 'HOSTNAME'
    pg_basebackup: incompatible server version 12.6
    pg_basebackup: removing data directory "/var/opt/gitlab/postgresql/data"
    ERROR: Error when fetching backup: pg_basebackup exited with code=1
    

중요: 본 해결책은 다음 상태일 때 적용됩니다:

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

  1. 모든 노드에서 클러스터 상태를 확인하여 리더 및 레플리카의 상태를 확인하세요

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

    sudo ls -al /opt/gitlab/embedded/bin | grep postgres
    
  3. 레플리카: 노드 파일이 올바르며 gitlab-ctl을 실행할 수 있는지 확인합니다. 레플리카에 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. 올바른 이진 파일이 연결되었는지 확인하세요. PostgreSQL의 배포된 이진 파일은 주요 릴리스 간에 다를 수 있으며, 일반적으로 일부 잘못된 심볼릭 링크가 있습니다:

      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에서 hardcoded된 버전을 제거하세요:

    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
    

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

기타 구성 요소의 문제점

만약 여기에 기술되지 않은 구성 요소에 문제가 발생한다면, 해당 문제에 대한 해결 방법을 확인해 보기 위해 특정 문서 페이지의 문제 해결 부분을 확인해주세요: