pg_wal 디렉터리가 계속 커져 볼륨을 채우고, 볼륨을 늘리면 금세 다시 찬다. 용량을 늘리는 것은 시간을 버는 일일 뿐 원인 제거가 아니다. WAL 파일을 손으로 지우면 데이터베이스가 복구 불가능해질 수 있다. 원인부터 찾는다.
du -sh /var/lib/pgsql/17/data/pg_wal
ls -1 /var/lib/pgsql/17/data/pg_wal | wc -l
가장 흔하다. 복제 슬롯은 해당 소비자가 아직 읽지 않은 WAL 을 서버가 지우지 못하게 붙든다. standby 를 없애면서 슬롯을 지우지 않으면 WAL 이 무한정 쌓인다.
SELECT slot_name, slot_type, active, restart_lsn,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained
FROM pg_replication_slots
ORDER BY retained DESC;
active = false 인데 retained 가 계속 커지는 슬롯이 범인이다.
SELECT pg_drop_replication_slot('old_standby');
슬롯을 지우면 그 standby 는 다시 붙지 못하고 재구축해야 한다. 되살릴 계획이 없는 슬롯만 지운다. 재발을 막으려면 상한을 건다. PostgreSQL 13 이상은 max_slot_wal_keep_size 로 슬롯이 붙들 수 있는 양을 제한한다.
max_slot_wal_keep_size = 20GB
archive_mode = on 인데 archive_command 가 계속 실패하면 아카이브되지 않은 WAL 을 서버가 지우지 않는다.
SELECT archived_count, last_archived_wal, failed_count, last_failed_wal, last_failed_time
FROM pg_stat_archiver;
failed_count 가 늘고 있으면 아카이브 대상(마운트, 원격 저장소, 권한)을 고친다. 임시로 아카이브를 끄면 그 구간의 WAL 은 백업 체인에서 빠지므로, 끈 뒤에는 전체 백업을 다시 받아야 한다.
오래 열린 트랜잭션이나 오래된 prepared transaction 도 WAL 정리를 막는다.
SELECT pid, state, now() - xact_start AS age, LEFT(query, 80)
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY age DESC LIMIT 10;
SELECT * FROM pg_prepared_xacts;
SHOW max_wal_size; -- 체크포인트 사이에 허용하는 WAL 총량
SHOW min_wal_size;
SHOW wal_keep_size; -- 13 이상. 12 이하는 wal_keep_segments
SHOW checkpoint_timeout;
max_wal_size 가 크면 그만큼 정상적으로 쌓인다. 이 경우는 문제가 아니라 설정대로 동작하는 것이다.
원인을 제거했는데도 파일이 남아 있으면 체크포인트를 돌려 회수한다.
CHECKPOINT;
디스크가 이미 100% 라 서버가 기동조차 안 되면, pg_wal 을 지우는 대신 여유 있는 다른 볼륨으로 옮기고 심볼릭 링크를 건다. 서버를 정지한 상태에서 한다.
systemctl stop postgresql-17
mv /var/lib/pgsql/17/data/pg_wal /data2/pg_wal
ln -s /data2/pg_wal /var/lib/pgsql/17/data/pg_wal
chown -h postgres:postgres /var/lib/pgsql/17/data/pg_wal
systemctl start postgresql-17
정말로 파일을 지워야 한다면 pg_archivecleanup 을 쓴다. 어느 파일까지 안전한지 서버가 판단해 준다. rm 으로 골라 지우지 않는다.
pg_archivecleanup -d /var/lib/pgsql/17/data/pg_wal 000000010000000000000042
.history 파일과 archive_status 디렉터리는 건드리지 않는다.
클라우드 블록 스토리지는 온라인 확장만 지원하고 축소는 지원하지 않는 경우가 대부분이다. AWS EBS 도 축소할 수 없다. 작은 볼륨을 새로 만들어 데이터를 옮기고 교체하는 것이 유일한 방법이다. Kubernetes 의 PVC 도 같아서, allowVolumeExpansion 으로 늘릴 수는 있어도 줄이지는 못한다. 늘리기 전에 원인을 먼저 확인하는 이유가 여기 있다.