pg_rewind

pg_rewind — PostgreSQL 데이터 디렉터리를 자신으로부터 파생된 또 다른 데이터 디렉터리에게 맞춰 동기화

요약

pg_rewind [옵션...] { -D | --target-pgdata } 디렉터리 위치 { --source-pgdata=디렉터리 위치 | --source-server=연결정보 }

설명

pg_rewind는 클러스터의 또 다른 복사본에 맞춰 PostgreSQL 클러스터를 동기화 해주는 도구이다, 클러스터의 타임라인이 분기된 후라 할지라도. 이를 사용하는 일반적인 시나리오는 장애복구 후에 '이전의 master 서버'를 '새로운 master 서버'의 standby 로 되돌려준다.

이는 '--target-pgdata'로 지정한 데이터 디렉터리를 '--source-pgdata'로 교체하는 것과 동일하다. 오직 데이터 파일의 변경분만 복제될 뿐이다. 설정파일들까지 포함한 모든 파일들이 전체 복제된다. pg_rewind의 장점은 처음부터 백업을 뜨거나 rsync 툴을 사용하는 것을 넘어선다. 즉, pg_rewind는 변경되지 않은 클러스터 블록에 대해서는 체크를 위한 읽기 조차 하지 않는다. 그래서 데이터베이스 사이즈가 크고 클러스터간에 블록 변경분이 아주 작을때 보다 빠르게 수행된다.

pg_rewind는 source/target 클러스간에 타임라인 이력을 조사하여 분기지점을 알아낸다. 그리고 target 클러스터의 pg_wal 디렉터리내에서 분기되었던 시점으로 되돌릴 전체 WAL 찾아내려 한다. 분기지점은 target, source 또는 그 이전의 공통된 클러스터 타임라인들 중에서 찾을 수 있다. 전형적인 장애복구 시나리오에서 target 클러스터는 분기된 이후 빠르게 서버가 중지있다. 이러면 문제가 없지만, 만약에 target 클러스터가 분기된 이후에도 오래도록 운영되었다면 source 클러스터쪽에서 오래된 WAL파일들이 없을 수 있다. 이 경우, 직접 그 대상 WAL 아카이브 파일을 pg_wal 디렉터리로 복사할 수도 있다. pg_rewind 명령은 페일오버 용도로만 사용하는 것이 아니라, 대기 서버가 운영 서버로 전환되었다가 다시 대기 서버로 바꾸려고 할 때도 사용될 수 있다.

pg_rewind 수행 후, target 서버는 최초 시작시 복구 모드로 수행되어 분기지점 이후의 source 서버내 모든 WAL을 재생한다. source 서버로 부터 더 이상의 사용가능한 WAL이 없게 되면 pg_rewind 세션은 더 이상 복사하지 않는다. 필요에 따라 target 데이터 디렉터리 안에 recovery.signal 파일 만들고, postgresql.conf 파일에서 복구에 필요한 적당한 restore_command 설정을 할 수도 있다.

pg_rewind를 수행하기 위한 요구사항은 target 서버의 postgresql.conf 에서 wal_log_hints 옵션이 활성화되어 있거나, initdb 로 클러스터를 초기화할때 체크섬이 활성화 되어 있어야 한다. 이것들의 활성화값은 모두 기본값은 아니다. full_page_writes 값은 on 되어 있어야 한다. 이건 기본값으로 활성화되어 있다.

옵션

pg_rewind는 다음 명령어 줄 옵션을 사용한다.

-D directory
--target-pgdata=directory

이 옵션은 source 서버로 부터 동기화하는 target 데이터 디렉터리를 가리킨다. target 서버는 pg_rewind 수행전에 완전히 내려가 있어야 한다.

--source-pgdata=directory

target 서버를 동기화시킬 source 서버의 데이터 디렉터리를 가리킨다. 이 옵션을 사용하려면 source 서버가 완전히 내려가 있어야 한다.

--source-server=connstr

Specifies a libpq connection string to connect to the source PostgreSQL server to synchronize the target with. The connection must be a normal (non-replication) connection with a role having sufficient permissions to execute the functions used by pg_rewind on the source server (see Notes section for details) or a superuser role. This option requires the source server to be running and not in recovery mode.

-n
--dry-run

target 디렉터리에 실제 수정없이 모든 것을 수행해 본다.

-N
--no-sync

By default, pg_rewind will wait for all files to be written safely to disk. This option causes pg_rewind to return without waiting, which is faster, but means that a subsequent operating system crash can leave the synchronized data directory corrupt. Generally, this option is useful for testing but should not be used when creating a production installation.

-P
--progress

진행상태를 표시한다. 이 옵션을 활성화 시키면 정확하진 않지만 source 클러스터로부터 데이터 복제하는 진행상태를 볼 수 있다.

--debug

pg_rewind를 디버깅하는 개발자들에게 유용한 디버깅 메시지를 출력한다.

-V
--version

버전 정보를 표시하고 종료한다.

-?
--help

도움말을 표시하고 종료한다.

환경 변수

--source-server 옵션이 사용되면, pg_rewindlibpq에서 지원되는 환경 변수도 사용할 수 있다.(33.14절 참조).

The environment variable PG_COLOR specifies whether to use color in diagnostic messages. Possible values are always, auto and never.

주석

When executing pg_rewind using an online cluster as source, a role having sufficient permissions to execute the functions used by pg_rewind on the source cluster can be used instead of a superuser. Here is how to create such a role, named rewind_user here:

CREATE USER rewind_user LOGIN;
GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;

When executing pg_rewind using an online cluster as source which has been recently promoted, it is necessary to execute a CHECKPOINT after promotion so as its control file reflects up-to-date timeline information, which is used by pg_rewind to check if the target cluster can be rewound using the designated source cluster.

어떻게 동작되는가?

이 생각은 기본적으로은 시스템 수준에서 모든 변경 사항을 source 클러스터에서 target 클러스터로 복사한다는데 있다.

  1. 1. target 클러스터의 WAL을 검사한다. 범위는, target 클러스터로부터 source 클러스터의 타임라인이 나뉘어진 지점 바로 앞의 마지막 체크포인트된 지점에서 시작한다. 각 WAL 레코드들을 통해서 변경된 데이터 블록들을 기록한다. 그러면 source 클러스터를 분기시킨 후에 target 클러스터에서 변경된 데이터 블록의 전체 목록을 만들 수 있다.

  2. 2. 1번에서 얻은 목록을 사용해서 source 클러스터에서 target 클러스터로 변경된 블록 전체를 복사한다. 이때 직접 시스템 파일에 접근하는 (--source-pgdata)이나 SQL (--source-server) 옵션 중 하나를 사용한다.

  3. 3. pg_xact이나 설정파일들도 모두 source 클러스터에서 target 클러스터로 복사한다. (변경되지 않는 릴레이션 파일을 제외하곤 모두) 베이스 백업과 비슷하게, pg_dynshmem/, pg_notify/, pg_replslot/, pg_serial/, pg_snapshots/, pg_stat_tmp/, pg_subtrans/ 디렉터리의 내용은 빠진다. 또한 pgsql_tmp 디렉터리 이하 모든 파일, backup_label, tablespace_map, pg_internal.init, postmaster.opts, postmaster.pid 파일도 생략한다.

  4. 4. source 클러스터에서 가져온 WAL을 target 클러스터에 적용한다. 장애때 생성된 체크포인트 지점부터 시작한다. (엄격히 말하면 pg_rewind는 WAL을 적용하지는 않고 백업라벨 파일을 만들 뿐이다. PostgreSQL 시작시 분기 이후의 체크포인트 내용을 담은 WAL들을 순차적으로 적용한다.