PostgreSQL 9.x Replication Publications

Replication


사 실 Postgresql 의 Replication 을 지원했었습니다. 8.2 버전에서 부터 로그파일을 전송해서 Standby 서버에서 받아, replay 하는 형식으로 지원을 했었습니다. 그런데 많은 사람들이 이를 Replication 사용하지 않았었습니다. 대부분의 사람들이 생각하는 Replication 은 Streamming 을 말하는 것일 겁니다.


Postgresql 9.0 에서 와서야 Replication 이 Postgresql 코어에 내장됐습니다. 그동안 3rd_party 에서 만들어낸 Replication 프로그램을 이용해야만 했습니다. 그러다보니 매우 많은 방법의 Replication 프로그램이 존재하다보니까, 혼란도 많았습니다. 그런데 Postgresql 9.0 에 정식으로 Replication 을 지원하게 되었습니다. Replication 은 쉽게 말해서 원본 데이터베이스와 동일한 데이터베이스를 실시간으로 복사본을 만드는 기능이라고 생각하시면 됩니다.


Replication 을 사용하는 가장 큰 이유는 다음과 같습니다.

  1. 고가용성: 여러 시스템 각각에 똑같은 데이터의 복사본을 가지고 있음으로 해서 장애대비와 통계자료를 위한 데이터베이스 시스템 활용으로인한 시스템 분산등으로 가용성을 높일 수 있습니다.

위 의 그림처럼 용어들을 사용합니다. Replication 을 할 대상 서버를 'Master' 라고 합니다. 복사본을 받는 서버를 'StandBy' 서버라고 합니다. 위 그림을 보면 특징이 있습니다. Master 서버는 한대이고 StandBy 서버는 여러대 입니다. 데이터베이스의 복사본을 여러대 놓을 수있다는 것은 당연한 것입니다.


Replication 동작은 Master 서버에 트랜잭션이 커밋되면 실행됩니다. Master 서버에 트랜잭션이 커밋되면 StandBy 서버로 '변화된' 데이터를 전송하는데 이 데이터 전송시간을 'Replication Relay'라고 합니다. 그리고 전송이 모두 다 완료되면 StandBy 서버는 전송받은 데이터를 적용해야 하는데 이 시간을 'Apply Delay'라고 합니다.


그 런데 트랜잭션이 커밋될때마다 변화된 데이터를 전송한다면 서버가 Replication 에 많은 자원을 낭비하게 됩니다. 그래서 트랜잭션 커밋이 발생하면 변화된 데이터를 쌓아놔서 한꺼번에 전송하게 됩니다. 이는 매우 좋은 방법인데, 그런데 쌓아놓은 데이터양이 많아지면 Replication Relay 가 길어지게되고 더군다나 Apply Delay 도 덩달아 늘어나게 됩니다. 결국 Replication 시간은 Replication Relay + Apply Delay 로 볼수 있습니다.


로그파일을 이용한 리플리케이션


이 리플리케이션은 로그파일을 이용한 리플리케이션 입니다. 사실 리플리케이션이라기 보다는 백업본을 리모트에서 복구모드로 동작하게 하는 것이라고 보는것이 맞습니다.


설정 순서는 다음과 같습니다.

  1. Master 서버가 standby 서버에 postgres 계정으로 ssh 패스워드 인증없이 바로 접속할 수 있도록 설정을 합니다.
  2. Master 서버의 postgresql.conf 파일을 수정하고 서버를 재시작 합니다.
  3. Master 서버에서 PITR 백업을 합니다.
  4. 백업본을 standby 서버로 전송합니다.
  5. stanby 서버에서 전송받은 백업 압축파일을 해제 합니다.
  6. stanby recovery.conf 파일을 작성하고 pg_xlog 디렉토리를 생성하고 소유권을 postgres 로 바꿉니다.
  7. standby 서버를 기동 합니다.

첫번째 postgres 계정의 패스워드 인증없이 ssh 설정은 인터넷을 찾아보면 많이 나옵니다. 반드시 Master 서버에서 stanby 서버로 postgres 계정의 패스워드 없는 인증없이 ssh 접속이 가능해야 합니다.


두번째, postgresql.conf 파일을 다음과 같이 설정합니다.


wal_level = archive # minimal, archive, or hot_standby
archive_mode = on # allows archiving to be done
# (change requires restart)
#archive_command = 'cp %p /usr/local/pgsql9.0/archive/%f' # command to use to archive a logfile segment
archive_command = 'scp %p postgres@192.168.0.45:/usr/local/pgsql9.0/archive/%f' # command to use to archive a logfile segment
archive_timeout = 30 # force a logfile segment switch after this
# number of seconds; 0 disables

'archive_command' 를 본다면 Master 가 standby 서버로 무슨일을 하는지 알게 됩니다. pg_xlog 에서 파일 3개를 넘어서면 삭제하지 않고 standby 서버로 전송해줍니다.


세번째, 이제 리플케이션을 위해서 Master 의 data 디렉토리를 압축백업해줍니다. 이를 수행하기 전에 standby 서버에서 다음과 같이 해줍니다.


mkdir -p /usr/local/pgsql9.0/archive
chown postgres.postgres /usr/local/pgsql9.0/archive

반드시 소유권을 postgres 로 해줘야 합니다.


cd /usr/src
/usr/local/pgsql9.0/bin/psql -U postgres -c "select pg_start_backup('/usr/src/20110226.tar')"
tar -cv --exclude=/usr/local/pgsql9.0/data/pg_xlog -f 20110206.tar /usr/local/pgsql9.0/data
/usr/local/pgsql9.0/bin/psql -U postgres -c "select pg_stop_backup(), current_timestamp"
scp 20110206.tar root@192.168.0.45:./

여기서 'pg_stop_backup()' 를 수행하면 standby


네번째, 압축해제하고 pg_xlog 디렉토리를 만들고 recovery.conf 을 작성해 줍니다.


tar -xv 20110226.tar -C /
cd /usr/local/pgsql9.0/data
mkdir pg_xlog
chown postgres.postgres pg_xlog
vim recovery.conf

recovery.conf 의 파일의 내용은 /usr/local/pgsql9.0/archive 에 있는 pg_xlog 파일을 가지고 복구 모드로 동작하도록 하는 것입니다.


restore_command = 'cp /usr/local/pgsql9.0/archive/%f %p'
archive_cleanup_command = '/usr/local/pgsql9.0/bin/pg_archivecleanup /usr/local/pgsql9.0/archive/ %r'
standby_mode = 'on'
trigger_file = '/tmp/postgresql.trigger.5432'

이렇게 파일을 작성하고 역시나 소유권을 postgres 로 변경해줍니다. 그리고 서버를 시작해줍니다.


이 렇게 해놓으면 Master 서버에서는 archive 해야할 로그파일을 stanby 서버로 전송하고 standby 서버는 이것을 replay 하게 됩니다. 그러니까 standby 서버는 replay 로만 동작하게 됩니다. 이는 상태를 보면 알 수 있습니다. standby 서버의 프로세스 상태는 다음과 같습니다.


postgres 18080 0.0 1.8 152236 9864 ? S 16:30 0:00 /usr/local/pgsql9.0/bin/postmaster -p 5432 -D /usr/local/pgsql9.0/data
postgres 18082 0.0 1.2 152348 6320 ? Ss 16:30 0:00 postgres: startup process waiting for 000000010000000000000029
postgres 18085 0.0 1.1 152372 6284 ? Ss 16:30 0:00 postgres: writer process

29 번째 파일을 기다리고 있다고 나옵니다. '/usr/local/pgsql9.0/archive' 에는 Master 에서 전송한 파일을 받고 받자마자 바로 replay를 합니다. 그리고 3개가 넘어가면 pg_archivecleanup 프로그램이 recovery.conf 에 명시된대로 삭제됩니다. 이는 '/usr/local/pgsql9.0/archive' 디렉토리를 모니터링 해보면 알 수 있습니다. 없던 파일이 나타나고 사라지는것을 확인할 수 있습니다.


이 Replication 의 특징는 standby 를 활용할 수 없습니다. Select 전용으로라도 활용할 수 없습니다. 왜냐하면 replay로 동작중이기 때문에 psql 를 이용해서 접속을 하면 다음과 같은 에러메시지를 만나게 됩니다.


/usr/local/pgsql9.0/bin/psql -U postgres
psql: FATAL: the database system is starting up

그리고 postgresql.log 를 보면 다음과 같습니다.


cp: cannot stat `/usr/local/pgsql9.0/archive/00000001000000000000002E': 그런 파일이나 디렉토리가 없음
cp: cannot stat `/usr/local/pgsql9.0/archive/00000001000000000000002E': 그런 파일이나 디렉토리가 없음
LOG: restored log file "00000001000000000000002E" from archive
cp: cannot stat `/usr/local/pgsql9.0/archive/00000001000000000000002F': 그런 파일이나 디렉토리가 없음
cp: cannot stat `/usr/local/pgsql9.0/archive/00000001000000000000002F': 그런 파일이나 디렉토리가 없음

또, Master 서버에서 'archive_command' 에 스크립트를 넣어서 다중 standby 서버를 가질 수 있습니다.


archive_command = 'myarchivescript %p %f'

myarchivescript 파일 내용.
scp $1 $STANDBYNODE1:$PGARCHIVE/$2
scp $1 $STANDBYNODE2:$PGARCHIVE/$2
scp $1 $STANDBYNODE3:$PGARCHIVE/$2

스트리밍 로그 리플리케이션


Streaming log replication 은 Postgresql 9.0 에서 새롭게 도입된 기능입니다. 이 기능은 데이터를 Master 에서 Standby 서버로 직접 전송함으로서 replication delay 를 줄여줍니다. 따라서 pg_xlog 파일을 전송이 필요가 없습니다. 또 xlog 를 Streaming으로 받기위해서 Master 서버에 SUPERUSER 권한의 접소계정이 필요합니다.


Master 서버의 설정을 먼저 해야합니다. xlog 를 Streaming 으로 받기위한 계정을 생성하고 외부에서 접속을 할수 있는 환경을 세팅해야 하는 것이 먼저 입니다.


vim /usr/local/pgsql9.0/data/postgresql.conf
listen_addresses = '*'
log_connection = on
max_wal_senders = 1
wal_level = archive
archive_mode = on
archive_command = 'cd .'
wal_keep_segments = 10000 # e.g 160GB

계정을 생성합니다.


/usr/local/pgsql9.0/bin/psql -U postgres
CREATE USER repuser SUPERUSER LOGIN CONNECTION LIMIT 1 PASSWORD '12345'

그리고 pg_hba.conf 파일에 Standby 서버를 위한 인증을 추가해줍니다.


host replication repuser 127.0.0.1/0 md5

Master 서버의 설정을 모두 끝났습니다. 서버를 재시작합니다. 그리고 Standby 서버에 데이터 싱크를 위해서 PITR 를 백업을 해줍니다. 그리고 이것을 Standby 서버로 전송해, 압축을 해제합니다.


Standby 서버의 설정을 해줍니다. 압축을 해제해줬기 때문에 Master 의 data 디렉토리를 그대로 가지고 있을 겁니다. postgresql.conf 파일을 최초의 파일로 교체해줍니다. 그리고 recovery.conf 파일을 작성해 줍니다.


standby_mode = 'on'
primary_conninfo = 'host=192.168.0.63 port=5432 user=repuser password=12345'
trigger_file = '/tmp/postgresql.trigger.5432'

이제 다 되었습니다. Standby 서버를 시작해줍니다. 로그파일을 열어확인해 봅시다.


LOG: database system was interrupted; last known up at 2011-02-26 19:51:12 KST
LOG: entering standby mode
LOG: streaming replication successfully connected to primary
LOG: redo starts at 0/4D000078
LOG: consistent recovery state reached at 0/4E000000
LOG: connection received: host=[local]

프로세스 상태를 확인해 봅니다.


ps aux | grep post
postgres 1695 0.0 1.8 152240 9884 ? S 20:02 0:00 /usr/local/pgsql9.0/bin/postmaster -p 5432 -D /usr/local/pgsql9.0/data
postgres 1697 0.0 1.2 152352 6304 ? Ss 20:02 0:00 postgres: startup process recovering 00000001000000000000004E
postgres 1698 0.0 1.3 157296 7184 ? Ss 20:02 0:00 postgres: wal receiver process streaming 0/4E0015A8
postgres 1702 0.0 1.2 152352 6308 ? Ss 20:02 0:00 postgres: writer process

Streaming log replication 의 동작상태를 알 수 있습니다.


Master 서버에서 replication 서버 모니터링은 다음과 같은 쿼리로 확인이 가능합니다.


SELECT S.procpid, S.usesysid, U.rolname AS usename, S.application_name, S.client_addr, S.client_port, S.backend_start FROM pg_stat_get_activity(NULL) AS S, pg_authid U WHERE S.usesysid = U.oid AND S.datid = 0;

Hot Standby Replication


지금까지의 Replication 은 Standby 서버에 접속을 할 수 없었습니다. Stnadby 서버에 접속을 시도하면 다음과 같이 에러가 발생합니다.


psql: FATAL: the database system is starting up

하지만 Hot Standby 는 Standby 서버에 접속할 수 있고, 읽기전용 쿼리를 실행할 수 있습니다.


Hot Standby 는 앞에서 언급한 두가지의 Replication 에 Hot Standby 를 설정할 수 있습니다. 설정 방법은 아주 간단합니다.


Master 서버에서
wal_level = 'hot_Standby' in postgresql.conf
Standby 서버에서
hot_Standby = on in postgresql.conf

위와 같이 설정을 한후에 서버들을 재시작해줘야 합니다. 적용 순서는 다음과 같습니다.

  1. Standby 서버 shutdown.
  2. Master 서버 재시작.
  3. Standby 서버 시작.

Standby 서버의 프로세스 상태는 다음과 같습니다.


ps aux | grep post
postgres 1988 0.0 1.8 152276 9908 ? S 22:31 0:00 /usr/local/pgsql9.0/bin/postmaster -p 5432 -D /usr/local/pgsql9.0/data
postgres 1990 0.0 1.2 152388 6404 ? Ss 22:31 0:00 postgres: startup process recovering 000000010000000000000052
postgres 1991 0.0 1.4 157844 7360 ? Ss 22:31 0:00 postgres: wal receiver process streaming 0/520018D0
postgres 1992 0.0 1.2 152412 6328 ? Ss 22:31 0:00 postgres: writer process
postgres 1993 0.0 1.1 115284 5808 ? Ss 22:31 0:00 postgres: stats collector process


덧글

  • abc 2016/03/14 13:36 # 삭제 답글

    노란색박스안에 conf 설정이나 명령들은 vim을 설치해서 vim으로 봐야하나요?
댓글 입력 영역