PostgreSQL 백업 방법
PostgreSQL 은 장애시 복구를 위해 3가지 백업방법이 있습니다.
3가지 방법은 SQL 덤프 / 파일 시스템 기반 백업 / 아카이브 모드 백업입니다.
이 중 아카이브 모드 백업에 대해 다뤄보겠습니다.
아카이브 모드 백업
PostgreSQL 은 미리쓰기기로그 (WAL, Write ahead log) 을 pg_xlog 디렉터리에서 관리합니다.
이 로그는 데이터베이스에 대한 모든 조작 기록을 보관하고 있어,
서버가 갑자기 비정상적으로 종료된경우 데이터파일에 적용하지 못한 작업은 이 로그파일을 읽어서 복구할 수 있습니다.
이 로그를 다른 서버로 보내, 이 로그의 내용을 그대로 실행하여 원본 서버와 똑같이 만들수 있습니다.
또한 특정시점 까지만 실행하도록 하여, 특정시점으로 복구할 수도 있습니다.
이 방법은 SQL 덤프 / 파일 시스템 백업보다 복잡하지만 다양한 장점이 있습니다.
아카이브 모드 백업의 장점
1. 파일 시스템을 백업할 때, 파일 시스템 상태에 대해서 신경 쓸 필요가 없습니다.
즉 파일 시스템의 스냅샷 기능을 고려할 필요가 없습니다.
2. 복원 작업에 필요한 WAL 파일의 수량은 제한이 없기 때문에, 백업을 시작한 시점 이후에 생긴 WAL 로그파일만 보관된다면, 백업 기간이 아무리 길어져도 복구가 가능합니다.
이는 전체 백업을 자주 할 수 없는 대용량 데이터베이스 백업에서 유용합니다.
3. 복원을 할 때 WAL 파일의 내용을 끝까지 실행할 필요가 없습니다. 이 복구를 특정시점 복구 point-in-time recovery 라고 합니다.
4. 다른 호스트에 전체백업을 복원한 후, 운영서버에서 만들어진 WAL 파일을 주기적으로 다른 호스트로 복사하여 반영해 놓으면, 운영서버에서 장애가 발생할 때 빠르게 복구가 가능합니다.
아카이브 모드 백업의 단점
이 작업도 특정 데이터베이스만을 대상으로 할 수 없고 전체를 대상으로 합니다.
또한 아카이브 로그를 저장해야 하기 때문에 디스크의 여유 공간도 많이 필요합니다.
따라서 아카이브 로그 파일이 계속 쌓이지 않도록 관리해 주어야 합니다.
참고로 계속 쌓이지 않도록 파일을 로테이션 방식으로 재사용할 수 있도록 설정할 수도 있습니다.
WAL 아카이브 파일
WAL 아카이브 파일의 구조
PostgreSQL 은 데이터베이스 조작시 순차적인 WAL 레코드를 만듭니다.
이 레코드는 물리적인 디스크 공간에 저장하기 위해 16MB 인 WAL 세그먼트 파일로 나뉘어 저장합니다.
이 파일의 이름은 WAL 순서에 따른 해당 번호 파일로 부여되며,
WAL 아카이브 파일을 만들지 않도록 설정하면 몇개만 만들어지며 사용하지 않는 로그파일을 로테이션 방식으로 재사용 합니다.
내부적으로 WAL 레코드들의 상태 정보를 찾아, 체크포인트 작업이 일어난 것에 대해서는 사용하지 않는 상태로 바꾸고 그 자리에 새로운 WAL 레코드를 기록하는 방식으로 재사용하게 됩니다.
WAL 아카이브 파일 만드는 방법
아카이브 백업과 복구를 위해 WAL 아카이브 파일을 만드는 방법을 설정하겠습니다.
아카이브 파일을 만들기 위해 postgresql.conf 파일에 아래 3가지의 프로터리를 설정해 줍니다.
프로퍼티 | 값 |
wal_level | replica 혹은 logical |
archive_mode | on |
archive_command | 완료된 WAL 파일 세그먼트를 아카이브하기 위해 실행하는 로컬 쉘 명령으로 사용자가 지정 예약어 %p : WAL 로그파일 절대경로 %f : 보관할 ㄹ로그 파일 이름 |
archive_command 는 아래 URL 을 참고해 주세요.
postgresql.kr/docs/9.6/runtime-config-wal.html#GUC-ARCHIVE-COMMAND
제 환경에서의 프로퍼티는 아래와 같습니다.
1
2
3
|
archive_mode = on
archive_command = 'test ! -f /var/lib/postgresql/ARCHIVE/%f && cp %p /var/lib/postgresql/ARCHIVE/%f'
archive_timeout = 1
|
cs |
위처럼 설정을 하면 pg_wal 경로에 아카이브 파일이 자동으로 생기게 됩니다.
아카이브 파일 1번은 영구보관된 상태, 2번은 영구보관으로 이동이 완료된 상태, 3번은 wal 로그폴더에 있는 상태입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
postgres@VirtualBox:~$ ls -al 10/main/pg_wal
-rw------- 1 postgres postgres 16777216 4월 4 22:19 000000010000000000000002
-rw------- 1 postgres postgres 16777216 4월 4 22:19 000000010000000000000003
drwx------ 2 postgres postgres 4096 4월 4 22:19 archive_status
postgres@VirtualBox:~$ ls -al 10/main/pg_wal/archive_status/
-rw------- 1 postgres postgres 0 4월 4 22:19 000000010000000000000002.done
postgres@VirtualBox:~$ ls -al ARCHIVE/
-rw------- 1 postgres postgres 16777216 4월 4 22:14 000000010000000000000001
-rw------- 1 postgres postgres 16777216 4월 4 22:19 000000010000000000000002
|
cs |
WAL 아카이브 파일 만들 때 주의점
이 archive_command 명령은 PostgreSQL 서버를 실행했던 시스템 사용자 권한으로 실행되어야 합니다.
또한 실행 리턴값은 성공한 경우 0, 아닌경우 0 이 아니게 반환되도록 해야 합니다.
그래야 이 리턴값으로 파일을 잘 보관했는지 실패했는지 판단하고 실패한경우 재처리 할 수 있기 떄문입니다.
WAL 파일을 저장할 때, 그 저장장치의 속도도 고려해야 하는데
정상적으로 진행된다 하더라도 WAL 파일이 만들어지는 속도가 보관하는 속도보다 빠르다면, 중간내용이 없이 보관되는 문제가 발생할 수 있기 때문입니다.
WAL 파일은 트랜잭션 정보만 있기 때문에 conf 파일의 변경사항은 수동으로 작업을 해줘야 합니다.
아카이브 명령은 WAL 파일 가운데 서버에 모두 반영된 (rollback 이나 commit 되어 checkpoint 작업이 끝난) 파일에 대해서 실행됩니다.
즉, 작업량이 아주 적은 데이터베이스인 경우 아카이브 명령이 실행될 간격이 길어지게 됩니다.
이 사이 데이터베이스 장애가 생긴다면 간격이 길어진만큼 손실될 가능성이 크기 때문에 archive_timeout 값을 짧게 하여 강제로 세그먼트 파일을 따로 저장하도록 할 수 있습니다.
베이스(전체) 백업 만들기
전체백업을 만드는 방법은 pg_basebackup 툴을 사용하는 방법입니다.
이 툴을 이용하면 일반적인 파일이나 tar 묶음 파일로 전체 백업파일을 만들 수 있습니다.
이 전체백업을 이용해서 복구작업을 하는 경우, 전체백업 시점부터 복사가 끝난시점까지 만들어진 모든 WAL 파일을 보관하고 이썽야 합니다.
WAL 의 어떤 파일부터 필요한지는, 전체백업의 복구에 필요한 WAL 파일의 첫번째 이름을 보면 됩니다.
이 전체백업과 아카이브 백업 구조를 시각화로 표현하면 다음과 같습니다.
pg_basebackup 사용방법
pg_basebackup 을 BACKUP 경로에 받습니다. wal 로그폴더는 백업받지 않으며, 체크포인트는 고속모드로 설정합니다.
결과파일인 backup_label 을 보면 WAL 파일은 4번째 까지 적용되었다고 나와있습니다. 4번째 이후는 보관해야겠죠?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
postgres@VirtualBox:~/BACKUP$ pg_basebackup -D /var/lib/postgresql/BACKUP -c fast -X none
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
postgres@VirtualBox:~$ ls -al /var/lib/postgresql/BACKUP
합계 88
drwxrwxr-x 19 postgres postgres 4096 4월 4 22:37 .
drwxr-xr-x 8 postgres postgres 4096 4월 4 22:36 ..
-rw------- 1 postgres postgres 3 4월 4 22:37 PG_VERSION
-rw------- 1 postgres postgres 206 4월 4 22:37 backup_label
drwx------ 7 postgres postgres 4096 4월 4 22:37 base
drwx------ 2 postgres postgres 4096 4월 4 22:37 global
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_commit_ts
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_dynshmem
drwx------ 4 postgres postgres 4096 4월 4 22:37 pg_logical
drwx------ 4 postgres postgres 4096 4월 4 22:37 pg_multixact
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_notify
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_replslot
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_serial
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_snapshots
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_stat
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_stat_tmp
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_subtrans
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_tblspc
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_twophase
drwx------ 3 postgres postgres 4096 4월 4 22:37 pg_wal
drwx------ 2 postgres postgres 4096 4월 4 22:37 pg_xact
-rw------- 1 postgres postgres 88 4월 4 22:37 postgresql.auto.conf
postgres@VirtualBox:~/BACKUP$ cat backup_label
START WAL LOCATION: 0/4000028 (file 000000010000000000000004)
CHECKPOINT LOCATION: 0/4000060
BACKUP METHOD: streamed
BACKUP FROM: master
START TIME: 2021-04-04 22:37:12 KST
LABEL: pg_basebackup base backup
|
cs |
pg_wal 경로에 가면 어떤 WAL 파일부터 보관해야 하는지시점이 저장됩니다.
1
2
3
4
5
6
|
postgres@VirtualBox:~/10/main/pg_wal$ ll
-rw------- 1 postgres postgres 16777216 4월 4 22:43 00000001000000000000000A
-rw------- 1 postgres postgres 302 4월 4 22:43 00000001000000000000000A.00000028.backup
-rw------- 1 postgres postgres 16777216 4월 4 22:43 00000001000000000000000B
-rw------- 1 postgres postgres 16777216 4월 4 22:42 00000001000000000000000C
drwx------ 2 postgres postgres 4096 4월 4 22:43 archive_status/
|
cs |
아카이브 모드 백업을 이용한 복구
장애로 인해 백업받은 파일로 복구를 해야하는 경우에 대해 설명합니다.
절차
1. 서버가 실행중이라면 서버를 중지합니다.
2. 운영에 사용되던 기존경로에 있던 파일들을 다른 경로로 저장합니다. (원본파일은 항상 보관하도록 설정)
3. 기존경로에 있던 폴더/파일을 전부 삭제합니다.
4. 백업받은 파일(pg_wal 경로 제외)을 기존 위치에 복사합니다. 이 때 파일 소유자나 권한 등은 동일해야 합니다.
pg_wal 경로는 복구작업을 진행하면서 자동으로 만들어 집니다.
만약 WAL 백업파일이 없다면, 2단계에서 복사한 pg_wal 경로의 로그파일을 기존경로로 복사합니다.
5. 데이터베이스 클러스터 디렉토리 안에 recovery.conf 파일을 만듭니다.
6. 서버를 실행합니다.
7. 서버가 복구모드로 구동되면서 필요한 WAL 파일을 찾아 반영되지 않은 트랜잭션을 반영합니다.
8. 복구작업이 끝나면 복구모드로 재실행되는것을 막기 위해 recovery.conf 를 recovery.done 으로 변경합니다.
이 절차는 특정시점 복구 없이 마지막 WAL 파일까지 복구하는 방식입니다.
특정시점으로 복구를 원하는 경우에는 5단계의 recovery.conf 파일에 필요한 프로퍼티를 설정합니다.
특정시점 복구 방법
1. 장애상황 발생
1
2
3
4
5
6
7
8
9
|
# 모든 데이터파일이 유실됨
postgres@VirtualBox:~/10/main$ rm -rf *
# PostgreSQL 프로세스 다운됨
postgres@VirtualBox:~/10/main$ ps -ef | grep post
root 4034 4026 0 21:58 pts/0 00:00:00 su - postgres
postgres 4035 4034 0 21:58 pts/0 00:00:00 -su
postgres 5612 4035 0 23:08 pts/0 00:00:00 ps -ef
postgres 5613 4035 0 23:08 pts/0 00:00:00 grep --color=auto post
|
cs |
2. 백업받은 파일을 기존 위치에 복사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
# 백업경로의 전체백업 파일
postgres@VirtualBox:~/BACKUP$ ll
합계 88
drwx------ 19 postgres postgres 4096 4월 4 22:44 ./
drwxr-xr-x 8 postgres postgres 4096 4월 4 23:07 ../
-rw------- 1 postgres postgres 3 4월 4 22:43 PG_VERSION
-rw------- 1 postgres postgres 206 4월 4 22:43 backup_label
drwx------ 7 postgres postgres 4096 4월 4 22:43 base/
drwx------ 2 postgres postgres 4096 4월 4 22:43 global/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_commit_ts/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_dynshmem/
drwx------ 4 postgres postgres 4096 4월 4 22:43 pg_logical/
drwx------ 4 postgres postgres 4096 4월 4 22:43 pg_multixact/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_notify/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_replslot/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_serial/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_snapshots/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_stat/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_stat_tmp/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_subtrans/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_tblspc/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_twophase/
drwx------ 3 postgres postgres 4096 4월 4 22:43 pg_wal/
drwx------ 2 postgres postgres 4096 4월 4 22:43 pg_xact/
-rw------- 1 postgres postgres 88 4월 4 22:43 postgresql.auto.conf
# 위 파일을 기존경로로 복사
postgres@VirtualBox:~$ cp -r BACKUP/* 10/main/
postgres@VirtualBox:~$ cd 10/main
# 기존경로에 복사된 파일 확인
postgres@VirtualBox:~/10/main$ ll
합계 88
drwx------ 19 postgres postgres 4096 4월 4 23:20 ./
drwxr-xr-x 3 postgres postgres 4096 3월 14 19:09 ../
-rw------- 1 postgres postgres 3 4월 4 23:20 PG_VERSION
-rw------- 1 postgres postgres 206 4월 4 23:20 backup_label
drwx------ 7 postgres postgres 4096 4월 4 23:20 base/
drwx------ 2 postgres postgres 4096 4월 4 23:20 global/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_commit_ts/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_dynshmem/
drwx------ 4 postgres postgres 4096 4월 4 23:20 pg_logical/
drwx------ 4 postgres postgres 4096 4월 4 23:20 pg_multixact/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_notify/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_replslot/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_serial/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_snapshots/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_stat/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_stat_tmp/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_subtrans/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_tblspc/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_twophase/
drwx------ 3 postgres postgres 4096 4월 4 23:20 pg_wal/
drwx------ 2 postgres postgres 4096 4월 4 23:20 pg_xact/
-rw------- 1 postgres postgres 88 4월 4 23:20 postgresql.auto.conf
|
cs |
3. recovery.conf 파일 생성
postgresql.conf 파일이 있는 경로에 생성해줍니다.
restore_command 는 백업받았던 WAL 폴더 경로를
restore_target_time 을 복구시점을 설정해 줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
postgres@VirtualBox:~$ ls -al /etc/postgresql/10/main
합계 64
drwxr-xr-x 3 postgres postgres 4096 4월 4 23:27 .
drwxr-xr-x 3 postgres postgres 4096 3월 14 19:09 ..
drwxr-xr-x 2 postgres postgres 4096 3월 14 19:09 conf.d
-rw-r--r-- 1 postgres postgres 315 3월 14 19:09 environment
-rw-r--r-- 1 postgres postgres 143 3월 14 19:09 pg_ctl.conf
-rw-r----- 1 postgres postgres 4686 3월 14 23:44 pg_hba.conf
-rw-r----- 1 postgres postgres 1636 3월 14 23:44 pg_ident.conf
-rw-r--r-- 1 postgres postgres 23465 4월 4 22:14 postgresql.conf
-rw-rw-r-- 1 postgres postgres 98 4월 4 23:27 recovery.conf
-rw-r--r-- 1 postgres postgres 317 3월 14 19:09 start.conf
postgres@VirtualBox:/etc/postgresql/10/main$ cat recovery.conf
restore_command = 'cp /var/lib/postgresql/ARCHIVE/%f %p'
restore_target_time = '2021-04-05 00:21:28'
|
cs |
4. PostgreSQL 실행
1
2
3
4
5
6
7
8
9
10
11
|
postgres@VirtualBox:~$ pg_ctl start "-o -c config_file=$PGCONF/postgresql.conf"
waiting for server to start....2021-04-05 00:42:18.299 KST [7748] LOG: listening on IPv4 address "127.0.0.1", port 5432
2021-04-05 00:42:18.300 KST [7748] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-04-05 00:42:18.309 KST [7749] LOG: database system was interrupted; last known up at 2021-04-05 00:19:30 KST
..2021-04-05 00:42:20.950 KST [7749] LOG: database system was not properly shut down; automatic recovery in progress
2021-04-05 00:42:20.952 KST [7749] LOG: redo starts at 0/20000028
2021-04-05 00:42:20.953 KST [7749] LOG: redo done at 0/240000D0
2021-04-05 00:42:20.953 KST [7749] LOG: last completed transaction was at log time 2021-04-05 00:21:28.326009+09
2021-04-05 00:42:21.097 KST [7748] LOG: database system is ready to accept connections
done
server started
|
cs |
'Database > PostgreSQL' 카테고리의 다른 글
[PostgreSQL] PostgreSQL XID 설명 (0) | 2021.04.05 |
---|---|
[PostgreSQL] PostgreSQL Vacuum 이란 ( FSM, VM, TID ) (0) | 2021.04.05 |
[PostgreSQL] PostgreSQL 파일 시스템 방식의 백업과 복원 (0) | 2021.04.02 |
[PostgreSQL] PostgreSQL 데이터베이스 데이터파일 경로 확인 방법 (0) | 2021.04.02 |
[PostgreSQL] PostgreSQL SQL 덤프 방식의 백업과 복원 (0) | 2021.04.02 |