위로 아래

 

config 파일 위치

/var/lib/pgsql/data/postgresql.conf

 

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 디렉터리로 이름을 똑같게 해서 복사하는 설정이다.

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

 

 

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

 

 

베이스 백업을 만드는 가장 손쉬운 방법은 pg_basebackup 툴을 사용하는 것이다. 이 툴을 이용하면 일반적인 파일이나, tar 묶음 파일로 베이스 백업 파일을 만들 수 있다

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

 

이 베이스 백업을 이용해서 복구작업을 한다면, 베이스 백업 작업에서 파일 시스템 복사를 시작하는 시점부터 복사가 끝나는 시점까지 만든 모든 WAL 파일을 따로 보관하고 있어야한다.

어떤 파일부터 따로 보관해야하는지는 베이스 백업을 시작하는 시점부터 백업이 끝나는 시점까지 생성된 WAL 파일을 백업 내역 파일에 기록해 둔다.

이 파일의 이름은 복구에 필요한 WAL 파일의 첫번째 파일 이름을 사용한다.

예를 들어서, 필요한 파일이 0000000100001234000055CD 이라면, 백업 내역 파일은 0000000100001234000055CD.007C9330.backup 파일이다.

이 파일 또한 pg_wal 디렉터리 안에 있으면, 베이스 백업이 끝나 이 파일이 만들어지면, 아카이빙 작업에 의해 WAL 세그먼트 파일과 함께 따로 보관하는 장소에 복사된다. (WAL 세그먼트 파일 이름 뒤에 있는 또 하나의 정보는 그 파일의 정확한 시작 위치인데 이 부분은 무시해도 좋다.)

 

베이스 백업이 끝나면, 백업 내역 파일의 이름을 보고 그 이름보다 알파벳 순으로 이전 것들은 복구를 하는데 사용되지 않는다. 그러므로 다중 백업 환경이 아니라면, 오래된 WAL 세그먼트 파일들은 파일 시스템에서 삭제 되어도 무방하다. 다중 백업 환경이라면 그 각각의 백업 복구를 위해서 필요한 모든 WAL 세그먼트 파일들을 잘 정리해 두어야한다.

 

 

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

 

 

 

 

복구 방법

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. 데이터베이스 클러스터 디렉터리 안에, recovery.conf 파일을 만든다. (이 파일의 내용에 대한 자세한 설명은 27장 참조) 또한 복구 과정 중에 외부에서 접근 할 수 없도록 임시로 pg_hba.conf 파일을 수정하는 것도 좋은 방법이다.
  8. 서버를 실행한다. 서버는 복구 모드로 가동되면서, 필요한 WAL 파일들을 찾아서 반영되지 않았는 트랜잭션들을 일괄 처리하기 시작한다. 복구 작업 도중 외부 영향으로 서버가 중지 된다면, 단순히 서버를 재실행하면, 이어서 복구 작업을 계속 진행한다. 복구 작업이 끝나면, 서버는 복구 모드로 재실행 되는 것을 막기 위해, recovery.conf 파일을 recovery.done 이름으로 바꾸고, 정상 실행 상태로 클라이언트의 접속을 기다린다.
  9. 이제 데이터베이스로 접속해서, 자료가 정상인지 살펴보고, 만일 원하는 대로 복구 되지 않았다면, 서버 로그를 살펴보면서, 1단계부터 다시 진행한다. 자료가 모두 정상이고, 데이터베이스 상태도 정상이라면, pg_hba.conf 파일의 내용을 원래대로 수정해서, 외부 접속도 허용한다.

이 복구 방법의 핵심은 어떻게 백업 WAL 세그먼트 파일을 데이터베이스에 적용시키냐는 것과, 그 복구를 어느 시점까지 할 것이냐이다. 이것을 recovery.conf 파일에서 지정한다. 이 파일을 만드는 간단한 방법은 먼저 데이터베이스 배포판의 share/ 디렉터리 안에 recovery.conf.sample 파일을 복사해서, 필요한 부분만 수정해서 사용하는 것이다. recovery.conf 파일에서 꼭 필요한 부분은 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.conf 파일에서 복구 중지 지점을 지정해서 원하는 지점에서 복구 작업을 중지할 수도 있다. 이 지점을 recovery target이라고 한다. 이 기능은 미숙한 데이터베이스 관리자가 실수로 중요 테이블을 삭제하는 것 같은 운영성 실수에 대한 복구를 지원하는데 유용하다. recovery target은 특정 시각으로 지정할 수도 있고, 관리자가 미리 지정한 어떤 문자열일 수도 있고, 특정 트랜잭션 ID로 지정할 수도 있다. 사고가 어느 트랜잭션 ID에서 발생했는지 알 수 있는 툴을 사용할 수 없다면, 단순한 특정 시각, 또는 관리자가 미리 지정한 어떤 문자열을 지정하는 것이 복구 작업을 하는데 손쉽다.

참고

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

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

 

 

참고 : https://postgresql.kr/docs/10/continuous-archiving.html

 

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

25.3. 아카이브 모드 백업(Continuous Archiving)과, 특정시점 복구(Point-in-Time Recovery, PITR) PostgreSQL에서는 미리 쓰기 기록 (선행 기입 로그, write ahead log, WAL)을 데이터베이스 클러스터 디렉터리 안 pg_wal/

postgresql.kr