[PostgreSQL] 아카이브 모드 백업을 이용한 특정 시점 복구 시나리오(Point In Time Recovery(PITR))

절차

  • 아카이브 모드 백업을 이용하여 특정 시점(PIRT) 으로 복구를 할 수 있습니다.
  • 해당 부분에 대한 시나리오를 수립하여 복구 진행 합니다.

아카이브 모드 백업을 이용한 특정 시점 복구 시나리오

  • 아카이브 모드 백업을 이용한 특정 시점 복구 시나리오를 정리해 보도록 하겠습니다.

Docker 컨테이너 실행

  • PostgreSQL Docker-Compose 를 실행합니다.
> docker-compose up


Dockar Container Bash 접근

  • Docker Container 정상 실행 되면, 아래 명령어를 통해 bash 로 접속합니다.
> docker exec -it postgres bash

계정 변경

  • 계정 변경을 진행합니다.
root@d5f06b09198b:/# su - postgres
postgres@d5f06b09198b:~$

경로 생성

  • 아카이브 파일을 백업 받을 경로를 생성합니다.
postgres@d5f06b09198b:~$ mkdir /var/lib/postgresql/data/arch


아카이브 모드 설정

  • postgresql.conf 파일에서 아카이브 모드를 설정합니다.
wal_level=replica
archive_mode=on
archive_command='cp %p /var/lib/postgresql/data/arch/%f' 
archive_timeout=60
log_destination=stderr
log_directory='../logs'
logging_collector=on
log_filename='postgresql-%Y-%m-%d_%H%M%S.log'

서버 재기동

  • 앞서 postgresql.conf 파일을 수정하였기 때문에, 서버를 다시 재 시작 해야 합니다.
> docker-compose stop
> docker-compose restart

테스트 진행할 테이블 및 데이터 삽입

  • 테스트를 진행하기 위해서 테이블 생성 및 데이터를 삽입합니다.
  • 다음과 같이 test_tbl1 테이블을 생성 후, 총 10개의 데이터를 삽입 하였습니다.
root@558e2e4d6820:/# psql -d adc -p 5432 -U mirero
psql (14.3 (Debian 14.3-1.pgdg110+1))
Type "help" for help.

adc=# create table test_tbl1(id int,name varchar(255));
CREATE TABLE
adc=# insert into test_tbl1 SELECT generate_series(1,10) AS id, md5(random()::text) AS descr;
INSERT 0 10
adc=# select count(1) from test_tbl1;
 count
-------
    10
(1 row)

adc=# select now();
              now
-------------------------------
   2022-07-07 10:43:35.387865+09
(1 row)

adc=# select pg_switch_wal();
 pg_switch_wal
---------------
 0/2000078
(1 row)

adc=# exit


pg_basebackup 적용

  • 앞서 데이터 10개를 넣은 시점의 데이터를 pg_basebackup 을 이용하여 전체 복사 진행합니다.
postgres@133f274fc4c6:~$ pg_basebackup -U mirero -p 5432 -D /var/lib/postgresql/data/backup

backup_label 확인

  • pg_basebackup 이 정상적으로 수행 되면, backup_label 이 생성됩니다.
  • backup_label 파일을 보면, 다음과 같은 정보들이 저장되어 있습니다.
postgres@133f274fc4c6:~/data/backup2$ cat backup_label
START WAL LOCATION: 0/7000028 (file 000000020000000000000007)
CHECKPOINT LOCATION: 0/7000060
BACKUP METHOD: streamed
BACKUP FROM: primary
START TIME: 2022-07-07 11:13:39 KST
LABEL: pg_basebackup base backup
START TIMELINE: 2

다시 test_tbl1 테이블에 10개의 데이터 삽입

  • 앞서 10개의 데이터를 가진 정보를 백업 해 놓았습니다.
  • 이제 다시 test_tbl1 테이블에 10개의 데이터를 삽입합니다.
root@558e2e4d6820:/# psql -U mirero -d adc
psql (14.3 (Debian 14.3-1.pgdg110+1))
Type "help" for help.

adc=# insert into test_tbl1 SELECT generate_series(1,10) AS id, md5(random()::text) AS descr;
INSERT 0 10

adc=# select pg_switch_wal();
 pg_switch_wal
---------------
 0/3000860
(1 row)

adc=# select now();
              now
-------------------------------
 2022-07-07 10:46:20.459847+09 # 복구 시점
(1 row)

또 다시 test_tbl1 테이블에 10개의 데이터 삽입

adc=# insert into test_tbl1 SELECT generate_series(1,10) AS id, md5(random()::text) AS descr;
INSERT 0 10
adc=# select count(1) from test_tbl1;
 count
-------
    30
(1 row)

adc=# select now();
             now
------------------------------
 2022-07-07 10:47:08.984964+09
(1 row)

pg_wal 파일 확인

  • 이쯤에 pg_wal 디렉터리 안에 있는 WAL 파일을 확인합니다.
postgres@133f274fc4c6:~/data/pg_wal$ ls
000000010000000000000004                  000000010000000000000005  archive_status
000000010000000000000004.00000028.backup  000000010000000000000006

서비스 중단

  • 이제 데이터 복구를 하기 위해서 서비스를 중단 합니다.
> docker-compose stop

BaseBackup 파일 이동

  • 앞서 /var/lib/postgresql/data/backup 경로에 basebackup 받은 파일들을 data_back_20220707 디렉터리를 생성 후, 해당 경로에 이동 시킵니다.


원본 디렉터리 arch 파일들 BaseBackup 안에 있는 arch 파일로 덮어씌우기

  • 다음으로 원본 data 디렉터리 안에 있는 arch 디렉터리 안에 있는 wal 파일 정보들을 앞서 옮겨놓은 data_back_20220707/backup/arch 디렉터리에 덮어 씌어줍니다.


원본 데이터 전체 삭제

  • 이제 원본 데이터 안에 있는 모든 파일들을 삭제 합니다.


백업 받은 파일들 원본 데이터 디렉터리로 복사

  • 앞서 data_back_20220707 안에 전체 데이터에비스를 백업 받은 파일들을 다시 원본 데이터 디렉터리로 복사합니다.


recovery.signal 파일 생성

  • 원본 디렉터리에 recovery.signal 파일을 생성합니다.


postgresql.conf 파일에서 recovery 관련 속성 수정

  • 이제 postgresql.conf 파일에서 recovery 관련 속성을 다음과 같이 수정합니다.
  • restore_command 는 복구할 아카이브 파일의 경로를 지정합니다.
  • recovery_target_time 은 복구할 시점을 지정합니다.
  • 여기서는 Insert 데이터가 20개 시점으로 지정하였습니다. 원래 전체 Data는 30개 입니다.
restore_command = 'cp /var/lib/postgresql/data/arch/%f %p'
recovery_target_time = '2022-07-07 10:46:20'

서버 재 기동

  • 이제 다시 서버를 재 기동 합니다.

복구 확인

  • 다시 test_tbl1 테이블의 전체 데이터 개수를 조회하니까 20개인 것을 확인할 수 있습니다.
  • 정상적으로 복구 된 것을 확인할 수 있습니다.
root@133f274fc4c6:/# psql -d adc -U mirero
psql (14.3 (Debian 14.3-1.pgdg110+1))
Type "help" for help.

adc=# select count(*) from test_tbl1;
 count
-------
    20
(1 row)

복구 모드 종료

  • 데이터베이스가 올바르게 복구된 것을 확인하였다면, pg_wal_replay_resume(); 명령을 통해 복구 모드를 종료할 수 있습니다.
  • 해당 명령을 수행하면 data/recovery.signal 파일이 사라집니다.
adc=# select pg_wal_replay_resume();
 pg_wal_replay_resume
----------------------

(1 row)
root@133f274fc4c6:/var/lib/postgresql/data# ls recovery.signal
ls: cannot access 'recovery.signal': No such file or directory
  • 위와 같이 정상적으로 recovery.signal 파일이 삭제된 것을 확인할 수 있습니다.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY