높은 WAL 활동 문제 해결 및 아카이브 로그 디스크 공간 관리
PostgreSQL에서 과도한 Write-Ahead Log(WAL) 생성 문제를 해결하고 관리하는 방법을 알아봅니다. 이 가이드는 대량 작업 및 복제 문제와 같은 높은 WAL 활동의 일반적인 원인을 다루고, WAL 아카이빙 구성, 복제 슬롯 관리, 디스크 공간 부족 방지를 위한 실용적인 솔루션을 제공합니다. 안정성과 효율적인 디스크 공간 활용에 중점을 둔 PostgreSQL 관리자를 위한 필독 자료입니다.
높은 WAL 활동 문제 해결 및 아카이브 로그 디스크 공간 관리
PostgreSQL에서 높은 Write-Ahead Log(WAL) 활동이 자동으로 문제가 되는 것은 아닙니다. 바쁜 데이터베이스는 WAL을 생성해야 합니다. 문제는 WAL 비율이 예상치 못할 때, 아카이브된 WAL이 정리되지 않을 때, 또는 PostgreSQL이 오래된 세그먼트를 재활용하지 못해 pg_wal이 증가할 때 발생합니다.
WAL 문제를 더 악화시키는 가장 빠른 방법은 pg_wal에서 파일을 수동으로 삭제하는 것입니다. 그렇게 하지 마십시오. WAL 디스크가 가득 찬 경우를 복구 상황으로 간주하십시오: WAL을 보유하고 있는 원인을 식별하고, 안전하게 가능하다면 여유 공간을 확보한 다음, 증가를 초래한 실패한 아카이브, 지연된 스탠바이, 또는 중단된 슬롯을 수정하십시오.
Write-Ahead Logging(WAL) 이해하기
PostgreSQL은 관련 데이터 페이지가 안전하게 기록되기 전에 변경 레코드를 WAL에 기록합니다. 충돌 후 PostgreSQL은 WAL을 재생하여 커밋된 변경 사항이 손실되지 않도록 합니다. 동일한 스트림은 스트리밍 복제 및 특정 시점 복구에도 사용됩니다.
WAL 파일은 고정 크기 세그먼트 파일에 저장됩니다. 많은 설치에서 16MB 세그먼트를 사용하는 것이 일반적인 기본값이지만, 크기는 클러스터가 초기화될 때 선택됩니다. 쓰기 작업이 많은 워크로드는 빠르게 많은 수의 세그먼트를 생성할 수 있습니다. 오래된 세그먼트는 PostgreSQL이 충돌 복구, 체크포인트, 아카이빙, 복제 또는 슬롯에 더 이상 필요하지 않은 경우에만 재활용되거나 제거됩니다.
주요 WAL 개념:
- 내구성: 커밋된 트랜잭션은 충돌 후 복구될 수 있습니다.
- 복제: 스탠바이는 프라이머리로부터 WAL 레코드를 수신합니다.
- 특정 시점 복구(PITR): 기본 백업과 아카이브된 WAL을 사용하여 보존 기간 내의 선택된 시점으로 복구할 수 있습니다.
- WAL 세그먼트: WAL은
pg_wal아래의 세그먼트 파일에 저장됩니다.
높은 WAL 활동의 일반적인 원인
여러 요인이 비정상적으로 많은 WAL 생성량에 기여할 수 있습니다. 근본 원인을 식별하는 것이 효과적인 문제 해결의 첫 번째 단계입니다.
1. 대량 데이터 로딩 및 수정
INSERT, UPDATE, DELETE, TRUNCATE, COPY와 같은 작업은 상당한 양의 WAL을 생성할 수 있습니다. 특히 대규모 테이블에 대한 대량 작업은 소규모 개별 트랜잭션보다 자연스럽게 더 많은 WAL 레코드를 생성합니다.
- 예시: 수백만 행을 삽입하는 단일
COPY FROM명령은 기가바이트의 WAL 데이터를 생성할 수 있습니다. - 예시: 대규모 데이터 마이그레이션 또는 배치 업데이트 스크립트 실행.
2. 복제 지연 및 스탠바이 문제
스탠바이 서버가 프라이머리를 따라잡지 못하는 경우(복제 지연), WAL 파일이 프라이머리에 축적됩니다. 프라이머리 서버는 완료된 WAL 세그먼트가 연결된 모든 스탠바이로 전송 및 처리되었음이 확인될 때까지 제거할 수 없습니다(wal_keep_size 또는 max_slot_wal_keep_size가 구성되지 않았거나 슬롯이 올바르게 사용되지 않는 경우).
- 시나리오: 스탠바이 서버가 다운되었거나, 연결이 끊어졌거나, 성능 문제가 발생하여 프라이머리에서 WAL 레코드를 소비하지 못하는 경우.
3. 체크포인트 후 전체 페이지 쓰기
체크포인트 후 데이터 페이지에 대한 첫 번째 변경은 full_page_writes가 활성화된 경우 전체 페이지 이미지를 기록할 수 있습니다. 이 설정은 찢어진 페이지로부터 복구를 보호하며 일반적으로 켜져 있습니다. 체크포인트가 너무 자주 발생하면 전체 페이지 이미지가 WAL 볼륨을 눈에 띄게 증가시킬 수 있습니다. 해결 방법은 일반적으로 내구성 보호를 비활성화하는 것이 아니라 체크포인트 동작을 조정하는 것입니다.
4. 관리되지 않는 pg_wal 디렉토리 증가
WAL 아카이빙이 활성화되어 있고 실패하는 경우 PostgreSQL은 아직 아카이브해야 하는 WAL 세그먼트를 보관합니다. 아카이빙이 활성화되지 않은 경우, 복제, 슬롯 또는 체크포인트 압력이 보유하지 않는 한 pg_wal은 더 이상 필요하지 않은 오래된 세그먼트를 계속 재활용해야 합니다.
5. 회수되지 않은 복제 슬롯
복제 슬롯은 특정 스탠바이 또는 논리적 디코딩 클라이언트가 소비하기 전에 WAL 세그먼트가 제거되지 않도록 보장합니다. 슬롯이 생성되었지만 소비자가 중지되거나 연결이 끊어지고 슬롯이 삭제되지 않으면, 해당 슬롯에 필요한 WAL 세그먼트는 스탠바이가 더 이상 활성 상태가 아니더라도 보존됩니다.
WAL 디스크 공간 관리: 구성 및 솔루션
높은 WAL 활동을 해결하려면 모니터링, 구성 조정 및 적절한 유지 관리 절차를 포함한 다각적인 접근 방식이 필요합니다.
1. WAL 아카이빙 활성화 및 모니터링
WAL 아카이빙은 디스크 공간을 관리하고 PITR을 활성화하는 가장 중요한 메커니즘입니다. 아카이빙이 활성화되면 완료된 WAL 파일이 별도의 위치(예: 네트워크 파일 공유, S3 버킷 또는 다른 디스크)로 복사됩니다.
구성:
postgresql.conf 파일을 수정하십시오:
wal_level = replica # 논리적 복제의 경우 logical
archive_mode = on # 아카이빙 활성화
archive_command = 'cp %p /path/to/archive/%f'
# wal-g 또는 유사 도구를 사용한 S3 예시:
# archive_command = 'wal-g wal-push %p'
%p: 아카이브할 WAL 파일의 전체 경로에 대한 자리 표시자.%f: WAL 파일의 파일 이름에 대한 자리 표시자.
중요: archive_command는 성공적으로 실행될 수 있어야 합니다. 0이 아닌 종료 코드를 반환하면 PostgreSQL은 아카이빙이 실패한 것으로 간주하여 WAL 파일이 제거되지 않을 수 있습니다. 대상 디렉토리에 충분한 공간이 있고 PostgreSQL을 실행하는 사용자에게 쓰기 권한이 있는지 확인하십시오.
아카이빙 모니터링
SQL 쿼리를 사용하여 아카이빙 상태를 확인하십시오:
SELECT archived_count,
failed_count,
last_archived_wal,
last_archived_time,
last_failed_wal,
last_failed_time
FROM pg_stat_archiver;
failed_count가 계속 증가하거나 데이터베이스가 계속 쓰고 있는데 last_archived_time이 오래된 경우, WAL 크기 매개변수를 조정하기 전에 아카이브 대상을 수정하십시오.
2. pg_wal 디렉토리 크기 관리
아카이빙이 활성화된 경우에도 아카이빙 후 WAL 세그먼트가 제거되지 않으면 프라이머리의 pg_wal 디렉토리가 커질 수 있습니다. 이는 다음과 같은 경우에 발생합니다:
- 스탠바이가 따라잡지 못하고 프라이머리가 복제를 위해 추가 WAL을 보유하는 경우.
- 복제 슬롯이 WAL 파일을 보유하고 있는 경우.
wal_keep_size
이 매개변수는 스트리밍 복제를 위해 프라이머리에 추가 WAL을 유지합니다. PostgreSQL 13에서 이전 wal_keep_segments 설정을 대체했습니다. 슬롯을 사용하지 않는 스탠바이에 유용하지만, 심하게 지연된 스탠바이가 항상 따라잡을 수 있다는 보장은 아닙니다.
# 프라이머리의 postgresql.conf
wal_keep_size = 1024 # 디스크에 1GB의 WAL 유지
특정 소비자를 위해 프라이머리가 WAL을 보유해야 하는 경우 복제 슬롯이 선호되는 경우가 많지만, 슬롯은 무기한 WAL을 보유할 수 있으므로 모니터링해야 합니다.
max_slot_wal_keep_size (PostgreSQL 13+)
이 설정은 복제 슬롯이 보유할 수 있는 WAL 양을 제한합니다. 손상된 슬롯으로 인한 무제한 증가에 대한 보호 장치이지만, 지연된 소비자가 필요한 WAL을 잃어 재초기화가 필요할 수 있습니다.
# 프라이머리의 postgresql.conf
max_slot_wal_keep_size = 2048 # 슬롯이 2GB의 WAL을 보유하도록 제한
# 또한 고려: wal_keep_size -- 비슬롯 기반 스트리밍에 여전히 관련
# wal_keep_size = 1024 # 비슬롯 스트리밍을 위해 1GB 유지
슬롯이 너무 뒤쳐져 이 제한을 초과하면 PostgreSQL은 체크포인트 시간에 필요한 WAL을 제거할 수 있습니다. 이는 디스크 공간을 보호하지만, 영향을 받은 스탠바이 또는 논리적 복제 클라이언트는 이전 위치에서 계속할 수 없게 될 수 있습니다.
복제 슬롯
복제 슬롯은 WAL 손실을 방지하고 안정적인 복제를 보장하는 데 중요합니다. 그러나 올바르게 관리되지 않으면 WAL 파일이 축적될 수 있습니다.
- 문제: 복제 슬롯이 생성되었지만 소비자(스탠바이 또는 논리적 클라이언트)가 연결을 끊거나 실패하고 슬롯이 삭제되지 않습니다. 프라이머리 서버는 슬롯이 기다리고 있는 모든 WAL 파일을 계속 유지합니다.
- 해결 방법: 정기적으로 복제 슬롯을 모니터링하고 더 이상 사용되지 않는 슬롯을 삭제하십시오.
-- 복제 슬롯 나열
SELECT slot_name,
plugin,
slot_type,
active,
restart_lsn,
wal_status,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal
FROM pg_replication_slots
ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;
-- 사용하지 않는 슬롯 삭제
SELECT pg_drop_replication_slot('slot_name_to_drop');
경고: 복제 슬롯을 삭제하면 연결된 소비자가 위치를 잃게 됩니다. 삭제하기 전에 소비자가 더 이상 필요하지 않거나 적절히 재초기화되었는지 확인하십시오.
3. min_wal_size 및 max_wal_size 조정
이 매개변수는 체크포인트 빈도와 PostgreSQL이 재사용을 위해 유지하려는 WAL 양에 영향을 줍니다. 아카이빙 또는 복제를 위해 보유된 WAL을 제한하지 않습니다.
min_wal_size: PostgreSQL이 즉시 제거하는 대신 재사용을 위해 최소한 이 정도의 WAL을 유지하도록 권장합니다.max_wal_size: 체크포인트를 트리거하는 경향이 있는 WAL 볼륨입니다. 다른 이유로 WAL이 보유되는 경우 하드 최대값이 아닙니다.
# postgresql.conf
min_wal_size = 1GB
max_wal_size = 4GB
max_wal_size를 늘리면 피크 쓰기 부하 중 시스템에 더 많은 여유 공간을 제공할 수 있지만, 미리 할당된 WAL 파일이 더 많은 디스크 공간을 차지하게 됩니다.
4. 아카이브된 WAL 파일의 정기적인 정리
WAL 아카이빙은 복구에 필수적이지만, 아카이브된 파일이 정리되지 않으면 디스크 공간 문제로 이어질 수 있습니다. 아카이브된 WAL 파일의 보존을 관리하기 위한 전략이 있어야 합니다.
전략: 스크립트를 구현하거나 전용 도구(
pg_archivecleanup,pgBackRest,wal-g,barman등)를 사용하여 PITR 또는 복제에 더 이상 필요하지 않은 오래된 WAL 파일을 아카이브 위치에서 제거하십시오.pg_archivecleanup사용: 이 유틸리티는 프라이머리 서버에서 실행되어 아카이브 디렉토리에서 오래된 WAL 파일을 제거할 수 있습니다.pg_archivecleanup /path/to/archive/location 0000000100000037000000AF두 번째 인수는 임의의 기간이 아니라 계속 보관해야 하는 가장 오래된 WAL 파일 이름입니다. 실제로는 pgBackRest, Barman 및 WAL-G와 같은 백업 도구가 백업 보존 및 복구에 필요한 WAL을 이해하기 때문에 더 안전합니다.
중요: 정리 전략이 백업 및 복구 특정 시점 복구(PITR) 요구 사항과 일치하는지 항상 확인하십시오. 원하는 복구 기간을 충당할 수 있을 만큼 WAL 파일을 보관해야 합니다.
5. 디스크 공간 및 WAL 생성 속도 모니터링
사전 예방적 모니터링은 디스크 공간 고갈을 방지하는 데 중요합니다.
디스크 공간 모니터링: 데이터 디렉토리,
pg_wal, 임시 파일 위치 및 아카이브 대상의 여유 공간을 추적하십시오.WAL 생성 모니터링: 시간 경과에 따른 LSN 차이를 사용하여 생성 속도를 추정하십시오.
SELECT now() AS sample_time, pg_current_wal_lsn() AS current_lsn;해당 값을 주기적으로 저장하고
pg_wal_lsn_diff(new_lsn, old_lsn)으로 샘플을 비교하십시오. 현재pg_wal디렉토리 크기를 빠르게 확인하려면:SELECT pg_size_pretty(sum(size)) AS pg_wal_size FROM pg_ls_waldir();
디스크 가득 참 문제 해결 단계
WAL 활동으로 인해 디스크가 이미 가득 찬 경우 즉각적인 조치가 필요합니다:
- 원인 식별:
pg_stat_archiver에서 아카이빙 실패를 확인하십시오.pg_replication_slots에서 사용되지 않거나 문제가 있는 슬롯을 검사하십시오. 스탠바이의 복제 지연을 확인하십시오. - 복구를 손상시키지 않고 공간 확보:
pg_wal에서 파일을 수동으로 삭제하지 마십시오.- 아카이브 대상이 가득 찬 경우, 백업 보존 기간을 벗어난 오래된 아카이브 WAL만 제거하십시오.
- 가능하면 스토리지를 추가하거나 아카이브 대상을 이동한 다음 PostgreSQL이 정상적으로 아카이브하고 재활용하도록 하십시오.
- 근본 원인 해결:
- 아카이빙 수정:
archive_command가 올바르고 대상에 공간이 있는지 확인하십시오. - 슬롯 관리: 사용하지 않는 복제 슬롯을 삭제하십시오.
- 복제 수정: 스탠바이 지연을 유발하는 문제를 해결하십시오.
- 디스크 공간 증가: 임시 또는 영구적으로 더 많은 스토리지를 추가하십시오.
- 아카이빙 수정:
- 아카이버 활성화: 아카이브 명령 또는 대상을 수정한 후 PostgreSQL이 재시도해야 합니다. 구성 변경에는 재로드로 충분할 수 있습니다. 전체 재시작은 디스크 사고 중 최후의 수단이어야 합니다.
더 안전한 사고 모델
pg_wal이 증가할 때 순서대로 세 가지 질문을 하십시오:
- 워크로드가 변경되어 PostgreSQL이 평소보다 더 많은 WAL을 생성하고 있습니까?
- PostgreSQL이 WAL을 아카이브할 수 없습니까?
- PostgreSQL이 복제 또는 슬롯을 위해 WAL을 보유하도록 지시받고 있습니까?
그 답변은 서로 다른 수정 사항을 가리킵니다. 대량 쓰기는 스케줄링, 배치 또는 체크포인트 조정이 필요할 수 있습니다. 아카이브 실패는 스토리지 및 명령 수정이 필요합니다. 슬롯 보존은 소비자 복구, 슬롯 정리 또는 보존 제한이 필요합니다. max_wal_size를 추측하는 것만으로는 실제 문제를 거의 해결하지 못합니다.