높은 WAL 활동 및 아카이브 로그 디스크 공간 관리 문제 해결
PostgreSQL에서 높은 쓰기 선행 로그(WAL) 활동은 디스크 공간을 빠르게 소모하고 데이터베이스 다운타임을 유발할 수 있는 심각한 문제입니다. WAL은 PostgreSQL이 데이터 내구성과 복구 가능성을 보장하는 메커니즘입니다. 데이터베이스에 대한 모든 변경 사항은 데이터 파일에 적용되기 전에 먼저 WAL에 기록됩니다. 필수적이지만 과도한 WAL 생성이 발생하면, 특히 아카이빙 또는 정리 프로세스가 최적으로 구성되지 않은 경우 가용 디스크 공간을 빠르게 초과할 수 있습니다.
이 문서는 높은 WAL 생성의 일반적인 원인을 살펴보고 아카이브 로그 디스크 공간을 효율적으로 관리하기 위한 실용적인 전략을 제공합니다. 기본 메커니즘을 이해하고 적절한 구성을 구현함으로써 디스크 관련 장애를 방지하고 PostgreSQL 환경의 상태를 유지할 수 있습니다.
쓰기 선행 로깅(WAL) 이해
문제 해결 전에 WAL이 작동하는 방식을 이해하는 것이 중요합니다. PostgreSQL은 트랜잭션이 원자성, 일관성, 격리성 및 내구성(ACID)을 갖도록 보장하기 위해 WAL을 사용합니다. 데이터베이스 변경이 발생하면 해당 변경을 설명하는 레코드가 WAL 버퍼에 기록된 다음 디스크의 WAL 파일로 플러시됩니다. 이를 통해 데이터 페이지가 업데이트되기 전에 서버가 충돌하더라도 복구 중에 WAL에서 변경 사항을 다시 적용할 수 있습니다.
WAL 파일은 기본적으로 16MB 크기의 세그먼트로 관리됩니다. 새로운 트랜잭션이 발생하면 새로운 WAL 파일이 생성됩니다. 이러한 파일은 빠르게 축적될 수 있으며, 적절하게 관리되지 않으면(예: 아카이빙 및 제거) 모든 사용 가능한 디스크 공간을 소모하게 됩니다.
주요 WAL 개념:
- 내구성: 트랜잭션이 커밋되면 시스템 장애에도 살아남도록 보장합니다.
- 복제: WAL은 대기 서버가 주 서버와 동기화 상태를 유지하기 위해 WAL 레코드를 수신하는 스트리밍 복제의 기본입니다.
- 특정 시점 복구(PITR): WAL 아카이빙은 PITR에 필수적이며, 데이터베이스를 특정 시점으로 복원할 수 있게 합니다.
- WAL 세그먼트: 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. 과도한 fsync 호출(덜 일반적이지만 가능)
WAL 자체는 주요 드라이버이지만, 비효율적인 애플리케이션 로직이나 특정 PostgreSQL 구성은 디스크로의 플러시 빈도를 높여 간접적으로 WAL 활동을 증가시킬 수 있습니다. 그러나 이는 대량 작업이나 복제 문제보다 덜 일반적입니다.
4. 관리되지 않는 pg_wal 디렉토리 증가
WAL 아카이빙이 활성화되지 않았거나 실패하면, 주 서버의 pg_wal(이전 pg_xlog) 디렉토리는 새로운 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 FROM pg_stat_archiver;
SELECT pg_current_wal_lsn() AS current_lsn,
pg_walfile_name_offset(pg_current_wal_lsn()) AS current_wal_file,
pg_last_wal_replay_lsn() AS replay_lsn; -- 대기 서버에서
-- 아직 아카이브되지 않은 WAL 파일 확인 (문제가 있음을 나타낼 수 있음)
SELECT pg_wal_lsn_segments(pg_current_wal_lsn() - pg_last_archived_wal_lsn()) AS segments_since_last_archive;
2. pg_wal 디렉토리 크기 관리
아카이빙이 활성화되어 있어도, WAL 세그먼트가 아카이빙 후 제거되지 않으면 주 서버의 pg_wal 디렉토리가 증가할 수 있습니다. 이는 다음과 같은 경우에 발생합니다:
- 대기 서버가 따라가지 못하고
wal_keep_size(또는 슬롯의 경우max_slot_wal_keep_size)가 충분한 WAL을 유지하기에 너무 작을 때. - 복제 슬롯이 WAL 파일을 보유하고 있을 때.
wal_keep_size (PostgreSQL 13 이전)
주 서버의 이 매개변수는 스트리밍 복제를 위해 pg_wal 디렉토리에 보관해야 하는 WAL 데이터 양(MB 단위)을 지정합니다. 대기 서버가 너무 뒤처지고 따라잡기 위해 필요한 WAL 양이 wal_keep_size를 초과하면, 대기 서버는 다시 연결하지 못할 수 있습니다.
# primary의 postgresql.conf
wal_keep_size = 1024 # 디스크에 1GB WAL 유지
참고: wal_keep_size는 과거의 접근 방식입니다. 일반적으로 더 강력한 복제를 위해서는 복제 슬롯을 사용하는 것이 선호됩니다.
max_slot_wal_keep_size (PostgreSQL 13 이상)
이는 복제 슬롯을 사용할 때 WAL 보존을 관리하는 선호되는 방법입니다. 모든 복제 슬롯이 결합하여 보존할 수 있는 총 WAL 디스크 공간(MB 단위)을 제한합니다.
# primary의 postgresql.conf
max_slot_wal_keep_size = 2048 # 슬롯이 2GB WAL을 보존하도록 제한
# 또한 고려할 사항: wal_keep_size -- 여전히 슬롯 기반이 아닌 스트리밍에 관련됨
# wal_keep_size = 1024 # 슬롯 기반이 아닌 스트리밍을 위해 1GB 유지
활성 슬롯에 필요한 총 WAL이 max_slot_wal_keep_size를 초과하면, 슬롯에서 소비되었더라도 새 WAL 파일이 제거되지 않아 디스크가 채워지게 됩니다. 이 매개변수는 문제가 있는 슬롯으로 인한 무제한 WAL 축적을 방지합니다.
복제 슬롯
복제 슬롯은 WAL 손실을 방지하고 안정적인 복제를 보장하는 데 중요합니다. 그러나 올바르게 관리되지 않으면 WAL 파일이 축적될 수 있습니다.
- 문제: 복제 슬롯이 생성되었지만 소비자가(대기 서버 또는 논리 클라이언트) 연결이 끊어지거나 실패하고 슬롯이 삭제되지 않은 경우. 주 서버는 슬롯이 기다리는 모든 WAL 파일을 유지합니다.
- 해결책: 정기적으로 복제 슬롯을 모니터링하고 더 이상 사용되지 않는 슬롯은 삭제합니다.
-- 복제 슬롯 목록
SELECT slot_name, plugin, slot_type, active, wal_status FROM pg_replication_slots;
-- 사용되지 않는 슬롯 삭제
SELECT pg_drop_replication_slot('slot_name_to_drop');
경고: 복제 슬롯을 삭제하면 연결된 모든 소비자가 위치를 잃게 됩니다. 삭제하기 전에 소비자가 더 이상 필요하지 않거나 제대로 다시 초기화되었는지 확인하십시오.
3. min_wal_size 및 max_wal_size 조정
이 매개변수는 PostgreSQL이 사전 할당할 WAL의 최소 및 최대 양을 제어합니다. 직접적으로 높은 WAL 생성을 유발하지는 않지만, 사전 할당으로 인해 고활동 기간 동안 pg_wal 디렉토리가 얼마나 빨리 증가하는지에 영향을 미칩니다.
min_wal_size: 최소한 이 정도의 WAL 공간이 사용 가능하도록 보장하여 빈번한 사전 할당을 방지합니다. 너무 낮게 설정하면pg_wal디렉토리 확장 빈도가 잦아질 수 있습니다.max_wal_size: PostgreSQL이 유지할 최대 WAL 양입니다. 이 한계를 초과하는 이전 세그먼트는 아카이빙 또는 복제에서 더 이상 필요하지 않으면 재활용되거나 제거됩니다.
# postgresql.conf
min_wal_size = 1GB
max_wal_size = 4GB
max_wal_size를 늘리면 피크 쓰기 부하 중에 시스템에 더 많은 여유 공간을 제공할 수 있지만, 사전 할당된 WAL 파일로 인해 더 많은 디스크 공간이 점유된다는 의미이기도 합니다.
4. 아카이브된 WAL 파일 정기 정리
WAL 아카이빙은 복구에 필수적이지만, 아카이브된 파일이 절대 정리되지 않으면 디스크 공간 문제를 유발할 수도 있습니다. 아카이브된 WAL 파일의 보존을 관리하기 위한 전략이 있어야 합니다.
-
전략: PITR 또는 복제에 더 이상 필요하지 않은 오래된 WAL 파일을 아카이브 위치에서 제거하기 위해 스크립트를 구현하거나 전용 도구(
pg_archivecleanup,pgBackRest,wal-g,barman등)를 사용합니다. -
pg_archivecleanup사용:
이 유틸리티는 주 서버에서 아카이브 디렉토리의 오래된 WAL 파일을 제거하기 위해 실행할 수 있습니다.
bash # 주 서버에서 PostgreSQL bin 디렉토리 내: pg_archivecleanup /path/to/archive/location <timelineID> <lsn_to_keep_until>
또는archive_command에 통합할 수도 있습니다(하지만 이는 덜 일반적이며 까다로울 수 있습니다).더 일반적인 접근 방식은 마지막 성공적인 백업 시점까지 WAL 파일을 유지하도록
pg_archivecleanup을 주기적으로 실행하도록 예약하는 것입니다.```bash
예시 cron 작업으로 매일 실행, 24시간 이전 WAL 파일 유지
이 설정이 백업 전략과 일치하는지 확인!
0 0 * * * pg_archivecleanup -d -v /path/to/archive/location
```중요: 항상 정리 전략이 백업 및 복구 특정 시점 복구(PITR) 요구 사항과 일치하는지 확인하십시오. 원하는 복구 창을 포괄할 만큼 충분히 오래 WAL 파일을 유지해야 합니다.
5. 디스크 공간 및 WAL 생성 속도 모니터링
사전 예방적인 모니터링은 디스크 공간 고갈을 방지하는 데 핵심입니다.
- 디스크 공간 모니터링: 시스템 모니터링 도구(예: Nagios, Prometheus, Zabbix)를 사용하여 데이터 디렉토리 및 아카이브 위치의 여유 공간을 추적합니다.
-
WAL 생성 모니터링: WAL 활동 및 아카이브 성공을 이해하기 위해
pg_stat_wal_receiver(대기 서버) 및pg_stat_archiver(주 서버)를 쿼리합니다.```sql
-- WAL 생성 속도 확인 (근사치)
SELECT pg_size_pretty(pg_current_wal_lsn()::bigint - pg_last_wal_write_lsn()::bigint) AS current_wal_written;-- WAL 파일 나이 확인
SELECT pg_walfile_name(f.path) AS wal_file, pg_wal_file_name(f.path) < pg_current_wal_lsn() AS is_old
FROM pg_ls_dir('/path/to/your/pg_wal') AS f(path)
ORDER BY f.path;
```
디스크 꽉 찼을 때 문제 해결 단계
WAL 활동으로 인해 디스크가 이미 꽉 찼다면 즉각적인 조치가 필요합니다:
- 원인 파악: 아카이빙 실패 여부를 확인하기 위해
pg_stat_archiver를 확인합니다. 사용되지 않거나 문제가 있는 슬롯을 확인하기 위해pg_replication_slots를 검토합니다. 대기 서버의 복제 지연을 확인합니다. - **공간 확보 (임시 조치):
- 아카이빙이 활성화되어 있고 작동 중인 경우: 복구에 더 이상 필요하지 않다고 확실히 판단되는 아주 오래된 아카이브 WAL 파일을 수동으로 삭제해 봅니다(매우 주의하십시오).
- 아카이빙이 활성화되지 않았거나 실패한 경우: 가능한 경우
pg_wal에서 완료된 WAL 파일을 다른 디스크로 임시 이동해야 할 수 있습니다. 백업이 있는 경우 데이터베이스를 다시 초기화하는 것을 고려할 수 있습니다(이는 극단적인 조치입니다).
- 근본 원인 해결:
- 아카이빙 수정:
archive_command가 올바르고 대상에 공간이 있는지 확인합니다. - 슬롯 관리: 사용되지 않는 복제 슬롯을 삭제합니다.
- 복제 수정: 대기 지연을 유발하는 문제를 해결합니다.
- 디스크 공간 늘리기: 임시 또는 영구적으로 더 많은 저장 공간을 추가합니다.
- 아카이빙 수정:
- 아카이버 재시작 (멈춘 경우): 때때로 아카이버 프로세스가 멈출 수 있습니다. PostgreSQL을 재시작하면 도움이 될 수 있지만, 그 의미를 이해하고 수행하십시오.
결론
높은 WAL 활동은 PostgreSQL 환경에서 흔한 문제이며, 종종 집중적인 쓰기 작업 또는 복제 및 아카이빙 문제에서 비롯됩니다. WAL 아카이빙을 부지런히 활성화하고 모니터링하며, max_slot_wal_keep_size 및 wal_keep_size로 보존 정책을 올바르게 구성하고, 복제 슬롯을 관리하며, 아카이브된 WAL 파일에 대한 강력한 정리 전략을 구현함으로써 디스크 공간 고갈을 효과적으로 방지하고 건강하고 안정적인 PostgreSQL 데이터베이스를 유지할 수 있습니다. 사전 예방적 모니터링은 이러한 문제에 대한 최선의 방어 수단으로 남습니다.