26.4. 로그 전달 복제에 대한 다른 방법

26.4.1. 실행
26.4.2. 레코드 기반의 로그 전달

운영 서버에서 사용했던 로그를 대기 서버로 보내서 복제 기능을 구현하는 방법은 restore_command 설정값으로 지정한 명령으로 전달 된 파일을 자기 서버에 적용하고, 적용할 파일이 없으면, 그 명령을 계속 반복하는 식이다. 이 부분은 앞 장에서 구체적으로 설명했다. This was the only option available in versions 8.4 and below. See the pg_standby module for a reference implementation of this. pg_standby 모듈이 이 독자적인 복제 기능을 구현해 놓은 것이다.

이 방식에서 주의해야할 점은, 운영 서버에서 만들어진 WAL 파일은 그것들이 만들어지는 순서에 따라 그대로 대기 서버로 반영 되어야한다는 점이다. 또한 반영 하는 작업은 반드시 직렬화 되어서 한 번에 하나의 파일만 적용해야한다. 대기 서버에서 쿼리를 사용할 수 있게 설정 한다면, (Hot Standby) WAL 파일 적용 간격에 차이 때문에, 자료가 정확하게 운영 서버와 같지 않다는 점도 기억해야한다. 이 대기 서버로의 자료 반영 지연 현상을 줄이려면, archive_timeout 설정값을 짧게 하면 된다. 또한 이 방식으로 구현하면, 스트리밍 방식 복제를 사용할 수 없다는 점도 기억해야한다.

기본 작동 방식은 일반적인 로그 전달, 복구 방식과 같다. 트랜잭션 로그를 전달하는 방법은 WAL 레코드가 다 채워진, WAL 세그먼트 파일을 서로 전달하고, 받아서 사용하는 길 뿐이다. 운영 서버에서 만드는 순차적인 WAL 세그먼트 파일들이 대기 서버로 옮길 때, 누락되는 일이 없도록, 나중에 만들어진 파일이 이전에 만들어진 파일보다 먼저 대기 서버에 도착하는 일이 없도록 해야한다. 또한 다른 운영 서버에서 만든 WAL 세그먼트 파일과 섞여 구분이 안되는 일이 없도록 해야한다. 대기 기능만 구현하고자 한다면, WAL 파일 전달량은 그렇게 많지는 않다.

복제 기능을 독자적으로 구현하는 열쇠는 restore_command 설정값에 있다. restore_command 설정에 대한 설명은 25.3.4절에서 설명하고 있다. 여기서 사용하는 명령은 서버가 처리해야하는 파일이 없으면, 0 아닌 값을 리턴해서, 복구 모드를 종료하고, 일반적인 정상 운영 서버로 실행 되도록 한다. 하지만, 복제용 대기 서버로 구축하려면, 이 명령은 원하는 파일이 없으면, 그 파일이 생길 때까지(운영 서버가 대기 서버로 보내줄 때까지) 기다리고 있다가, 생기면 다시 대기 서버가 복구 작업을 계속 할 수 있어야한다. 또한 .history이 운영 서버로부터 넘어 오면 그 파일은 무시하고, 0 아닌 값을 리턴하면서 이 명령을 끝내야한다. 이렇게 설명한 모든 부분을 사용자가 직접 프로그래밍 해야한다. 이 프로그램은 아울러, 장애처리를 위한 운영 역할로 전환할 수 있는 기능도 있어야하며, OS 시그널 처리도 있어야 한다.

restore_command 설정값으로 사용될 프로그램의 의사코드는 다음과 같다:

triggered = false;
while (!NextWALFileReady() && !triggered)
{
    sleep(100000L);         /* wait for ~0.1 sec */
    if (CheckForExternalTrigger())
        triggered = true;
}
if (!triggered)
        CopyWALFileForRecovery();

이런 방식으로 구현된 실재 프로그램을 pg_standby 모듈에서 제공한다. 이 모듈은 위에서 설명한 구현 요소들을 모두 구현했다. 이 모듈과 함께 사용자 정의 스크립트들을 사용해서 구축할 수도 있을 것이다.

어떻게 대기 서버가 운영 서버로 바뀔 것인가에 대한 설계는 꽤 중요한 부분이다. 이 또한 restore_command 설정값으로 지정하는 명령어에서 담당한다. 단순하게 이 명령어의 리턴값이 0 아닌 값으로 종료되면 된다. 0 아닌 값으로 종료되는 상황은 어떤 특정 파일이 생겼을 때, 또는 더 나아가 운영 서버가 응답이 없을 때, 등등 발생할 수 있는 모든 상황을 꼼꼼히 살펴보고 그것을 구현하면 된다. 문제는 이 명령어 실행은 서버가 각 개별 WAL 파일에 대해서 한 번 처리하고, 종료되고, 다시 실행하는 식으로 작동되기 때문에, 서버 데몬과 달리 시그널 처리를 하기 힘들다. 그렇기 때문에, 어떤 특정 파일을 만들어 장애처리 신호로 사용하겠다면, 그 파일은 다른 프로세스가 만드는 것이 타당하다. 한편, 운영 서버의 archive_timeout 값을 참조해서, 원하는 WAL 파일이 넘어오지 않을 경우 다음 작업을 할 수 있는 시간 제한 기능을 둘 수도 있으나, 이 때 네트워크 상태나, 운영 서버의 부하 상태도 함께 고려해야한다. 그렇지 않으면, 의도 되지 않게 장애처리 기능이 작동해서, 상황을 더 악화시킬 수도 있다.

26.4.1. 실행

대기 서버 설정은 간단한 절차를 통해서 할 수 있다. 절차들의 세부 내용은 각 참조하는 절을 참고하라.

  1. 운영 서버와 대기 서버의 시스템을 최대한 똑같이 설정 하고, 각자 동일한 버전의 PostgreSQL을 사용한다.

  2. 운영 서버에서 대기 서버의 WAL 아카이브 디렉터리로 연속적인 아카이빙을 설정하라. archive_mode, archive_command archive_timeout 가 운영 서버에 적절하게 설정되도록 확인한다(25.3.1절을 참조).

  3. 운영 서버의 기본 백업을 만들고(25.3.2절을 참조), 대기 서버에 데이터를 적재하라.

  4. 이전에 설명한 것처럼(25.3.4절을 참조) restore_command 설정으로 주서버의 WAL 아카이브된 파일을 대기 서버에서 사용할 수 있도록 한다.

복구 작업은 WAL 아카이브를 읽기 전용으로 처리하여, WAL 파일이 대기 서버 시스템에 복사 되면 테이프로 WAL 파일이 복사되어 데이터베이스 대기 서버가 동시에 읽을 수 있다. 이와 같이 대기 서버는 재난 복구를 목적으로 파일을 장기간 저장하면서 동시에 고가용성을 구현할 수 있다.

테스트를 목적으로 운영 서버와 대기 서버를 같은 시스템에서 실행할 수 있다. 이 작업은 server robustness를 개선하지 않고 고가용성이라 하지 않는다.

26.4.2. 레코드 기반의 로그 전달

레코드 기반으로 로그를 전달하는 것도 가능한데, 사용자가 직접 개발을 해야 된다. 또, 전체 WAL 파일이 전달됐을 때에는 hot standby 쿼리에만 변경 사항이 보인다.

pg_walfile_name_offset() 함수 (9.27절 참조) 를 호출해서 파일명과 현재 마지막 WAL의 정확한 바이트 오프셋을 구할 수 있다. pg_xlogfile_name_offset 함수는 WAL 파일에 직접 접근할 수 있고 WAL 파일 마지막 데이터를 대기 서버에 복사할 수 있다. 이 방법을 쓰면 데이터 손실은 프로그램을 복사하는 폴링polling 순환 시기에 발생하는데, 손실은 매우 적고, 부분적으로 사용되는 세그먼트 파일을 강제로 아카이빙할 때 낭비하는 대역폭은 없다. 대 기 서버의 restore_command 스크립트는 전체 WAL 파일을 다루므로, 점차적으로 복사된 데이터는 보통 대기 서버에서 사용할 수 없다. 이 데이터는 운영 서버가 죽었을 때만 사용되는데, 마지막 WAL 파일 부분이 대기 서버에 쓰이게 된다. 이 프로세스를 정확하게 실행하려면 데이터 복사 프로그램과 restore_command 스크립트의 조합이 필요하다.

PostgreSQL 9.0 버전 이상은 스트리밍 리플리케이션(26.2.5절을 참조)으로 편리하게 할 수 있다.