현재 데이터베이스의 전체 백업.첫번쨰 백업은 반드시 전체백업이어야 한다.전체 백업은 자신 이외의 파일을 참조하지 않음
마지막 전체백업 이후 변경사항에 대해 백업.차등백업으로 복구시 의존하는 전체백업도 유효해야됨
마지막 백업이후 변경사항에 대해 백업.증분백업이 의존하고 있는 증분백업,차등,전체백업이 유효해야 정상작동
정의
- 데이터베이스의 변경사항을 실제 데이터 파일에 쓰기 전에 로그에 먼저 기록하는 기법
작동 방식
- 데이터 변경 요청 발생
- 변경 내용을 WAL 파일에 기록
- WAL 파일이 디스크에 안전하게 저장되었음을 확인
- 실제 데이터 파일 변경
WAL의 주요 목적:
- 데이터 일관성 보장:
- 시스템 충돌 시 WAL을 사용하여 불완전한 트랜잭션을 롤백하거나 완료할 수 있습니다
- 성능 향상
- 무작위 쓰기 대신 순차적 쓰기를 사용하여 I/O 성능을 개선
- 시점 복구 지원
- 특정 시점으로의 데이터베이스 복구를 가능
WAL의 구조:
- 일련의 16MB (기본 크기) 세그먼트 파일로 구성됩니다.
- 각 세그먼트는 연속된 트랜잭션 로그를 포함합니다.
WAL의 중요성:
- 장애 복구
- 시스템 충돌 후 데이터베이스를 일관된 상태로 복구할 수 있습니다.
- 복제
- 스트리밍 복제를 통해 실시간으로 대기 서버를 동기화
- 백업
- 온라인 백업과 시점 복구를 가능하게 합니다.
WAL 관리:
- WAL 아카이빙: 완료된 WAL 세그먼트를 안전한 위치에 저장합니다.
- WAL 보관: 필요한 기간 동안 WAL 파일을 유지합니다.
- 체크포인트: 주기적으로 변경된 데이터를 디스크에 기록하고 WAL을 정리합니다
postgresql.conf
archive_command = 'pgbackrest --stanza=my_stanza archive-push /var/lib/postgresql/data/%p'
archive_mode = on
max_wal_senders = 3
wal_level = replica
archive_timeout = 60
공식문서에는 archive_command = 'pgbackrest --stanza=demo archive-push %p' 으로 나와있지만 실제 명령어 실행시 경로가 맞지 않아 /var/lib/postgresql/data/%p으로 변경함
postgresql/copy.sh 스크립트로 도커 공유 볼륨 수정
archive_timeout = 60: wal사이즈(15mb)를 충족하지 않아도 특정 시간이 되면 wal파일 스위치하여 60초마다 wal파일 푸시
pgbackrest.conf
[global]
...
repo1-retention-full=4
repo1-retention-full-type=count
repo1-retention-diff=7
repo1-retention-archive=1
repo1-retention-archive-type=diff
[my_stanza]
pg1-path=/var/lib/postgresql/data
pg1-user=sohatech
pg1-database=sohatechfarmdb
리텐션은 갯수(count)와 기간(time,일)로 설정가능하다
my_stanza: stanza이름
pg1-path:postgres디렉토리
pgbackrest/copy.sh 실행
pgbackrest --stanza=my_stanza --log-level-console=info stanza-create
pgbackrest --stanza=my_stanza --log-level-console=info check
pgbackrest --stanza=my_stanza --log-level-console=info stanza-upgrade
repository생성 및 권한설정정
chown -R postgres:postgres /var/lib/pgbackrest && chmod -R 750 /var/lib/pgbackrest && chown -R postgres:postgres /var/log/pgbackrest
실질적으로 백업이 저장되는 공간
docker exec -it pg bash
pgbackrest --stanza=my_stanza --type=full backup --log-level-console=info
pgbackrest --stanza=my_stanza --type=diff backup --log-level-console=info
pgbackrest --stanza=my_stanza --type=incr backup --log-level-console=info
pgbackrest --stanza=my_stanza info
su postgres
pg_ctl stop
pg_ctl start
pg_ctl은 root모드로 실행되지 않으므로 postgres유저로 접속한다
백업전 stop,백업 후 start
pgbackrest restore --stanza=my_stanza --set=20241018-090125F --delta --target-action=promote --type=immediate
--type=immediate: 복구시점이후 wal이 적용되지 않음.적용하지 않으면 백업 시점 이후의 모든 변경사항이 자동으로 적용되어, 결과적으로 최신 상태의 데이터베이스가 복원
--target-action=promote:복구완료후 즉시 프로덕션 환경으로 승격하여 서비스 활성화
--delta:현재데이터베이스와 비교하여 차이점만 복구,이 옵션없으면 현재 데이터베이스 완전 삭제후 실행가능
psql -U sohatech -d sohatechfarmdb -Atc"select current_timestamp"
pgbackrest --stanza=my_stanza restore --type=time "--target=2024-10-21 06:23:46+00" --delta --target-action=promote
psql -U sohatech -d sohatechfarmdb -c "SELECT pg_is_in_recovery();"
psql -U sohatech -d sohatechfarmdb -c "SELECT pg_wal_replay_resume();"
pg_controldata -D $PGDATA | grep -E "Latest checkpoint|Time of latest"
pg_waldump -p /path/to/pgbackrest/archive /path/to/last/wal/file
시나리오
- 시점 A의 백업에서 복구
- 시점시점 B (A 이후)까지 WAL 적용
- 시점다시 A와 B 사이의 시점 C로 복구 시도
문제
- B 이후의 WAL이 이미 적용되어 C 시점으로의 정확한 복구 어려움
해결
- A 시점부터 새로 복구를 시작하고 C 시점까지만 WAL 적용
WAL 아카이브 보존:
- 복구 시점 A까지의 WAL 파일들은 계속 유지
- WAL 파일들은 백업의 일관성을 유지하기 위해 필요하기 때문
WAL 파일 처리:
- 복구 시점 A 이후의 WAL 파일들은 무시
- PostgreSQL은 복구 시점 A까지만 WAL을 재생하고 그 이후의 WAL은 적용하지 않음
- 하지만 실제 WAL 파일이 물리적으로 삭제되지는 않음음
새로운 타임라인:
- 복구 완료 후 새로운 타임라인이 생성
- 이는 복구 시점 A 이후의 데이터베이스 변경사항이 원본과 다른 분기로 진행됨
WAL 아카이브 관리:
- 기존의 WAL 파일들은 repo-retention-archive 설정에 따라 관리
- 백업 보존 정책에 따라 불필요한 WAL 파일은 expire 명령어로 제거
시나리오:
1. 전체 백업 수행 (Full Backup) - WAL 위치: 000000010
2. WAL 아카이브 생성 - 000000011, 000000012, 000000013
3. 차등 백업 A 수행 - WAL 위치: 000000014
4. WAL 아카이브 생성 - 000000015, 000000016, 000000017
5. 차등 백업 B 수행 - WAL 위치: 000000018
repo1-retention-archive=1인 경우:
차등 백업 A의 시점에서는 000000014부터의 WAL만 유지
차등 백업 B의 시점에서는 000000018부터의 WAL만 유지
이전 WAL들(000000015-000000017)은 제거됨
이는 다음을 의미
각 백업 시점으로의 복구는 항상 가능
PITR(Point-in-Time Recovery)은 가장 최근 백업 이후의 시점으로만 가능
오래된 WAL 아카이브는 자동으로 제거되어 디스크 공간 절약
만약 repo1-retention-archive=2로 설정하면:
두 개의 연속된 백업 사이의 모든 WAL을 유지
더 많은 과거 시점으로의 PITR이 가능
하지만 더 많은 디스크 공간 사용
문서의 예시를 보면:
P00 DETAIL: repo1: 15-1 archive retention on backup 20241021-052042F, start = 00000002000000000000000C, stop = 00000002000000000000000D
P00 DETAIL: repo1: 15-1 archive retention on backup 20241021-052042F_20241021-052048D, start = 000000020000000000000012, stop = 000000020000000000000013
P00 INFO: repo1: 15-1 remove archive, start = 00000002000000000000000E, stop = 000000020000000000000011
여기서:
각 백업의 시작/종료 WAL은 유지됨
백업 사이의 중간 WAL(000000E-000000011)은 제거됨
그러나 백업의 일관성에 필요한 WAL은 항상 보존됨