25.3. 아카이브 모드 백업(Continuous Archiving)과, 특정시점 복구(Point-in-Time Recovery, PITR)

25.3.1. WAL의 아카이브 파일 만들기
25.3.2. 베이스 백업 만들기
25.3.3. 저수준 API를 이용한 베이스 백업 만들기
25.3.4. 아카이브 모드 백업을 이용한 복구
25.3.5. 타임라인
25.3.6. 팁과 예제
25.3.7. 위험부담

PostgreSQL에서는 미리 쓰기 기록 (선행 기입 로그, write ahead log, WAL)을 데이터베이스 클러스터 디렉터리 안 pg_wal/ 디렉터리에서 관리하고 있다. 이 로그는 데이터베이스의 데이터 파일에 대한 모든 조작 기록을 보관하고 있다. 이 로그를 만드는 가장 첫번째 이유는 서버가 갑자기 중지되었을 경우, 미처 데이터 파일에 적용하지 못한 작업(checkpoint 작업이 안된)을 이 로그에서 읽어서 그대로 다시 실행해서, 서버를 안전하게 복구하기 위해서다. 이 기법을 그대로 응용하면, 이 로그를 준비된 다른 서버로 보내서, 이 로그의 내용을 그대로 재실행 하면, 원본 서버와 똑 같은 상태를 만들 수 있다. (물론 특정 시점까지만 실행하면, 데이터베이스를 특정시점으로 되돌릴 수도 있다.) 여기서 소개하고 있는 백업과 복원 방법은 지금까지 이야기한 것보다 많이 복잡하다. 하지만, 다음과 같은 장점이 있다:

참고

pg_dump 명령과 pg_dumpall 명령을 이용해서 만든 백업 파일은, 데이터베이스의 논리적 백업이기 때문에 실재 데이터베이스에서 일어난 모든 기록을 보관하고 있지 않다. 그래서, 파일 시스템 기반 백업이나, 아카이브 모드 백업에서는 사용할 수 없다.

파일 시스템 기반 백업에서 이야기한 것과 같이, 이 백업/복원 작업도 데이터베이스의 특정 부분을 대상으로 할 수 없고, 데이터베이스 클러스터 전체를 대상으로 한다. 또한 아카이브 로그를 다루는 여유 공간이 상당히 필요하다: 베이스 백업량도 많고, 업무량도 많아서 WAL 파일을 많이 만든다면, 베이스 백업과, WAL 파일을 처리하기 위한 비용도 상당히 많이 든다. 하지만, 고가용성 데이터베이스 시스템으로 운영해야하는 환경에서는 여전히 이 방법이 제일 추천할 만한 방법이다.

이 아카이브 모드 백업(다른 데이터베이스에서는 흔히 온라인 백업이라고 함)을 이용한 복원 작업을 무사히 마치려면, 적어도 베이스 백업을 시작하기 직전의 WAL 파일부터, 베이스 백업이 끝나는 시점까지 새로 생긴 WAL 파일들이 복원 작업을 할 때 필요하다. 그래서, 이 백업 방식을 사용하려면, 먼저, 아카이브 로그 백업에 대한 정책을 수립하고, 베이스 백업을 진행해야한다.

25.3.1. WAL의 아카이브 파일 만들기

내부적으로 PostgreSQL 시스템은 데이터베이스를 조작하는데, 끊임 없이 순차적으로 WAL 레코드를 만든다. 이것을 물리적인 디스크 공간에 저장하기 위해서, WAL 세그먼트 파일로 나눠서 저장한다. 이 하나의 WAL 파일은 기본적으로 16MB 크기의 파일이다 (이 크기는 initdb 명령으로 지정한다). 이 파일의 이름은 WAL 순서에 따른 해당 번호를 사용한다. WAL 아카이브 파일을 만들지 않도록 설정하면, 이 파일은 몇 개만 만들어지며, 이것 가운데 더이상 사용하지 않는 로그 파일을 찾아서 재사용한다. 내부적으로 WAL 레코드들의 상태 정보를 찾아서, 이미 체크포인트 작업이 일어난 것에 대해서는 더 이상 사용하지 않는 상태로 바꾸고, 그 자리에 새로운 WAL 레코드를 기록하는 방식으로 재사용한다.

WAL 아카이브 파일을 만든다면, 어떤 WAL 세그먼트 파일을 재사용하기 전에, 기존에 있던 WAL 레코드 정보를 다른 곳(같은 호스트 내 일 수도 있고, NFS 마운트 위치일 수도 있고, 심지어 테이프 같은 곳일 수도 있다)에 따로 보관하는 작업을 한다. 이 보관하는 작업에 대한 방법은 관리자가 직접 지정한다. 이미 똑 같은 이름의 파일이 있는 경우에 대해서도 관리자가 결정하도록 한다. 단지 PostgreSQL 서버에서는 WAL 세그먼트 파일을 재사용할 때, 그 전에 관리자가 설정한 따로 보관하는 방법에 따른 그 작업만 수행한다. 이 아카이브 보관 방법으로 단순하게, cp 명령이 이용할 수도 있고, 이보다 훨씬 복잡한 사용자 정의 쉘 스크립트일 수도 있고, 또한 백업 솔루션의 명령이 될 수도 있다. 이 부분에 대해서는 전적으로 관리자 몫이다.

WAL 아카이브 파일을 만드려면, wal_level 환경 설정 매개 변수의 값으로 replica 또는 그 이상으로 지정한다. 다음, archive_mode 환경 설정 매개 변수 값은 on, archive_command 환경 설정 매개 변수 값에는 적당한 시스템 명령어를 지정한다. 이 설정은 모두 postgresql.conf 파일 안에서 설정한다. archive_command 값으로 지정할 쉘 명령어에는 %p (WAL 로그파일 절대경로), %f (보관할 로그 파일 이름) 예약 인자를 사용할 수 있다. % 글자 그대로 써야할 경우면, %%로 입력한다. 일반적으로 이 설정 값은 다음과 같은 형태로 사용된다:

archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'  # Unix
archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'  # Windows

윗 설정은 단순하게, WAL 세그먼트 파일을 /mnt/server/archivedir 디렉터리로 이름을 똑같게 해서 복사하는 설정이다. 윗 예제는 Unix와, Windows 운영체제에 대한 한 예제일 뿐이다. 실제 설정은 해당하는 운영체제에 맞게 변경 되어야한다. %p %f 예약 인자들은 다음과 같이 변경되어 실재로 명령이 실행된다:

test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065

이렇게 실행 된다면, WAL 로그파일을 항상 특정 위치에 새롭게 만드는 작업을 하게될 것이다.

이 아카이브 명령의 실행은 PostgreSQL 서버들 실행했던 시스템 사용자 권한으로 실행된다. 그래서, WAL 세그먼트 파일을 처리하는 것과 같이 이 파일의 아카이브 파일의 처리에 있어서도 운영체제 차원은 보안 정책을 고려해야한다. 누구나 읽고 덮어쓰고, 지울 수 있다면, 치명적인 보안 사고가 발생할 수 있음을 주의해야 한다.

또 하나 주의할 사항은 아카이브 명령의 쉘 실행 리턴값은 그 명령이 성공 했을 경우 0(zero), 아니면, 그 밖에 값이 되도록 해야한다. PostgreSQL 서버는 이 리턴값으로 로그 파일을 잘 보관했는지, 실패했는지를 판단하고, 성공했다면, 원본 로그 파일을 지우거나 재사용하고, 실패하면, 성공할 때까지 재시도한다.

이 아카이브 명령은 이미 있는 파일을 덮어쓰지 않도록 해야한다. 덮어 쓰는 경우가 생기면, 관리 입장에서 복원 작업 시 의도되지 않는 오류가 발생 할 수 있다. (해당 파일이 이미 다른 데이터베이스에서 생성했거나, 그것을 사용할 수도 있기 때문이다.) 그 로그 파일이 이미 있다면, 끊임 없이 오류를 발생하며, 이 문제는 관리자가 파악해서, 수동으로 처리하는 것이 가장 안전하기 때문이다.

로그 파일을 보관 하는 작업을 하기 전에 먼저 그 파일이 그곳에 있는지 부터 확인하고, 그 경우는 해당 명령어가 0 아닌 값을 리턴할 수 있도록 설정하기를 권한다. Unix에서는 이런 작업을 위해, test 명령을 제공하고 있다. 몇 Unix 플랫폼에서는 이미 있는 파일을 덮어쓰지 않기 위해 cp 명령에서 -i 옵션을 제공하는데, 이 명령을 사용할 때는 반드시 리턴값을 확인 해 볼 필요가 있다. (GNU cp 명령은 이 경우, 0 값을 리턴한다. 이는 원하는 결과가 아니다.)

WAL 파일을 따로 저장하는 작업을 할 때, 운영상 해당 작업을 수동으로 중시 했을 경우나, 저장 공간이 부족하여, 이 저장 작업이 실패해서, 계속 반복 될 경우, 어떤 일이 생길지에 대해서도 고려해야한다. 한 예로, WAL 세그먼트 파일을 테이프 저장장치로 보관하려고 하는데, 해당 장치가 자동으로 테이프 교환을 하지 않고, 테이프의 여유 공간이 없다면, 사용자가 테이프를 바꾸기 전까지 계속해서 파일 기록 작업을 실행했다가, 오류를 내고, 다시 실행할 것이다. 이렇게 되면, pg_wal/ 디렉터리에서는 테이프 저장장치로 자료가 안전하게 복사되지 않았기 때문에, 해당 WAL 세그먼트 파일을 삭제하거나 재사용하지 않을 것이며, 그 이후 만들어지는 새로운 WAL 세그먼트 파일들이 계속 해서 쌓일 것이고, 결국 pg_wal/ 디렉터리의 여유 공간이 없어 서버는 PANIC 오류를 내면서 중지하게된다.

또한 WAL 파일을 따로 저장할 때의 그 저장 장치의 자료 기록 속도도 함께 고민해야한다. 정상적으로 작업이 진행된다 하더라도, WAL 파일을 만들어내는 속도가, 그 파일을 따로 보관하는 속도보다 빠르다면, 똑같은 문제가 발생할 수 있다. 물론 따로 보관하는 속도가 다소 늦더라도, 정상적으로 이루워지고, pg_wal/ 디렉터리의 여유공간이 충분히 있다면 별문제 되지는 않지만, 그렇지 않다면, 위에서 언급한 문제가 발생할 여지가 있다. 이 기능을 사용하기 전에 충분히 이 부분에 대한 문제를 고민해 보아야하며, 관리자는 이 기능이 의도된 대로 잘 작동하는지 감시해야한다.

저장 파일의 경로는 최대 64 개의 ASCII 글자면 되고, 파일이름은 %f 예약어를 사용해야하며, (즉 디렉터리까지만 바꿀 수 있다) 원본 WAL 세그먼트 파일은 %p 예약어를 사용해야한다.

WAL 파일에는 트랜잭션 작업 정보만 담겨있기 때문에, postgresql.conf, pg_hba.conf, pg_ident.conf 파일의 변경 사항은 복원 되는 데이터베이스에 이 백업 방법으로는 반영되지 않는 점을 주의해야한다. 이 환경설정 파일의 백업은 시스템의 일반 파일 백업 정책에 따라 백업하길 바란다. 이 환경설정 파일 백업을 위해서, 해당 파일의 위치를 바꾸려면, 19.2절 항목을 참조하라.

아카이브 명령은 WAL 파일 가운데, 서버에 모두 반영된,(rollback되거나 commit 되어 checkpoint 작업이 끝난) 파일에 대해서 실행된다. 즉, 작업량이 아주 적은 데이터베이스일 경우라면, 아카이브 명령이 실행될 간격이 아주 길어진다. 이 사이 데이터베이스 장애가 생긴다면, 자료 손실이 그 긴 기간 만큼 생기게 됨으로 WAL 세그먼트 파일의 모든 내용이 처리되기 전에 강제로 특정 시간이 지나면 아카이브 명령을 사용해서 이 세그먼트 파일을 따로 저장하려면, archive_timeout 환경설정 값을 짧게 조정하면 된다. 이 설정값을 너무 짧게 잡으며, 디스크 공간을 낭비하는 단점이 생긴다. 일반적으로 이 설정값은 분 딘위가 적당하다.

또한 사용자가 강제로 세그먼트 파일을 pg_switch_wal 함수를 이용해서 바꿀 수 있다. 일반적으로 대량 자료 입력, 변경, 삭제 작업이 일어나고, 이것에 대한 즉시 백업이 필요한 경우에 이 함수를 사용한다. 기타 WAL 세그먼트 파일의 조작 관련 함수들은 표 9.85 표를 참조하라.

14.4.7절에서 언급하고 있듯이, wal_level 환경설정값을 minimal로 설정하게 되면 이 WAL 로그를 따로 보관해서 그것을 기반으로 복원 하는 기능을 사용할 수 없다. 이 설정을 사용하면, WAL 파일에 복원 관련 정보를 보관하지 않기 때문이다. 이렇기 때문에, wal_level 설정값을 변경하면, 서버를 재실행해야한다. 하지만, archive_command 설정값은 환경설정파일 다시 로드하는 것으로도 충분하다. 필요에 따라서 운영 중에 이 작업이 중지되어야할 필요도 있기 때문이다. 이렇게 하려면, archive_command 설정값으로 빈문자열('')로 지정하면 된다.이러면 archive_command설정값이 다시 WAL 파일을 복사하는 작업을 하기 전까지 pg_wal/ 디렉터리에 계속 남아있게 된다.

25.3.2. 베이스 백업 만들기

베이스 백업을 만드는 가장 손쉬운 방법은 pg_basebackup 툴을 사용하는 것이다. 이 툴을 이용하면 일반적인 파일이나, tar 묶음 파일로 베이스 백업 파일을 만들 수 있다. pg_basebackup 툴을 이용하는 방법보다 보다 유연하게 백업을 하고 싶다면, 저수준 API를 이용해서 사용자 정의 백업 방식을 구현할 수 있다. (25.3.3절 참조)

베이스 백업을 만드는데 걸리는 시간에 대해서는 우려할 필요가 없다. 하지만, 운영 서버가 full_page_writes 비활성화 상태로 운영 되고 있다면, 베이스 백업을 하는 동안 자동으로 full_page_writes 설정이 활성화 되어 서버의 성능이 약간 떨어질 것이다.

이 베이스 백업을 이용해서 복구작업을 한다면, 베이스 백업 작업에서 파일 시스템 복사를 시작하는 시점부터 복사가 끝나는 시점까지 만든 모든 WAL 파일을 따로 보관하고 있어야한다. 어떤 파일부터 따로 보관해야하는지는 베이스 백업을 시작하는 시점부터 백업이 끝나는 시점까지 생성된 WAL 파일을 백업 내역 파일에 기록해 둔다. 이 파일의 이름은 복구에 필요한 WAL 파일의 첫번째 파일 이름을 사용한다. 예를 들어서, 필요한 파일이 0000000100001234000055CD 이라면, 백업 내역 파일은 0000000100001234000055CD.007C9330.backup 파일이다. 이 파일 또한 pg_wal 디렉터리 안에 있으면, 베이스 백업이 끝나 이 파일이 만들어지면, 아카이빙 작업에 의해 WAL 세그먼트 파일과 함께 따로 보관하는 장소에 복사된다. (WAL 세그먼트 파일 이름 뒤에 있는 또 하나의 정보는 그 파일의 정확한 시작 위치인데 이 부분은 무시해도 좋다.) 베이스 백업이 끝나면, 백업 내역 파일의 이름을 보고 그 이름보다 알파벳 순으로 이전 것들은 복구를 하는데 사용되지 않는다. 그러므로 다중 백업 환경이 아니라면, 오래된 WAL 세그먼트 파일들은 파일 시스템에서 삭제 되어도 무방하다. 다중 백업 환경이라면 그 각각의 백업 복구를 위해서 필요한 모든 WAL 세그먼트 파일들을 잘 정리해 두어야한다.

백업 내역 파일은 크기가 작은 단순 텍스트 파일이다. 이 파일에는 pg_basebackup 툴에서 자동으로 지정한 백업 라벨과, 백업 복구에 필요한 WAL 세그먼트 파일 이름 정보와 백업 시간이 기록되어있다. 백업본의 구분하려고 라벨을 사용한다면, 이 백업 내역 파일을 이용하면 충분하다.

베이스 백업 주기는 전체 백업량과, 그 간격 사이 만들어지는 WAL 세그먼트 파일의 양과, 백업 파일을 보관하는 속도, 여유 공간, 그리고 복구할 때 소요되는 시간까지 여러 부분들을 모두 고려해야한다. — WAL 세그먼트 파일이 많다면, 베이스 백업을 준비 해 놓고도 그 파일을 모두 반영하는데 걸리는 시간도 필요하기 때문이다.

25.3.3. 저수준 API를 이용한 베이스 백업 만들기

저수준 API를 이용해서 베이스 백업을 만드는 방법은, pg_basebackup 툴을 사용할 때보다 몇 단계 작업이 추가 되기는 하지만, 상대적으로 간단하다. 이렇게 작업할 때 가장 주의해야 할 점은 다음 설명하고 있는 각 단계가 반드시 정상적으로 수행 된 경우에만 다음 단계 작업을 해야한다는 점이다.

Low level base backups can be made in a non-exclusive or an exclusive way. The non-exclusive method is recommended and the exclusive one is deprecated and will eventually be removed.

25.3.3.1. Making a Non-Exclusive Low Level Backup

A non-exclusive low level backup is one that allows other concurrent backups to be running (both those started using the same backup API and those started using pg_basebackup).

  1. Ensure that WAL archiving is enabled and working.

  2. Connect to the server (it does not matter which database) as a user with rights to run pg_start_backup (superuser, or a user who has been granted EXECUTE on the function) and issue the command:

    SELECT pg_start_backup('label', false, false);
    

    where label is any string you want to use to uniquely identify this backup operation. The connection calling pg_start_backup must be maintained until the end of the backup, or the backup will be automatically aborted.

    By default, pg_start_backup can take a long time to finish. This is because it performs a checkpoint, and the I/O required for the checkpoint will be spread out over a significant period of time, by default half your inter-checkpoint interval (see the configuration parameter checkpoint_completion_target). This is usually what you want, because it minimizes the impact on query processing. If you want to start the backup as soon as possible, change the second parameter to true, which will issue an immediate checkpoint using as much I/O as available.

    The third parameter being false tells pg_start_backup to initiate a non-exclusive base backup.

  3. Perform the backup, using any convenient file-system-backup tool such as tar or cpio (not pg_dump or pg_dumpall). It is neither necessary nor desirable to stop normal operation of the database while you do this. See 25.3.3.3절 for things to consider during this backup.

  4. In the same connection as before, issue the command:

    SELECT * FROM pg_stop_backup(false, true);
    

    This terminates backup mode. On a primary, it also performs an automatic switch to the next WAL segment. On a standby, it is not possible to automatically switch WAL segments, so you may wish to run pg_switch_wal on the primary to perform a manual switch. The reason for the switch is to arrange for the last WAL segment file written during the backup interval to be ready to archive.

    The pg_stop_backup will return one row with three values. The second of these fields should be written to a file named backup_label in the root directory of the backup. The third field should be written to a file named tablespace_map unless the field is empty. These files are vital to the backup working and must be written byte for byte without modification, which may require opening the file in binary mode.

  5. Once the WAL segment files active during the backup are archived, you are done. The file identified by pg_stop_backup's first return value is the last segment that is required to form a complete set of backup files. On a primary, if archive_mode is enabled and the wait_for_archive parameter is true, pg_stop_backup does not return until the last segment has been archived. On a standby, archive_mode must be always in order for pg_stop_backup to wait. Archiving of these files happens automatically since you have already configured archive_command. In most cases this happens quickly, but you are advised to monitor your archive system to ensure there are no delays. If the archive process has fallen behind because of failures of the archive command, it will keep retrying until the archive succeeds and the backup is complete. If you wish to place a time limit on the execution of pg_stop_backup, set an appropriate statement_timeout value, but make note that if pg_stop_backup terminates because of this your backup may not be valid.

    If the backup process monitors and ensures that all WAL segment files required for the backup are successfully archived then the wait_for_archive parameter (which defaults to true) can be set to false to have pg_stop_backup return as soon as the stop backup record is written to the WAL. By default, pg_stop_backup will wait until all WAL has been archived, which can take some time. This option must be used with caution: if WAL archiving is not monitored correctly then the backup might not include all of the WAL files and will therefore be incomplete and not able to be restored.

25.3.3.2. Making an Exclusive Low Level Backup

참고

The exclusive backup method is deprecated and should be avoided. Prior to PostgreSQL 9.6, this was the only low-level method available, but it is now recommended that all users upgrade their scripts to use non-exclusive backups.

The process for an exclusive backup is mostly the same as for a non-exclusive one, but it differs in a few key steps. This type of backup can only be taken on a primary and does not allow concurrent backups. Moreover, because it creates a backup label file, as described below, it can block automatic restart of the master server after a crash. On the other hand, the erroneous removal of this file from a backup or standby is a common mistake, which can result in serious data corruption. If it is necessary to use this method, the following steps may be used.

  1. 서버가 아카이브 모드로 설정 되어있고 정상적으로 WAL 세그먼트 파일들이 따로 보관하는 작업이 실행되는 상태여야한다.

  2. Connect to the server (it does not matter which database) as a user with rights to run pg_start_backup (superuser, or a user who has been granted EXECUTE on the function) and issue the command:

    SELECT pg_start_backup('라벨');
    

    라벨 자리에는 어떤 문자열이 와도 상관 없다. 관리자가 해당 백업 작업에 대한 식별자로 사용되는 문자열이면 된다. pg_start_backup 함수는 먼저 데이터 클러스터 디렉터리에, backup_label 이라는 파일을 만들고, 그 안에, 지정한 라벨 문자열과, 백업을 시작하는 시간을 기록한다. 또한 이 함수는 pg_tblspc/ 디렉터리 안에 정의된 테이블스페이스에 정보가 하나 이상 있다면, 그 맵핑 정보 (tablespace map)를 담고 있는 tablespace_map 이라는 이름의 파일을 만든다. 이 두 파일은 백업을 식별하는 중요한 파일이기에, 이 백업으로 복구 작업을 진행할 때 꼭 필요하다.

    기본적으로, pg_start_backup 함수를 마치는데, 꽤 긴 시간이 소요되기도 한다. 백업 시작 전에 이 함수에 의해서 체크포인트 작업을 하는데, 이 작업을 준비하기 위한 내부적인 작업들과, 또, 체크포인트 작업은 데이터베이스 성능에 최대한 영향을 끼치지 않기 위해, 데이터베이스 서버가 다른 작업으로 바쁘며, checkpoint_completion_target 설정값에서 지정한 시간만큼 일단 기다리는 이 대기 시간까지 합쳐, 실재로 이 함수의 총 실행 시간이 길어지기도 한다. 만일 이렇게 긴 기다림의 시간 없이 바로 백업 준비를 위한 작업을 곧바로 하려면 다음과 같은 명령을 사용한다:

    SELECT pg_start_backup('label', true);
    

    위 명령은 최대한 빨리 체크포인트 작업을 진행한다.

  3. 데이터 클러스터 디렉터리를 시스템 차원에서 백업한다. 이 때의 백업 방법은 파일 시스템 백업하는 그 어떠한 방법으로도 가능하다. 예를 들면, tar , cpio 같은 명령어를 사용하는 것을 말한다 (pg_dump, pg_dumpall 명령어를 사용하는 것이 아니라). 이때 주의할 사항은 이 백업 작업을 하는 동안, 데이터베이스를 중지할 필요도 없으며, 중지 해서도 안된다는 점이다. 이 단계에서 할 작업의 자세한 설명은 25.3.3.3절 을 참조한다.

    As noted above, if the server crashes during the backup it may not be possible to restart until the backup_label file has been manually deleted from the PGDATA directory. Note that it is very important to never remove the backup_label file when restoring a backup, because this will result in corruption. Confusion about when it is appropriate to remove this file is a common cause of data corruption when using this method; be very certain that you remove the file only on an existing master and never when building a standby or restoring a backup, even if you are building a standby that will subsequently be promoted to a new master.

  4. 파일 시스템 백업이 끝나면, pg_stop_backup 함수를 실행할 수 있는 권한의 사용자(슈퍼유저이거나, 해당 함수에 대한 EXECUTE 권한이 있는 사용자)로 다시 데이터베이스에 접속해 다음 명령을 실행한다:

    SELECT pg_stop_backup();
    

    이 작업은 데이터베이스 서버 쪽에, 이제 백업이 끝났으니, 지금까지 사용했던 WAL 세그먼트 파일들은 아카이브 보관 작업 처리하는 쪽으로 넘기고, 새 WAL 세그먼트 파일로 바꾸어서 다시 서버를 일상적인 상태로 실행한다.

  5. 다음 이 마지막 로그 파일을 보관 하는 작업이 완료되면, 베이스 백업은 끝난다. pg_stop_backup 명령이 끝나는 시점은 마지막 사용했던 WAL 파일이 archive_command 설정값으로 지정된 명령에 의해서, 무사히 처리되었을 때다. pg_stop_backup 명령은 archive_mode 설정값이 on 상태일 때만 실행되며, 이 명령이 실행되기 직전까지 사용하고 있던 WAL 파일은 반드시, 정상적으로 보관처리가 되어야 끝난다. 일반적인 환경에서는 이 명령은 짧은 시간 안에 끝나지만, 예상했던 것보다 이 명령 시간이 오래 걸린다면, archive_command 설정값으로 지정된 작업에 문제가 있는지 살펴보고, 그 원인을 해결해야한다. 또한 archive_command 설정값이 비어 있어도 이 명령은 끝나지 않는다. archive_command 설정값으로 지정된 작업은 성공 할 때까지 반복 한다는 점도 주의 해야한다.

    When using exclusive backup mode, it is absolutely imperative to ensure that pg_stop_backup completes successfully at the end of the backup. Even if the backup itself fails, for example due to lack of disk space, failure to call pg_stop_backup will leave the server in backup mode indefinitely, causing future backups to fail and increasing the risk of a restart failure during the time that backup_label exists.

25.3.3.3. 데이터 디렉터리 백업하기

Some file system backup tools emit warnings or errors if the files they are trying to copy change while the copy proceeds. When taking a base backup of an active database, this situation is normal and not an error. However, you need to ensure that you can distinguish complaints of this sort from real errors. For example, some versions of rsync return a separate exit code for vanished source files, and you can write a driver script to accept this exit code as a non-error case. Also, some versions of GNU tar return an error code indistinguishable from a fatal error if a file was truncated while tar was copying it. Fortunately, GNU tar versions 1.16 and later exit with 1 if a file was changed during the backup, and 2 for other errors. With GNU tar version 1.23 and later, you can use the warning options --warning=no-file-changed --warning=no-file-removed to hide the related warning messages.

Be certain that your backup includes all of the files under the database cluster directory (e.g., /usr/local/pgsql/data). If you are using tablespaces that do not reside underneath this directory, be careful to include them as well (and be sure that your backup archives symbolic links as links, otherwise the restore will corrupt your tablespaces).

You should, however, omit from the backup the files within the cluster's pg_wal/ subdirectory. This slight adjustment is worthwhile because it reduces the risk of mistakes when restoring. This is easy to arrange if pg_wal/ is a symbolic link pointing to someplace outside the cluster directory, which is a common setup anyway for performance reasons. You might also want to exclude postmaster.pid and postmaster.opts, which record information about the running postmaster, not about the postmaster which will eventually use this backup. (These files can confuse pg_ctl.)

It is often a good idea to also omit from the backup the files within the cluster's pg_replslot/ directory, so that replication slots that exist on the master do not become part of the backup. Otherwise, the subsequent use of the backup to create a standby may result in indefinite retention of WAL files on the standby, and possibly bloat on the master if hot standby feedback is enabled, because the clients that are using those replication slots will still be connecting to and updating the slots on the master, not the standby. Even if the backup is only intended for use in creating a new master, copying the replication slots isn't expected to be particularly useful, since the contents of those slots will likely be badly out of date by the time the new master comes on line.

The contents of the directories pg_dynshmem/, pg_notify/, pg_serial/, pg_snapshots/, pg_stat_tmp/, and pg_subtrans/ (but not the directories themselves) can be omitted from the backup as they will be initialized on postmaster startup. If stats_temp_directory is set and is under the data directory then the contents of that directory can also be omitted.

Any file or directory beginning with pgsql_tmp can be omitted from the backup. These files are removed on postmaster start and the directories will be recreated as needed.

pg_internal.init files can be omitted from the backup whenever a file of that name is found. These files contain relation cache data that is always rebuilt when recovering.

The backup label file includes the label string you gave to pg_start_backup, as well as the time at which pg_start_backup was run, and the name of the starting WAL file. In case of confusion it is therefore possible to look inside a backup file and determine exactly which backup session the dump file came from. The tablespace map file includes the symbolic link names as they exist in the directory pg_tblspc/ and the full path of each symbolic link. These files are not merely for your information; their presence and contents are critical to the proper operation of the system's recovery process.

It is also possible to make a backup while the server is stopped. In this case, you obviously cannot use pg_start_backup or pg_stop_backup, and you will therefore be left to your own devices to keep track of which backup is which and how far back the associated WAL files go. It is generally better to follow the continuous archiving procedure above.

25.3.4. 아카이브 모드 백업을 이용한 복구

이제, 최악의 사고가 일어났을 때, 아카이브 모드 백업 방식으로 보관해둔 백업을 가지고, 데이터베이스 서버를 복구하는 방법에 대해서 설명한다. 작업 순서는 다음과 같다:

  1. 서버가 실행 중이라면, 먼저 서버를 중지한다.

  2. 만일 시스템의 디스크 공간이 넉넉하다면, 데이터베이스 클러스터 디렉터리 전체와, 관계된 사용자 정의 테이블스페이스의 파일들과 필요한 WAL 세그먼트 파일 모두다. 이 작업을 기존 운영 중이던 시스템에서 하려면, 적어도 두 배 이상의 디스크 공간이 필요하게 된다. 이런 여유 공간이 없다면, 적어도 기존 데이터베이스 서버의 클러스터 디렉터리 안에 있는 pg_wal 파일들과, 서버 환경 설정 파일들 만이라도 복사한다. 백업한 WAL 세그먼트 파일들과 미처 백업 되지 못한 WAL 세그먼트 파일들을 모두 구할 수 있다면, 서버가 중지되기 직전의 상태로 복구 될 수 있다.

  3. 기존 서버용 데이터 클러스터 디렉터리와, 기존 테이블스페이스용 디렉터리를 모두 지운다.

  4. 백업 파일을 원래의 위치에 그대로 복사한다. 이 때 작업자는 데이터베이스 서버를 실행하는 시스템 사용자여야한다. (root로 작업하면, 반드시, 해당 소유주로 변경해야한다!) 그래서, 파일 접근 권한과, 소유주를 원래의 그것과 같게 맞추어야한다. 다음 사용자 정의 테이블스페이스를 사용한다면, pg_tblspc/ 디렉터리 내에 심볼릭 링크로 되어 있는 원본 디렉터리와, 그 안에 있는 모든 파일을 복사해 둔다.

  5. pg_wal/ 디렉터리는 비워둔다; 만일 이 디렉터리 안에 파일이 있다면, 지워야한다. 복구 작업에서 이 디렉터리 안에 필요한 파일들은 자동으로 만들어진다. 만일 pg_wal/ 디렉터리를 백업 대상에서 제외했다면, 디렉터리를 만들거나, 심볼릭 링크를 만들어 데이터베이스 서버가 해당 디렉터리를 사용할 수 있도록 한다. 이 때도, 이 디렉터리의 접근권한과 소유주가 데이터베이스 서버를 실행하는 시스템 사용자만 사용할 수 있는지 확인해야한다. 만일 심볼릭 링크라면, 혹 옛 데이터베이스에서 사용하는 원본 경로와 같아서 옛 자료들을 덮어쓸 수 있는지 꼭 확인해야한다.

  6. 만일 WAL 세그먼트 파일에 대한 백업본이 없다면, 2단계에서 복사해둔 pg_wal/ 내의 파일들을 복구하려는 곳으로 복사한다. (옮기지 말고 복사하길 권한다. 아직 완벽한 복구가 이루워지지 않았기 때문에, 복사가 안전하다.)

  7. Set recovery configuration settings in postgresql.conf (see 19.5.4절) and create a file recovery.signal in the cluster data directory. 또한 복구 과정 중에 외부에서 접근 할 수 없도록 임시로 pg_hba.conf 파일을 수정하는 것도 좋은 방법이다.

  8. 서버를 실행한다. 서버는 복구 모드로 가동되면서, 필요한 WAL 파일들을 찾아서 반영되지 않았는 트랜잭션들을 일괄 처리하기 시작한다. 복구 작업 도중 외부 영향으로 서버가 중지 된다면, 단순히 서버를 재실행하면, 이어서 복구 작업을 계속 진행한다. 복구 작업이 끝나면, 서버는 recovery.signal (중복 복구 작업을 막기위해) 파일을 지우고, 정상 실행 상태로 클라이언트의 접속을 기다린다.

  9. 이제 데이터베이스로 접속해서, 자료가 정상인지 살펴보고, 만일 원하는 대로 복구 되지 않았다면, 서버 로그를 살펴보면서, 1단계부터 다시 진행한다. 자료가 모두 정상이고, 데이터베이스 상태도 정상이라면, pg_hba.conf 파일의 내용을 원래대로 수정해서, 외부 접속도 허용한다.

이 복구 방법의 핵심은 어떻게 백업 WAL 세그먼트 파일을 데이터베이스에 적용시키냐는 것과, 그 복구를 어느 시점까지 할 것이냐이다. 이런 것들은 복구 환경 설정에서 지정한다. 반드시 필요한 설정은 restore_command 설정이다. 이 설정은 PostgreSQL에서 백업본 WAL 세그먼트 파일을 어떻게 적용시킬 것인가에 대한 정의다. 간단하게 설명하면, 서버 환경 설정 가운데, archive_command 설정과 반대되는 명령을 지정하면 된다. 여기서 사용되는 예약어는 archive_command 설정값을 지정할 때와 같다. %f 값은 백업 아카이브 디렉터리 안에 있는 파일이름이 되고, %p 값은 트랜잭션 로그 파일로 대체된다. (상대 경로를 사용하면, 서버를 실행하는 현재 디렉터리를 기준으로 처리된다.) %% 예약어는 % 문자로 처리된다. 다음은 일반적인 이 설정값이다:

restore_command = 'cp /mnt/server/archivedir/%f %p'

윗 설정은 /mnt/server/archivedir 디렉터리 안에 있는 미리 백업 해둔 WAL 세그먼트 파일들을 복구 작업을 진행할 때 사용하겠다는 예제다. 물론 이 명령은 사용하는 백업 장치에 따라서 훨씬 복잡할 수도 있으며, 테이프 백업 장치처럼, 해당 테이프를 마운트하고, 원하는 위치로 이동하는 등, 몇몇 명령들이 포함된, 직접 만든 쉘 스크립트를 이용할 수도 있다.

여기서 중요한 점은 여기서 지정한 작업이 실패 했을 경우, 그 작업의 리턴값이 0이 아닌(nonzero) 것이여야 한다는 점이다. 이 작업에서는 아카이브 백업 디렉터리 안에 없는 파일도 요청할 것이다. 이 때 이 작업의 결과는 반드시 0이 아닌 리턴값을 리턴해야한다. 이 상황은 오류 상황이 아니다. 이 작업의 오류 상황으로는 해당 스크립트에서 명령어가 없다거나, 서버가 정상 종료되면서, 복구작업을 하는 프로세스로 SIGTERM 시그널을 보내는 경우를 제외한 기타 다른 시그널로 그 작업이 중지 되는 경우가 있다. 이런 상황에서는 복구 작업이 중지 되고, 서버는 정상 작동을 하지 않고 멈춘다.

서버는 .history 이름으로 끝나는 파일을 찾을 수도 있는데, 이 때, 그 파일이 없으면, 그 파일이 없다고, (0 아닌 값을 리턴함으로) 서버 쪽에 알려주어야한다. 또한, %f 파일 이름과, 서버 쪽으로 복사되는 %p 파일 이름이 항상 같지는 않다. 그렇기 때문에, 쉘 스크립트를 직접 만들어 사용한다면, 이 부분에 대한 처리에 실수가 없도록 주의해야한다.

아카이브 백업 디렉터리에서 WAL 세그먼트 파일을 못 찾으면, 데이터 클러스터 안에 있는 pg_wal/ 디렉터리 안에서 찾는다. 혹시 처리해야할 WAL 세그먼트 파일이 더 있는데, 미처 백업 되지 않은 것이 있으면, 그것까지도 처리하기 위한 방법이다. 하지만, 똑 같은 파일이름으로 아카이브 백업 디렉터리 안에 이미 그 파일이 있다면, 그 파일이 적용되고, pg_wal/ 안에 있던 파일은 무시하고, 새로운 WAL 세그먼트 이름으로 그 로그를 반영한다. 이렇기 때문에, 복구 작업 전에 반드시 WAL 세그먼트 파일들을 잘 정리해야한다.

일반적으로 복구 작업은 아카이브 백업 디렉터리 안에 가장 마지막 로그 파일을 반영하고, 그 다음 파일을 찾아서 없을 때까지 진행되기 때문에, 복구 로그의 마지막은 어떤 파일을 찾을 수 없다는 file not found 메시지가 출력된다. 또한 복구 작업을 시작하면서, 00000001.history 형태의 파일을 찾기도한다. 이 모든 경우는 정상적인 복구 과정 속에서 생기는 로그들이다. 자세한 이야기는 25.3.5절에서 설명하고 있다.

복구 작업은 복구 중지 지점을 지정해서 원하는 지점에서 복구 작업을 중지할 수도 있다. 이 지점을 recovery target이라고 한다. 이 기능은 미숙한 데이터베이스 관리자가 실수로 중요 테이블을 삭제하는 것 같은 운영성 실수에 대한 복구를 지원하는데 유용하다. recovery target은 특정 시각으로 지정할 수도 있고, 관리자가 미리 지정한 어떤 문자열일 수도 있고, 특정 트랜잭션 ID로 지정할 수도 있다. 사고가 어느 트랜잭션 ID에서 발생했는지 알 수 있는 툴을 사용할 수 없다면, 단순한 특정 시각, 또는 관리자가 미리 지정한 어떤 문자열을 지정하는 것이 복구 작업을 하는데 손쉽다.

참고

복구 작업을 멈출 시점은 베이스 백업 시간 이후여야한다. pg_stop_backup 명령이 실행된 시간보다 늦은 시점으로 지정해야한다. 베이스 백업 - 데이터 클러스터 파일들을 파일 시스템 차원으로 백업하고 있었던 그 시간 대로 복구 할 수는 없다. 이 작업이 필요하다면, 이전 베이스 백업 자료와, 해당 WAL 백업 파일들이 필요하다.

만일 WAL 파일 자체에 문제가 있다면, 정상적으로 처리한 트랜잭션까지만 적용되고, 복구 작업은 멈추고, 서버도 중지된다. 이런 경우라면, 문제가 발생한 시점을 파악해서, 처음부터 다시 그 시점 전까지만 recovery target 으로 지정해서 복구한다. 반면, 복구 작업 도중 외부적인 영향으로 작업이 중지 되었다면, (시스템 리부팅, disk full, .... 이런 이유들) 문제의 원인을 해결하고, 단순히 서버 재실행을 하면, 복구 작업을 이어서 계속 진행한다. 복구 작업은 일반 실행환경에서의 체크 포인트 작업과 같이 재실행된다. 내부적으로 pg_control 파일을 주기적으로 갱신해서, 이미 반영된 로그들에 대해서는 더이상 재작업을 하지 않도록 하기 때문에, 중복처리에 대한 염려는 안해도 된다.

25.3.5. 타임라인

어떤 데이터베이스를 특정 시점으로 복원하는 것은 마치 공상과학 소설에서 나오는 시간여행이나, 다원우주론 같이 복잡한 여러 문제점을 만든다. 예를 들어서, 그 데이터베이스의 최초의 변화 내역에서, 화요일 오후 5시 15분에 중요한 테이블을 지웠고, 그것을 수요일 아침까지 몰랐다고 치자. 이 때, 관리자는 침착하게, 백업 자료를 가지고, 화요일 오후 5시 14분까지 복구를 하고, 서버를 운영했다. 이렇게 해서 두 번째 변화 내역이 진행되었고, 데이터베이스 변화 내역에서는 그 테이블이 삭제 되지 않고 계속 운영 되었다. 하지만, 좀 있다가 판단해 보니, 이 판단이 바람직한 것이 아닌 것 같아, 다시 최초의 변화 내역 기준으로 수요일 아침으로 데이터베이스를 상태로 (그 중요 테이블이 지원진 채로 운영된 상태) 다시 되돌아야가야할 필요가 생긴다. 단순하게 생각하면, 이미 한 번 과거로 되돌아 갔고, 거기서 이미 WAL 파일을 덮어써 버렸기 때문에, 이 작업이 불가능할 것 같다. 이 문제를 해결하기 위해서, 백업 WAL 세그먼트 파일을 이용한 데이터베이스 복구 작업을 할 때는 서버가 각각의 복구 작업에 필요한 WAL 세그먼트 파일의 이름을 다르게 해서 사용한다.

이것을 PostgreSQL에서는 타임라인이라는 개념으로 설명하고 있다. 복구 작업이 끝나고, 데이터베이스가 새롭게 실행되면, 새로운 타임라인 ID로 WAL 레코드를 만든다. 이 타임라인 ID는 WAL 세그먼트 파일 이름의 한 부분으로 사용되어 같은 트랜잭션 번호에 대해서도 다른 WAL 파일을 만들 수 있도록 해서, 예전 데이터베이스 변경 내역 정보를 덮어쓰지 않도록 한다. 이런 방식이면, 얼마든지 다양한 타임라인이 존재할 수 있다. 필요 없는 기능 같아 보이기는 하지만, 이 기능이 가끔 구원자 역할을 톡톡히 한다. 복구시점을 정확히 모르고, 그 시점을 정확하게 찾을 때까지 계속 복구 작업을 계속 해야하는 상황에 아주 유용하게 사용된다. 타임라인 정보가 없다면, 이런 작업은 거의 관리가 안될 정도로 복잡해저버린다. 타이라인을 사용하면, 이미 분기 되어 더이상 사용하지 않는 어떠한 이전 데이터베이스 상태로도 되돌아 갈 수 있다.

새로운 타임라인으로 운영될 때마다 PostgreSQL에서는 타임라인 내역 파일을 만든다. 이 파일에는 언제, 어디서 분기되었는지 대한 정보를 담고 있다. 이 내역 파일은 다중 타임라임이 있을 경우, 사용자가 지정한 특정 타임라인을 사용할 때, 어느 WAL 파일을 사용해야하는지에 대한 정보를 담고 있어, 복원 작업에 사용된다. 즉, 이 파일 또한 새롭게 생성 되면, WAL 세그먼트 파일과 마찬가지로, 바로 WAL 세그먼트 파일 백업 처리할 때와 마찬가지로 archive_command 설정값에서 지정한 작업을 진행해서, 따로 보관 된다. 이 내역 파일은 (큰 크기의 WAL 세그먼트 파일과 달리) 단순한 텍스트 파일이다. 그래서 충분히 많은 파일들을 보관 할 수 있다. 또한 해당 내역 파일을 문서편집기로 열어서, 그 복구 내역에 대한 구체적인 내용을 기록해 두면, 나중에 여러모로 쓸모가 있을 것이다.

복구 작업의 최종 타임라인은 아카이브에서 찾은 마지막 타임라인이다. 특정 타임라인으로 복구하려면, recovery_target_timeline 설정값으로 현재 타임라인을 뜻하는 current를 사용하거나, 특정 타임라인 번호를 지정할 수 있다. 물론 이 타임라인은 반드시 베이스 백업 뒤에 사용한 하위 타임라인 가운데 하나여야 한다.

25.3.6. 팁과 예제

아카이브 모드를 사용하는 환경설정에 관계된 몇가지 팁과 예제를 여기서 소개한다.

25.3.6.1. 독립된 핫백업

PostgreSQL 백업 방식으로 독립된 핫백업을 구현할 수 있다. 이 방식으로 구현하면, 특정시점 복구는 불가능해지지만, 장애복구시, pg_dump 프로그램을 이용해서, 만든 덤프 파일을 사용하는 복구보다 훨씬 빠른 시간안에 복구 할 수 있다. (물론 pg_dump의 덤프 파일 크기가 데이터 클러스터 디렉터리 사이즈에 비해 아주 적은 경우라면, 오히려 더 늦을 수도 있을 것이다.) 베이스 백업에서 언급했던 것처럼 독립된 핫백업 서버를 구축하는 가장 손쉬운 방법은 pg_basebackup 툴을 이용해서 베이스 백업을 받는 것이다. pg_basebackup을 호출할 때 -X 매개 변수를 쓰면 사용되는 트랜잭션 로그 전체가 백업에 자동으로 쓰이고, 그 이상의 작업은 필요 없다.

백업 파일을 복사하는데 보다 유연한 방법이 필요한 경우라면, 보다 저수준의 작업으로 독립된 핫백업을 구현할 수 있다. 독립된 핫백업을 구축하려면, wal_level 값은 replica 또는 그 이상으로, archive_mode 값은 on, archive_command 값으로 스위치 파일이 있는 경우에 한해서 그 파일을 다른 곳에도 보관할 수 있도록 설정하면 된다. 다음은 이 설정의 예제다:

archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress || (test ! -f /var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f)'

윗 설정은 /var/lib/pgsql/backup_in_progress 파일이 없으면, 그냥 건너뛰고, 이 파일이 있으면 복사하려는 WAL 세그먼트 파일이 없는 경우만 다른 곳에 복사하는 작업을 한다. (이렇게 해서, PostgreSQL 서버가 더이상 쓸모가 없는 WAL 파일을 다시 사용할 수 있도록 한다.)

WAL 세그먼트 파일들의 백업 설정을 위가 같이 해 두고, 아래와 같이 베이스 백업 스크립트를 만든다:

touch /var/lib/pgsql/backup_in_progress
psql -c "select pg_start_backup('hot_backup');"
tar -cf /var/lib/pgsql/backup.tar /var/lib/pgsql/data/
psql -c "select pg_stop_backup();"
rm /var/lib/pgsql/backup_in_progress
tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/

/var/lib/pgsql/backup_in_progress 이름으로 스위치 파일을 먼저 만들어, 베이스 백업을 준비하는 동안만 WAL 파일을 다른 장소에 따로 보관하고, 베이스 백업을 tar 파일로 만들고, 백업 작업이 끝났다고 서버쪽에 알리고, 스위치 파일을 지우고, tar 작업을 하는 동안 생긴 생긴 WAL 파일들을 같은 tar 파일에 추가하고 작업을 끝낸다. 이 때 이 스크립트의 오류를 확인해 예외처리를 해야할 필요도 있다.

저장 공간이 넉넉치 않다면, pg_compresslog, http://pglesslog.projects.postgresql.org, 프로그램을 이용해서, 필요없는 full_page_writes 정보와, 실재 작업할 내용이 없는 WAL 파일의 영역을 정리해서 보관할 수도 있다. 거기다 pg_compresslog 프로그램으로 정리된 내용을 gzip 프로그램을 이용해서 더 압축할 수도 있다:

archive_command = 'pg_compresslog %p - | gzip > /var/lib/pgsql/archive/%f'

복구 할 때는 gunzip 프로그램과, pg_decompresslog 프로그램을 다음과 같이 사용한다:

restore_command = 'gunzip < /mnt/server/archivedir/%f | pg_decompresslog - %p'

25.3.6.2. archive_command 스크립트

많은 사람들이 archive_command 설정값으로 postgresql.conf 파일에 아래와 같이 스크립트를 사용해서, 그 값을 단순화 한다:

archive_command = 'local_backup_script.sh "%p" "%f"'

아카이빙 작업을 단순한 시스템 명령들의 조합으로 설정하기 보다, 하나의 스크립트로 지정해 놓으면, 백업 관련 작업과, 데이터베이스 관리 작업을 분리할 수 있어, 얻는 이득이 많다. 필요하다면, 그 스크립트만 수정하면 백업 정책을 언제든지 바꿀 수 있기 때문이다. 이렇게 하면, 많이 쓰는 bash 또는 perl 스크립트로 작성할 수 있으며, 보다 안전하고, 꼼꼼한 작업을 할 수 있다.

작은 정보

archive_command 에서 지정한 스크립트의 로그를 서버 로그로 저장하고 싶다면, logging_collector 환경 설정값을 on으로 켜두면 된다. 이렇게 하면, 스크립트에서 stderr 쪽으로 출력하는 모든 내용은 서버 로그로 저장된다. 이렇게 해서, 보다 손 쉽게 오류를 검사 할 수 있다.

스크립트를 실행하면서 생기는 모든 stderr 출력은 데이터베이스 서버 로그로 기록된다. 이렇게 해서, 백업 스크립트 오류를 쉽게 진단할 수 있다.

이 스크립트를 만들 때는 다음 항목들에 대한 고려도 함께 하면 좋다:

  • 파일이 복사 되면서 발생하는 파일 누출 문제 - 보안 문제

  • WAL 파일 복사(전송, 다른 곳에 따로 보관하는 것)의 가장 안전하고, 확실한 방법 - 실패 했을 경우 재시도에 대한 정책, 복구를 빠르게 하기 위한 이중 백업 등

  • 다른 백업, 복구 소프트웨어를 사용할 때의 인터페이스 문제 Interfacing with other backup and recovery software

  • 오류 모니터링 소프트웨어와의 인터페이스 문제

25.3.7. 위험부담

여기서는 아카이브 모드 백업 기술의 여러가지 한계점을 소개하고 있다. 이 한계들은 미래의 배포판에서 수정될 예정이다:

  • 베이스 백업이 시작 된 다음 CREATE DATABASE 명령으로 새 데이터베이스가 만들어지고, 그 데이터베이스를 만들 때, 원본이 되었던 템플릿 데이터베이스가 베이스 백업이 끝나기 전에 변경 되었다면, 복원 작업을 할 때, 원본이 되었던 모습과 같은 새 데이터베이스가 만들어지지 않을 가능성이 있다. 이 문제를 피하려면, 베이스 백업 중에는 템플릿 데이터베이스를 변경 하지 않는 것이 가장 좋은 방법이다.

  • CREATE TABLESPACE 명령은 거기서 사용하는 실재 경로가 그대로 반영 된다. 이 말은 복원 하는 시점에 미리 그 실재 경로의 디렉터리가 있어야함을 의미한다(물론 처음 테이블스페이스를 만들 때 처럼 그 디렉터리는 비어있고, 소유주와 접근권한이 데이터베이스가 사용할 수 있는 상태여야한다). 이점은 복원 작업에서 상당한 주의가 필요하다. 만일 같은 호스트에서 복원을 하는데, 임시 복원 작업을 진행하면서, 그 테이블스페이스에 있던 원본 파일을 손상 할 수도 있으며, 다른 호스트에서 테이블스페이스의 실재 디렉터리가 없어서, 원본 자료를 손실 할 수도 있다. 이 문제를 피해갈 수 있는 가장 좋은 방법은, 일단 테이블스페이스를 만들거나, 삭제할 경우에는 반드시 그 다음에, 베이스 백업본을 만들어 두는 것이다.

또 다른 단점은 기본 WAL 포멧은 많은 디스크 페이지 스냅샷을 포함하고 있어, 그 크기가 상당히 크다는 점이다. 이 페이지 스냅샷 기법은 서버가 갑자기 중지 될 경우, 해당 디스크 페이지가 부분적으로 기록되었을 경우, 그 페이지를 안전하게 복구 하기 위해서 도입되었다. 물론 사용하고 있는 하드웨어와 소프트웨어에 따라, 이런 부분적인 디스크 페이지 기록으로 인한 오류가 미비하거나, 무시할 정도일 경우도 있다. 이럴 경우, full_page_writes 환경변수 값을 off로 설정하면, 이 로그 전체 크기를 많이 줄일 수 있다. (하지만, 먼저 29장을 꼼꼼히 살펴 보고, 결정하라.) 이 환경변수값을 off로 설정해도 PITR 기능을 사용할 수 있다. 또한 full_page_writes 값이 on 이더라도, 아카이브 로그를 만들 때, 필요없는 페이지 복사본들은 버리고, 복원에 필요한 것만 담아서 만드는 방식도 도입되어야할 것이다. (미래의 개발자들에게 이 일은 넘긴다.) 운영 입장에서, 관리자는 체크 포인트 간격을 늘려서 이 WAL 로그를 적게 만드는 방법도 한 방법이다.