PostgreSQL
GitLab v19.5Offering: GitLab Self-Managed
요약
이 페이지는 GitLab 지원팀이 문제 해결 시 사용하는 PostgreSQL 관련 정보를 담고 있습니다. 여기에 문서화된 일부 절차는 GitLab 인스턴스를 손상시킬 수 있습니다. 유료 티어를 사용 중이고 이러한 명령의 사용법이 확실하지 않다면, 겪고 있는 문제에 관한 지원을 받기 위해 지원팀에 문의합니다.
이 페이지는 GitLab 지원팀이 문제 해결 시 사용하는 PostgreSQL 관련 정보를 담고 있습니다. GitLab은 지원팀이 축적한 지식을 누구나 활용할 수 있도록 이 정보를 공개합니다.
여기에 문서화된 일부 절차는 GitLab 인스턴스를 손상시킬 수 있습니다. 사용에 따른 위험은 사용자가 감수합니다.
유료 티어를 사용 중이고 이러한 명령의 사용법이 확실하지 않다면, 겪고 있는 문제에 관한 지원을 받기 위해 지원팀에 문의합니다.
데이터베이스 콘솔 시작#
다음 경우에 권장됩니다:
- 단일 노드 인스턴스.
- 스케일 아웃 또는 하이브리드 환경의 Patroni 노드(일반적으로 리더).
- 스케일 아웃 또는 하이브리드 환경에서 PostgreSQL 서비스를 실행하는 서버.
sudo gitlab-psql
단일 노드 인스턴스나 웹 또는 Sidekiq 노드에서는 Rails 데이터베이스 콘솔도 사용할 수 있지만, 초기화에 시간이 더 걸립니다:
sudo gitlab-rails dbconsole --database main
docker exec -it <container-id> gitlab-psql
PostgreSQL 설치에 포함된 psql 명령을 사용합니다.
sudo -u git -H psql -d gitlabhq_production
- 하이브리드 환경을 실행하고 PostgreSQL이 Linux 패키지 설치(Omnibus)에서 실행 중이라면, 권장 방식은 해당 서버에서 로컬로 데이터베이스 콘솔을 사용하는 것입니다. Linux 패키지 항목의 세부 정보를 참고합니다.
- 외부 서드파티 PostgreSQL 서비스에 포함된 콘솔을 사용합니다.
- 툴박스 Pod에서
gitlab-rails dbconsole을 실행합니다.- 자세한 내용은 Kubernetes 치트 시트를 참고합니다.
관리형 PostgreSQL 서비스(예: AWS RDS)를 사용하는 클라우드 네이티브 배포에서는 데이터베이스 구성 파일을 직접 수정할 수 없습니다. 대신 클라우드 서비스의 파라미터 그룹 또는 구성 인터페이스를 통해 PostgreSQL 파라미터를 구성합니다.
콘솔을 종료하려면 quit을 입력합니다.
기타 GitLab PostgreSQL 문서#
이 섹션은 GitLab 문서의 다른 곳에 있는 정보로 연결되는 링크를 제공합니다.
절차#
- Linux 패키지 설치를 위한 데이터베이스 절차. 포함 항목:
- SSL: 활성화, 비활성화 및 검증.
- Write Ahead Log(WAL) 아카이빙 활성화.
- 외부(비 Omnibus) PostgreSQL 설치 사용 및 백업.
- 소켓과 함께 또는 소켓 대신 TCP/IP로 수신 대기.
- 다른 위치에 데이터 저장.
- GitLab 데이터베이스의 파괴적 재시드.
- 패키지로 제공되는 PostgreSQL 업데이트에 관한 지침(자동 업데이트를 중지하는 방법 포함).
- 외부 PostgreSQL 정보.
- 외부 PostgreSQL로 Geo 실행.
- HA용으로 구성된 PostgreSQL을 실행할 때의 업그레이드.
- CI 러너 내부에서 PostgreSQL 사용.
- Linux 패키지 개발 문서에 있는 Linux 패키지 설치의 PostgreSQL 버전 관리 방법.
- PostgreSQL 스케일링
gitlab-ctl patroni check-leader와 PgBouncer 오류에 관한 문제 해결 포함.
- 개발자 데이터베이스 문서. 그중 일부는 프로덕션 용도로는 결코 사용할 수
없습니다. 포함 항목:
- EXPLAIN 계획 이해.
지원 주제#
데이터베이스 데드락#
참고:
- 인스턴스에 푸시가 몰리면 데드락이 발생할 수 있습니다. GitLab 코드가 흔치 않은 상황에서 이런 종류의 예상치 못한 영향을 미칠 수 있다는 컨텍스트를 제공합니다.
ERROR: deadlock detected
이슈 #30528에서 적용 가능한 타임아웃 세 가지가 확인되었으며, 권장 설정은 다음과 같습니다:
deadlock_timeout = 5s
statement_timeout = 15s
idle_in_transaction_session_timeout = 60s
이슈 #30528에서 인용합니다:
"데드락이 발생했을 때 짧은 시간 후 트랜잭션을 중단해 해결하면, 이미 갖춰 둔 재시도 메커니즘이 데드락된 작업을 다시 시도하게 되고, 여러 번 연속으로 데드락이 발생할 가능성은 낮습니다."
지원팀에서 타임아웃을 재구성하는 일반적인 접근 방식(HTTP 스택에도 동일하게 적용됩니다)은, 임시 해결책으로 일시적으로 조정하는 것은 허용된다는 것입니다. 그렇게 해서 고객이 GitLab을 사용할 수 있게 된다면, 문제를 더 온전히 파악하고 핫픽스를 적용하거나 근본 원인을 해소하는 다른 변경을 적용할 시간을 벌 수 있습니다. 일반적으로 근본 원인이 해결된 뒤에는 타임아웃을 적절한 기본값으로 되돌려야 합니다.
이 경우 개발팀에서 받은 지침은 deadlock_timeout 또는 statement_timeout을 줄이되
세 번째 설정은 60초로 두라는 것이었습니다. idle_in_transaction을 설정하면 세션이
며칠씩 멈춰 있는 상황에서 데이터베이스를 보호합니다. GitLab.com에 이 타임아웃을 도입하는 이슈에
더 많은 논의가 있습니다.
PostgreSQL 기본값:
statement_timeout = 0(제한 없음)idle_in_transaction_session_timeout = 0(제한 없음)
이슈 #30528의 댓글에 따르면
모든 Linux 패키지 설치에서 이 두 값은 최소 몇 분 단위로 설정해야 합니다
(무한정 멈추지 않도록 하기 위해서입니다). 다만 statement_timeout의 15초는
매우 짧으며, 기반 인프라의 성능이 매우 뛰어난 경우에만
효과가 있습니다.
현재 설정은 다음으로 확인합니다:
sudo gitlab-rails runner "c = ApplicationRecord.connection ; puts c.execute('SHOW statement_timeout').to_a ;
puts c.execute('SHOW deadlock_timeout').to_a ;
puts c.execute('SHOW idle_in_transaction_session_timeout').to_a ;"
응답에 시간이 조금 걸릴 수 있습니다.
{"statement_timeout"=>"1min"}
{"deadlock_timeout"=>"0"}
{"idle_in_transaction_session_timeout"=>"1min"}
이 설정은 /etc/gitlab/gitlab.rb에서 다음과 같이 업데이트할 수 있습니다:
postgresql['deadlock_timeout'] = '5s'
postgresql['statement_timeout'] = '15s'
postgresql['idle_in_transaction_session_timeout'] = '60s'
저장한 뒤 변경 사항이 적용되도록 GitLab을 재구성합니다.
이 값들은 Linux 패키지 설정입니다. 고객의 PostgreSQL 설치나 Amazon RDS 같은 외부 데이터베이스를 사용하는 경우 이 값은 설정되지 않으므로 외부에서 설정해야 합니다.
statement timeout 임시 변경#
PgBouncer가 활성화된 경우에는 다음 조언이 적용되지 않습니다. 변경된 타임아웃이 의도한 것보다 많은 트랜잭션에 영향을 줄 수 있기 때문입니다.
일부 상황에서는 GitLab을 재구성하지 않고 다른 statement timeout을 설정하는 편이 나을 수 있습니다. 이 경우 재구성은 Puma와 Sidekiq를 재시작하기 때문입니다.
예를 들어 statement timeout이 너무 짧으면 백업 명령의 출력에 다음과 같은 오류가 나타나면서 백업이 실패할 수 있습니다:
pg_dump: error: Error message from server: server closed the connection unexpectedly
PostgreSQL 로그에서도 오류가 나타날 수 있습니다:
canceling statement due to statement timeout
Linux 패키지 설치의 경우#
statement timeout을 임시로 변경하려면:
-
편집기에서
/var/opt/gitlab/gitlab-rails/etc/database.yml을 엽니다. -
statement_timeout값을0으로 설정합니다. 이 값은 statement timeout을 무제한으로 설정합니다. -
새 Rails 콘솔 세션에서 이 값이 사용되는지 확인합니다:
sudo gitlab-rails runner "ActiveRecord::Base.connection_db_config[:variables]" -
다른 타임아웃이 필요한 작업을 수행합니다 (예: 백업 또는 Rails 명령).
-
/var/opt/gitlab/gitlab-rails/etc/database.yml의 편집 내용을 되돌립니다.
클라우드 네이티브 배포의 경우#
관리형 PostgreSQL 서비스(예: AWS RDS, Azure Database for PostgreSQL, Google Cloud SQL)를 사용하는 클라우드 네이티브 배포에서는 데이터베이스 구성 파일을 직접 수정할 수 없습니다. 대신 클라우드 서비스의 파라미터 그룹 또는 구성 인터페이스를 통해 statement_timeout 파라미터를 구성합니다:
- AWS RDS: 데이터베이스 인스턴스에 연결된 파라미터 그룹을 수정하고
statement_timeout을0(무제한)으로 설정합니다. - Azure Database for PostgreSQL: Azure 포털에서 서버 파라미터를 업데이트하고
statement_timeout을0으로 설정합니다. - Google Cloud SQL: 데이터베이스 플래그를 수정하고
statement_timeout을0으로 설정합니다.
파라미터 그룹이나 구성을 변경한 뒤에는 변경 사항이 적용되도록 데이터베이스 인스턴스를 재부팅해야 할 수 있습니다. 구체적인 방법은 클라우드 제공업체의 문서를 참고합니다.
(RE)INDEX 진행 보고서 관찰#
일부 상황에서는 CREATE INDEX 또는 REINDEX 작업의 진행 상황을 관찰해야 할 수 있습니다. 예를 들어 CREATE INDEX 또는 REINDEX 작업이 활성 상태인지 확인하거나, 작업이 어느 단계에 있는지 확인할 때 이렇게 합니다.
사전 요구 사항:
- PostgreSQL 버전 12 이상을 사용해야 합니다.
CREATE INDEX 또는 REINDEX 작업을 관찰하려면:
- 내장된
pg_stat_progress_create_index뷰를 사용합니다.
예를 들어 데이터베이스 콘솔 세션에서 다음 명령을 실행합니다:
SELECT * FROM pg_stat_progress_create_index \watch 0.2
사람이 읽기 쉬운 출력을 만드는 방법과 로그 파일에 데이터를 기록하는 방법은 이 스니펫을 참고합니다.
문제 해결#
데이터베이스 연결 거부#
다음과 같은 오류가 발생하면 안정적인 연결을 위해 max_connections가 충분히 큰지 확인합니다.
connection to server at "xxx.xxx.xxx.xxx", port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
psql: error: connection to server on socket "/var/opt/gitlab/postgresql/.s.PGSQL.5432" failed:
FATAL: sorry, too many clients already
max_connections를 조정하는 방법은 여러 데이터베이스 연결 구성을 참고합니다.
래퍼라운드 데이터 손실을 피하기 위해 데이터베이스가 명령을 수락하지 않음#
이 오류는 autovacuum이 실행을 완료하지 못하고 있음을 의미할 가능성이 높습니다:
ERROR: database is not accepting commands to avoid wraparound data loss in database "gitlabhq_production"
또는
ERROR: failed to re-find parent key in index "XXX" for deletion target page XXX
오류를 해결하려면 VACUUM을 수동으로 실행합니다:
-
gitlab-ctl stop명령으로 GitLab을 중지합니다. -
다음 명령으로 데이터베이스를 단일 사용자 모드로 전환합니다:
/opt/gitlab/embedded/bin/postgres --single -D /var/opt/gitlab/postgresql/data gitlabhq_production -
backend>프롬프트에서VACUUM;을 실행합니다. 이 명령은 완료까지 몇 분이 걸릴 수 있습니다. -
명령이 완료될 때까지 기다린 다음 Control + D를 눌러 종료합니다.
-
gitlab-ctl start명령으로 GitLab을 시작합니다.
GitLab 데이터베이스 요구 사항#
데이터베이스 요구 사항을 참고하고 필수 확장 목록을 검토해 설치합니다.
production/sidekiq 로그의 직렬화 오류#
production/sidekiq 로그에 이 예시와 같은 오류가 나타나면, 문제를 해결하기 위해
default_transaction_isolation을 read committed로 설정하는 방법을 참고합니다:
ActiveRecord::StatementInvalid PG::TRSerializationFailure: ERROR: could not serialize access due to concurrent update
PostgreSQL 복제 슬롯 오류#
이 예시와 같은 오류가 나타나면, PostgreSQL HA의 복제 슬롯 오류를 해결하는 방법을 참고합니다:
pg_basebackup: could not create temporary replication slot "pg_basebackup_12345": ERROR: all replication slots are in use
HINT: Free one or increase max_replication_slots.
Geo 복제 오류#
이 예시와 같은 오류가 나타나면, Geo 복제 오류를 해결하는 방법을 참고합니다:
ERROR: replication slots can only be used if max_replication_slots > 0
FATAL: could not start WAL streaming: ERROR: replication slot "geo_secondary_my_domain_com" does not exist
Command exceeded allowed execution time
PANIC: could not write to file 'pg_xlog/xlogtemp.123': No space left on device
Geo 구성 검토 및 일반적인 오류#
Geo 문제를 해결할 때는 다음을 수행합니다:
- 일반적인 Geo 오류를 검토합니다.
- Geo 구성을 검토합니다. 포함 항목:
- 호스트 및 포트 재구성.
- 사용자 및 비밀번호 매핑 검토 및 수정.
pg_dump와 psql 버전 불일치#
이 예시와 같은 오류가 나타나면, 패키지되지 않은 PostgreSQL 데이터베이스를 백업하고 복원하는 방법을 참고합니다:
Dumping PostgreSQL database gitlabhq_production ... pg_dump: error: server version: 13.3; pg_dump version: 14.2
pg_dump: error: aborting because of server version mismatch
확장 btree_gist가 허용 목록에 없음#
Azure Database for PostgreSQL - Flexible Server에 PostgreSQL을 배포하면 이 오류가 발생할 수 있습니다:
extension "btree_gist" is not allow-listed for "azure_pg_admin" users in Azure Database for PostgreSQL
이 오류를 해결하려면 설치 전에 확장을 허용 목록에 추가합니다.