Innovating today, leading tomorrow

OpenSQL_Internals
[OpenSQL] PostgreSQL의 WAL 2 (Base Back-up and PITR)

[OpenSQL] PostgreSQL의 WAL 2 (Base Back-up and PITR)

Base Back-up

온라인 데이터베이스 백업은 크게 논리적인 백업(Logacal backup)과 물리적인 백업(Physical backup)으로 분류할 수 있습니다. 논리적인 백업은 대용량 데이터베이스의 백업이 오래 걸리고, 복원에는 더 오래 걸리는 반면, 물리적인 백업은 상대적으로 짧은 시간에 대용량 데이터베이스를 백업 및 복원할 수 있기 때문에 실제 시스템에서 매우 중요하고 유용한 기능입니다.

PostgreSQL 8.0 버전부터 물리적인 온라인 전체 백업 (Online physical full backup)이 가능해졌으며, 실행중인 데이터베이스 클러스터 전체의 스냅샷에 대한 백업을 베이스 백업(Base backup)이라고 합니다.

백업 라벨 파일

백업 라벨 파일(backup_label)은 기본 디렉토리(Base directory)의 최상위 레벨에 생성되며 위에서 얻은 체크포인트 위치를 비롯한 베이스 백업에 필요한 필수적인 정보들을 담고 있습니다.

백업 라벨 파일은 아래의 여섯 개의 정보를 담고 있고, PostgreSQL 11 버전부터는 일곱 개의 정보를 담고 있습니다.

백업 라벨 파일 정보

  • CHECKPOINT LOCATION
    • pg_start_backup으로 수행된 체크포인트의 위치를 나타내는 LSN을 기록합니다.
  • START WAL LOCATION
    • PITR에서는 사용되지 않고, 스트리밍 복제(Streaming replication)에서만 사용됩니다.
    • 복제 모드(Replication-mode)인 스탠바이(Standby) 서버에서 초기 시작 시점에 한 번만 읽기 때문에 ‘START WAL LOCATION’이라고 이름이 붙었습니다.
  • BACKUP METHOD
    • pg_start_backup과 pg_basebackup 중, 해당 베이스 백업을 만드는데 사용된 방식입니다.
  • BACKUP FROM
    • 해당 백업이 프라이머리(Primary) 서버와 스탠바이(Standby) 서버 중 어디서 생성되었는지를 기록합니다.
  • START TIME
    • pg_start_backup이 수행된 타임스탬프(Timestamp)를 기록합니다.
  • LABEL
    • pg_start_backup에 지정된 레이블(Label)을 기록합니다.
  • START TIMELINE
    • 백업이 시작될 때의 타임라인(Timeline)을 기록합니다
    • PostgreSQL 11 버전에서 소개된 온전성 검사(Sanity check)를 위해 저장된 값입니다.

백업 라벨 파일은 다음과 같이 확인할 수 있습니다.

postgres> cat /usr/local/pgsql/data/backup_label
START WAL LOCATION: 0/9000028 (file 000000010000000000000009)
CHECKPOINT LOCATION: 0/9000060
BACKUP METHOD: pg_start_backup
BACKUP FROM: master
START TIME: 2023-2-16 15:47:32 GMT
LABEL: Weekly Backup

백업 히스토리 파일

백업 히스토리 파일의 네이밍 방식은 다음과 같습니다.

{WAL segment}.{offset value at the time the base backup was started}.backup

Operation

  1. pg_start_backup 명령어 실행
  2. 아카이빙 명령어(ex. cp command)를 이용해 데이터베이스 클러스터 전체 스냅샷을 확보
  3. pg_stop_backup 명령어 실행

pg_start_backup

pg_start_backup은 베이스 백업을 준비합니다. WAL Chapter에서 설명했듯이 복구(Recovery) 절차는 REDO 포인트부터 시작하기 때문에 pg_start_backup은 명시적으로 REDO 포인트를 만들기 위해 베이스 백업을 시작할 때 체크포인트를 수행해야 합니다. 그리고 베이스 백업을 수행하는 동안에도 정기적인 체크포인트가 여러 번 수행될 수 있기 때문에 위에서 얻은 체크포인트의 위치를 pg_control 외의 다른 파일에 저장해둬야 합니다.

pg_start_backup은 다음 과정을 수행하여 이루어집니다.

  1. 전체 페이지 쓰기 모드(Full-page write mode)로 강제 전환
  2. (8.4 버전부터) 현재의 WAL 세그먼트 파일(Current WAL segment file)로 스위치(Switch)
  3. 체크포인트 수행
  4. backup_label 파일을 생성

pg_stop_backup

pg_stop_backup은 다음 과정을 수행하여 이루어집니다.

  1. pg_start_backup에 의해 강제로 전체 페이지 쓰기 모드로 전환되었다면, 이전 모드(Non-full-page writes mode)로 전환
  2. 백업 종료(Backup end)에 대한 XLOG 레코드(Record)를 남김
  3. WAL 세그먼트 파일(WAL segment file)을 스위치
  4. 백업 히스토리 파일(Backup history file)을 생성 이 파일은 backup_label 파일의 내용과 pg_stop_backup이 수행된 타임스탬프를 담고 있습니다.
  5. backup_label 파일을 삭제 이 파일은 데이터베이스 복구에 필요한 것이기 때문에, 백업 히스토리 파일로 복사되었다면 백업 대상인 원래의 데이터베이스 클러스터(Original database cluster)에서는 필요가 없기 때문에 삭제합니다.

Point-In-Time Recovery (PITR)

베이스 백업과 연속적인 아카이빙 방식으로 생성된 아카이브 로그를 이용해 특정 시점으로 데이터베이스 클러스터를 복구하는 방법을 Point-in-time recovery라고 합니다. 베이스 백업과 마찬가지로 PostgreSQL 8.0 버전부터 사용이 가능합니다.

Outline

12:05 GMT of 23 August, 2022 시점에 실수가 발생했다고 가정하겠습니다. 문제가 되는 데이터베이스 클러스터를 제거하고 이전에 만들었던 베이스 백업을 이용해 새로운 데이터베이스 클러스터를 복구해야 합니다.

PITR을 수행하기 위해 설정 파일의 restore_command와 recovery_target_time 파라미터를 설정해야 합니다. PostgreSQL 11 버전까지는 recovery.conf 파일에 설정해야 하며, PostgreSQL 12 버전부터는 postgresql.conf 파일에 설정을 하면 됩니다

PostgreSQL을 수행할 때 설정 파일에 위의 두 파라미터가 설정되어 있고, 데이터베이스 클러스터 내에 backup_label이 있으면, PITR 모드를 수행하게 됩니다.

recovery.signal file
recovery.signal file PostgreSQL 12 버전부터 recovery.conf 파일 제거되었고, 관련 파라미터들은 postgresql.conf에 작성되어야 합니다. 그리고 베이스 백업을 이용해 복구를 하기 위해 빈 파일인 recovery.signal 파일을 데이터베이스 클러스터 디렉토리에 생성해줘야 합니다.

만약 recover_target_time이 설정되어 있지 않다면 PostgreSQL은 아카이브 로그 파일을 끝까지 읽어서 리플레이를 수행합니다.

PITR vs Crash Recovery

Crash Recovery와 PITR은 기본적으로 동일한 동작을 수행하며 다음과 같은 두 가지 차이가 있습니다.

  • WAL 세그먼트 파일을 읽는 위치
    • Crash Recovery : 베이스 디렉토리 아래에 있는 pg_wal 서브 디렉토리
    • PITR : archive_command 파라미터에 설정된 아카이브 디렉토리
  • 체크포인트 위치를 읽는 파일
    • Crash Recovery : pg_control 파일
    • PITR : backup_label 파일

타임라인

PostgreSQL에서 타임라인은 원본 데이터베이스 클러스터(Original database cluster)와 복원된 데이터베이스 클러스터(Recovered database cluster)를 구분하는데 사용되며, PITR의 핵심 개념입니다.

타임라인 아이디

각 타임라인은 타임라인 아이디를 부여받습니다. 타임라인 아이디는 4-byte unsigned integer로 1부터 시작합니다.

각각의 데이터베이스 클러스터에는 개별적인 타임라인 아이디가 할당됩니다. 처음 initdb 유틸리티를 통해 생성된 초기 데이터베이스 클러스터의 타임라인 아이디는 1입니다. 데이터베이스 클러스터가 복구될 때마다 타임라인 아이디는 1씩 증가합니다. 예를 들어, 이전 섹션에서 다뤘던 원본 데이터베이스 클러스터로부터 복원된 데이터베이스 클러스터의 타임라인 아이디는 2입니다.

타임라인 히스토리 파일

PITR 과정이 완료되면 ‘00000002.history’과 같은 이름의 타임라인 히스토리 파일이 아카이브 디렉토리와 pg_xlog(또는 pg_wal) 서브 디렉토리에 생성됩니다. 이 파일은 어느 타임라인이 언제 분기되었는지를 기록합니다.

타임라인 히스토리 파일은 최소 한 줄 이상이 쓰여져 있고, 각 줄은 아래 내용을 담고 있습니다.

  • timelineId : 복구에 사용된 아카이브 로그의의 타임라인 아이디
  • LSN : WAL 세그먼트 파일의 스위치가 발생한 LSN 위치
  • reason : 사람이 읽을 수 있는 형태로 작성된 타임라인이 변경된 이유에 대한 설명

하단의 타임라인 히스토리 파일은 다음과 같이 해석할 수 있습니다.

postgres> cat /home/postgres/archivelogs/00000002.history
1 0/A000198 before 2022-6-21 12:05:00.861324+00

“타임라인 아이디가 2인 데이터베이스 클러스터가 타임라인 아이디 1인 베이스 백업으로부터 복구되었고, 아카이브 로그를 0/A000198 위치까지 리플레이함으로 ‘2022-6-21 12:05:00.861324+00’ 시점 이전까지 복구되었다.”

Operation

  1. REDO 포인트를 찾기 위해 내부 함수인 read_backup_label을 이용해 backup_label 파일에 있는 ‘CHECKPOINT LOCATION’을 읽음
  2. PITR 관련 파라미터인 restore_command, recovery_target_time를 설정 파일로부터 읽음
    • PostgreSQL 11 버전까지 : recovery.conf
    • PostgreSQL 12 버전부터 : postgresql.conf
  3. WAL 데이터를 리플레이
    • restore_command에 의해 아카이브 영역(Archival area)에서 임시 영역(Temporary area)으로 복사된 아카이브 로그를 읽어서 XLOG 레코드(XLOG record)를 리플레이합니다. 임시 영역으로 복사된 로그 파일들은 사용된 후에 삭제됩니다.
    • 이 장에서 다룬 예시에서는 타임스탬프(timestamp) ‘2022-8-24 12:05:00’ 이전 시점까지의 WAL 데이터가 리플레이 됩니다.
    • 만약 설정 파일(recovery.conf 또는 postgresql.conf)에 recovery_target_time이 설정되어 있지 않으면 아카이브 로그의 끝까지 레플레이 됩니다.
    • WAL 데이터 중 Commit/abort 레코드에는 타임스탬프가 적혀있기 때문에 recovery_target_time까지의 수행이 가능합니다.
  4. 타임라인 히스토리 파일(Timeline history file)을 생성
    • 복구가 끝나면 ‘00000002.history’과 같은 이름의 타임라인 히스토리 파일이 pg_xlog 또는 pg_wal 서브 디렉토리 생성됩니다.
    • 만약 아카이브 로그가 활성화 되어 있다면 아카이브 디렉토리에도 동일한 이름의 파일이 생성됩니다.
    • 해당 파일이 담는 내용과 역할은 다음 섹션에서 설명합니다.

타임라인 히스토리 파일은 두 번째와 그 이후의 PITR 과정에서 중요한 역할을 합니다. 두 번째 복구를 시도하는 예시를 통해 확인을 해보겠습니다.

타임라인 아이디가 2인 이미 한 번 복원된 데이터베이스 클러스터를 운영 중에 12:15:00 시점에 문제가 발생했다고 가정해보겠습니다.

recovery.conf(또는 postgresql.conf)의 설정은 다음과 같습니다.

  • recovery_targte_time은 문제가 발생한 시점으로 설정하며, recovery_target_timeline은 해당 타임라인을 따라 복구하기를 원하는 타임라인 아이디를 설정합니다.

restore_command = ‘cp /mnt/server/archivedir/%f %p’
recovery_target_time = “2022-8-24 12:15:00 GMT”
recovery_target_timeline = 2

PostgreSQL을 다시 시작하면 PITR 모드로 돌입하며 타임라인 아이디 2를 따라 데이터베이스 클러스터의 복구를 시작합니다. 그림 10.5는 이 상황을 설명하며 수행 절차는 다음과 같습니다.

  1. PostgreSQL은 backup_label 파일에서 ‘CHECKPOINT LOCATION’의 값을 읽음
  2. PostgreSQL은 recovery.conf(또는 postgresql.conf) 파일에서 restore_command, recovery_target_time, recovery_target_timeline의 값을 읽음
  3. PostgreSQL은 recovery_target_timeline 파라미터 값에 해당하는 타임라인 히스토리 파일 ‘00000002.history’을 읽음
  4. PostgreSQL은 WAL 데이터를 다음 절차에 따라 리플레이 함
    1. REDO 포인트부터 00000002.history파일에 기록된 LSN ‘0/A000198’까지 타임라인 아이디 1에 해당하는 아카이브 로그를 읽어서 WAL 데이터를 리플레이
    2. LSN ‘0/A000198’ 이후부터 타임스탬프 ‘2022-8-24 12:15:00’시점까지 타임라인 아이디 2에 해당하는 아카이브 로그를 읽어서 WAL 데이터를 리플레이
  5. 복구가 완료되면, 타임라인 아이디는 3으로 증가하며 새로운 타임라인 히스토리 파일인 00000003.history 파일이 pg_xlog(또는 pg_wal) 서브 디렉토리와 아카이브 디렉토리에 생성됨

postgres> cat /home/postgres/archivelogs/00000003.history
1 0/A000198 before 2022-8-24 12:05:00.861324+00
2 0/B000078 before 2022-8-24 12:15:00.927133+00

한 번이라도 PITR을 수행했다면, 적절한 타임라인 히스토리 파일을 사용하기 위해 타임라인 아이디를 명시해줘야 합니다. 이처럼 타임라인 히스토리 파일은 데이터베이스 클러스터의 히스토리를 기록할 뿐 아니라 PITR 과정에 대한 복구 지침 문서이기도 합니다.

지금까지 PostgreSQL의 WAL 2 (Base Back-up and PITR)에 관해 알아보았습니다
‘PostgreSQL의 WAL 3 (Streaming Replication)’를 바로 이어서 확인해보세요!

광고성 정보 수신

개인정보 수집, 활용 목적 및 기간

(주)티맥스티베로의 개인정보 수집 및 이용 목적은 다음과 같습니다.
내용을 자세히 읽어보신 후 동의 여부를 결정해 주시기 바랍니다.

  • 수집 목적: 티맥스티베로 뉴스레터 발송 및 고객 관리
  • 수집 항목: 성함, 회사명, 회사 이메일, 연락처, 부서명, 직급, 산업, 담당업무, 관계사 여부, 방문 경로
  • 보유 및 이용 기간: 동의 철회 시까지

※ 위 개인정보 수집 및 이용에 대한 동의를 거부할 권리가 있습니다.
※ 필수 수집 항목에 대한 동의를 거부하는 경우 뉴스레터 구독이 제한될 수 있습니다.

개인정보의 처리 위탁 정보
  • 업체명: 스티비 주식회사
  • 위탁 업무 목적 및 범위: 광고가 포함된 뉴스레터 발송 및 수신자 관리
 

개인정보 수집 및 이용

개인정보 수집, 활용 목적 및 기간

(주)티맥스티베로의 개인정보 수집 및 이용 목적은 다음과 같습니다. 내용을 자세히 읽어보신 후 동의 여부를 결정해 주시기 바랍니다.

  • 수집 목적: 티맥스티베로 뉴스레터 발송 및 고객 관리
  • 수집 항목: 성함, 회사명, 회사 이메일, 연락처, 부서명, 직급, 산업, 담당업무, 관계사 여부, 방문 경로
  • 보유 및 이용 기간: 동의 철회 시까지

※ 위 개인정보 수집 및 이용에 대한 동의를 거부할 권리가 있습니다.
※ 필수 수집 항목에 대한 동의를 거부하는 경우 뉴스레터 구독이 제한될 수 있습니다.

개인정보의 처리 위탁 정보

  • 업체명: 스티비 주식회사
  • 위탁 업무 목적 및 범위: 광고가 포함된 뉴스레터 발송 및 수신자 관리
  •