Geo PostgreSQL 복제 문제 해결
Offering: GitLab Self-Managed
다음 섹션에서는 복제 오류 메시지를 수정하기 위한 문제 해결 단계를 설명합니다(geo:check 출력에서 Database replication working? 복제 슬롯에 연결된 복제 클라이언트(보조 사이트)가 연결을 끊으면 복제 슬롯이 '비활성'으로 표시됩니다.
다음 섹션에서는 복제 오류 메시지를 수정하기 위한 문제 해결 단계를 설명합니다(geo:check 출력에서 Database replication working? ... no로 표시).
여기에 제시된 지침은 대부분 단일 노드 Geo Linux 패키지 배포를 가정하며 다른 환경에 맞게 조정이
필요할 수 있습니다.
비활성 복제 슬롯 제거#
복제 슬롯에 연결된 복제 클라이언트(보조 사이트)가 연결을 끊으면 복제 슬롯이 '비활성'으로 표시됩니다. 비활성 복제 슬롯은 클라이언트가 다시 연결할 때 전송되고 슬롯이 다시 활성화되기 때문에 WAL 파일이 보존됩니다. 보조 사이트가 다시 연결할 수 없는 경우 다음 단계를 사용하여 해당 비활성 복제 슬롯을 제거합니다:
-
Geo 기본 사이트의 데이터베이스 노드에서 PostgreSQL 콘솔 세션을 시작합니다:
sudo gitlab-psql -d gitlabhq_production[!note] 복제 슬롯 관리에는 슈퍼유저 권한이 필요하므로
gitlab-rails dbconsole을 사용하는 것은 작동하지 않습니다. -
복제 슬롯을 확인하고 비활성 상태인 경우 제거합니다:
SELECT * FROM pg_replication_slots;active가f인 슬롯은 비활성 상태입니다.
-
해당 슬롯을 사용하여 보조 사이트가 구성되어 있어서 이 슬롯이 활성화되어야 하는 경우:
-
보조 사이트의 PostgreSQL 로그에서 복제가 실행되지 않는 이유를 확인합니다.
-
보조 사이트가 더 이상 다시 연결할 수 없는 경우:
-
PostgreSQL 콘솔 세션을 사용하여 슬롯을 제거합니다:
SELECT pg_drop_replication_slot('<name_of_inactive_slot>'); -
복제 프로세스를 다시 시작하면 복제 슬롯이 올바르게 재생성됩니다.
-
-
-
슬롯을 더 이상 사용하지 않는 경우(예: Geo가 더 이상 활성화되어 있지 않은 경우) 해당 Geo 사이트를 제거하는 단계를 따르세요.
메시지: WARNING: oldest xmin is far in the past 및 pg_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?#
이는 보조 사이트에서 복제 프로세스를 시작할 때 발생할 수 있으며, 초기 데이터세트가 너무 커서 기본 타임아웃(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#
이 오류 메시지는 일반적인 사용에서 가끔 발생하며, 시스템이 충분히 복원력이 있어 복구됩니다.
그러나 특정 조건에서 보조 사이트의 일부 데이터베이스 쿼리가 과도하게 오래 실행되어 이 오류 메시지의 빈도가 높아질 수 있습니다. 이로 인해 모든 복제에서 취소되어 일부 쿼리가 완료되지 않는 상황이 발생할 수 있습니다.
이러한 장기 실행 쿼리는 향후 제거 예정이지만
해결 방법으로
hot_standby_feedback을
활성화하는 것을 권장합니다. 이렇게 하면 VACUUM이 최근 삭제된 행을 제거하지 못하므로
기본 사이트에서 팽창(bloat)이 발생할 가능성이 높아집니다. 그러나 GitLab.com에서 프로덕션
환경에서 성공적으로 사용되었습니다.
보조 사이트에서 /etc/gitlab/gitlab.rb에 다음을 추가하여 hot_standby_feedback을 활성화합니다:
postgresql['hot_standby_feedback'] = 'on'
그런 다음 GitLab을 재구성합니다:
sudo gitlab-ctl reconfigure
이 문제를 해결하는 데 도움을 주려면 이슈에 댓글을 달아 주세요.
메시지: server certificate for "PostgreSQL" does not match host name#
이 오류가 표시되는 경우:
FATAL: could not connect to the primary server: server certificate for "PostgreSQL" does not match host name
이 오류는 Linux 패키지가 자동으로 생성하는 PostgreSQL 인증서에는 공통 이름(Common Name)
PostgreSQL이 포함되어 있지만 복제가 다른 호스트에 연결하고 GitLab이 기본적으로 verify-full
SSL 모드를 사용하려고 시도하기 때문에 발생합니다.
이 문제를 수정하려면 다음 중 하나를 수행합니다:
replicate-geo-database명령에--sslmode=verify-ca인수를 사용합니다.- 이미 복제된 데이터베이스의 경우
/var/opt/gitlab/postgresql/data/gitlab-geo.conf에서sslmode=verify-full을sslmode=verify-ca로 변경하고gitlab-ctl restart postgresql을 실행합니다. - 자동으로 생성된 인증서 대신 사용자 지정 인증서(CN 또는 SAN에 데이터베이스 연결에 사용되는 호스트 이름 포함)로 PostgreSQL에 SSL 구성을 사용합니다.
메시지: LOG: invalid CIDR mask in address#
이 오류는 postgresql['md5_auth_cidr_addresses']에서 잘못 형식화된 주소가 있을 때 발생합니다.
2020-03-20_23:59:57.60499 LOG: invalid CIDR mask in address "***"
2020-03-20_23:59:57.60501 CONTEXT: line 74 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"
이를 수정하려면 /etc/gitlab/gitlab.rb의 postgresql['md5_auth_cidr_addresses'] 아래에 있는
IP 주소를 CIDR 형식(예: 10.0.0.1/32)으로 업데이트합니다.
메시지: LOG: invalid IP mask "md5": Name or service not known#
이 오류는 postgresql['md5_auth_cidr_addresses']에 서브넷 마스크 없이 IP 주소를 추가한 경우
발생합니다.
2020-03-21_00:23:01.97353 LOG: invalid IP mask "md5": Name or service not known
2020-03-21_00:23:01.97354 CONTEXT: line 75 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"
이를 수정하려면 /etc/gitlab/gitlab.rb의 postgresql['md5_auth_cidr_addresses'] 아래에
CIDR 형식(예: 10.0.0.1/32)으로 서브넷 마스크를 추가합니다.
메시지: Found data in the gitlabhq_production database#
gitlab-ctl replicate-geo-database를 실행할 때 Found data in the gitlabhq_production database!
오류가 발생하면 projects 테이블에서 데이터가 감지된 것입니다. 하나 이상의 프로젝트가 감지되면
우발적인 데이터 손실을 방지하기 위해 작업이 중단됩니다. 이 메시지를 무시하려면 명령에
--force 옵션을 전달합니다.
메시지: FATAL: could not map anonymous shared memory: Cannot allocate memory#
이 메시지가 표시되면 보조 사이트의 PostgreSQL이 사용 가능한 메모리보다 높은 메모리를 요청하려고 시도한다는 것을 의미합니다. 이 문제를 추적하는 이슈가 있습니다.
Patroni 로그의 예시 오류 메시지(Linux 패키지 설치의 경우 /var/log/gitlab/patroni/current에 위치):
2023-11-21_23:55:18.63727 FATAL: could not map anonymous shared memory: Cannot allocate memory
2023-11-21_23:55:18.63729 HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 17035526144 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
해결 방법은 보조 사이트의 PostgreSQL 노드에서 사용 가능한 메모리를 기본 사이트의 PostgreSQL 노드의 메모리 요구사항과 일치하도록 늘리는 것입니다.
메시지: could not open certificate file "/root/.postgresql/postgresql.crt"#
이 오류가 표시되는 경우:
sql: error: connection to server at "x.x.x.x", port 5432 failed:
could not open certificate file "/root/.postgresql/postgresql.crt": Permission denied...
이 오류는 psql 또는 libpq를 사용하는 애플리케이션과 같은 PostgreSQL 클라이언트가
/root/.postgresql/postgresql.crt와 같은 특정 기본 위치에서 클라이언트 SSL 인증서를 찾기
때문에 발생합니다. 그러나 이 오류 메시지는 오해를 유발할 수 있습니다. GitLab 복제기 사용자에
대한 잘못된 비밀번호 사용과 같은 다른 이유로 인증이 실패할 때 자주 나타납니다. SSL 인증서
문제를 해결하기 전에 먼저 인증 자격 증명이 올바른지 확인합니다.
데이터베이스 복제 지연 원인 조사#
sudo gitlab-rake gitlab: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 바이트가 전송된 후 보조 사이트에서 수신되었지만 아직 플러시되거나 적용되지 않은 시간을 나타냅니다.write_lag값이 높으면 기본 노드와 보조 노드 간의 네트워크 성능 저하 또는 불충분한 네트워크 속도를 나타낼 수 있습니다.flush_lag값이 높으면 보조 노드의 스토리지 장치에서 저하되거나 최적화되지 않은 디스크 I/O 성능을 나타낼 수 있습니다.replay_lag값이 높으면 PostgreSQL에서 장기 실행 트랜잭션이나 CPU와 같은 필요한 리소스의 포화를 나타낼 수 있습니다.write_lag와flush_lag사이의 시간 차이는 WAL 바이트가 기본 스토리지 시스템으로 전송 되었지만 플러시되었다고 보고하지 않았음을 나타냅니다. 이 데이터는 영구 스토리지에 완전히 기록되지 않았을 가능성이 높으며 일종의 휘발성 쓰기 캐시에 보관되어 있을 수 있습니다.flush_lag와replay_lag사이의 차이는 스토리지에 성공적으로 지속된 WAL 바이트이지만 데이터베이스 시스템에서 재생할 수 없는 것을 나타냅니다.
Message: pg_basebackup: initiating base backup, waiting for checkpoint to complete에서 중단#
초기 복제가 Message: pg_basebackup: initiating base backup, waiting for checkpoint to complete에서
중단되면 기본 Geo 사이트가 활발하게 사용되지 않고 있음을 의미합니다. 이는 주로 비프로덕션
GitLab 서버 또는 새로 설치된 GitLab에서 발생합니다.
해결 방법은 일부 데이터베이스 쓰기를 유발하는 것입니다. 예를 들어 기본 사이트에 로그인하여 일부 이슈와 댓글을 생성할 수 있습니다.
다른 해결 방법은 기본 사이트의 데이터베이스에서 SQL 쿼리 CHECKPOINT;를 실행하는 것입니다:
sudo gitlab-psql -xc 'CHECKPOINT;'
